From b6c655cf1cd5008d43e41cc9a4d388d505a7c84c Mon Sep 17 00:00:00 2001 From: Dawid Kubicki Date: Mon, 19 Nov 2018 23:41:12 +0100 Subject: [PATCH] biometric added --- Friendvatars.xcodeproj/project.pbxproj | 22 +- .../xcschemes/xcschememanagement.plist | 2 +- .../UserInterfaceState.xcuserstate | Bin 33870 -> 36977 bytes Friendvatars/Assets.xcassets/Contents.json | 6 + .../FaceID.imageset/Contents.json | 21 + .../FaceID.imageset/FaceID.png | Bin 0 -> 2165 bytes .../TouchID.imageset/Contents.json | 21 + .../TouchID.imageset/TouchID.png | Bin 0 -> 43401 bytes Friendvatars/AuthViewController.swift | 2 + Friendvatars/AuthViewController.xib | 34 +- Friendvatars/BiometricTest.swift | 15 + Friendvatars/FriendsViewController.swift | 2 +- .../NoteBiometricViewController.swift | 43 +- Friendvatars/NoteBiometricViewController.xib | 49 +- Podfile | 1 + Podfile.lock | 12 +- Pods/KeychainAccess/LICENSE | 22 + .../Lib/KeychainAccess/Keychain.swift | 2921 +++++++++++++++++ Pods/KeychainAccess/README.md | 602 ++++ Pods/Manifest.lock | 12 +- Pods/Pods.xcodeproj/project.pbxproj | 1192 ++++--- .../xcschemes/CryptoSwift.xcscheme | 60 + .../xcschemes/KeychainAccess.xcscheme | 60 + .../xcschemes/Pods-Friendvatars.xcscheme | 71 + .../xcschemes/xcschememanagement.plist | 21 +- .../CryptoSwift/CryptoSwift.xcconfig | 7 +- .../KeychainAccess/Info.plist | 26 + .../KeychainAccess/KeychainAccess-dummy.m | 5 + .../KeychainAccess/KeychainAccess-prefix.pch | 12 + .../KeychainAccess/KeychainAccess-umbrella.h | 16 + .../KeychainAccess/KeychainAccess.modulemap | 6 + .../KeychainAccess/KeychainAccess.xcconfig | 9 + ...ods-Friendvatars-acknowledgements.markdown | 26 + .../Pods-Friendvatars-acknowledgements.plist | 32 + .../Pods-Friendvatars-frameworks.sh | 59 +- .../Pods-Friendvatars-resources.sh | 18 +- .../Pods-Friendvatars.debug.xcconfig | 10 +- .../Pods-Friendvatars.release.xcconfig | 10 +- 38 files changed, 4857 insertions(+), 570 deletions(-) create mode 100644 Friendvatars/Assets.xcassets/Contents.json create mode 100644 Friendvatars/Assets.xcassets/FaceID.imageset/Contents.json create mode 100644 Friendvatars/Assets.xcassets/FaceID.imageset/FaceID.png create mode 100644 Friendvatars/Assets.xcassets/TouchID.imageset/Contents.json create mode 100644 Friendvatars/Assets.xcassets/TouchID.imageset/TouchID.png create mode 100644 Friendvatars/BiometricTest.swift create mode 100644 Pods/KeychainAccess/LICENSE create mode 100644 Pods/KeychainAccess/Lib/KeychainAccess/Keychain.swift create mode 100644 Pods/KeychainAccess/README.md create mode 100644 Pods/Pods.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/CryptoSwift.xcscheme create mode 100644 Pods/Pods.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/KeychainAccess.xcscheme create mode 100644 Pods/Pods.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/Pods-Friendvatars.xcscheme create mode 100644 Pods/Target Support Files/KeychainAccess/Info.plist create mode 100644 Pods/Target Support Files/KeychainAccess/KeychainAccess-dummy.m create mode 100644 Pods/Target Support Files/KeychainAccess/KeychainAccess-prefix.pch create mode 100644 Pods/Target Support Files/KeychainAccess/KeychainAccess-umbrella.h create mode 100644 Pods/Target Support Files/KeychainAccess/KeychainAccess.modulemap create mode 100644 Pods/Target Support Files/KeychainAccess/KeychainAccess.xcconfig diff --git a/Friendvatars.xcodeproj/project.pbxproj b/Friendvatars.xcodeproj/project.pbxproj index ae30e89..1f7486d 100644 --- a/Friendvatars.xcodeproj/project.pbxproj +++ b/Friendvatars.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 123D62D321A3148300D5CD74 /* NoteBiometricViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123D62D121A3148300D5CD74 /* NoteBiometricViewController.swift */; }; 123D62D421A3148300D5CD74 /* NoteBiometricViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 123D62D221A3148300D5CD74 /* NoteBiometricViewController.xib */; }; + 123D62D621A370AD00D5CD74 /* BiometricTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 123D62D521A370AD00D5CD74 /* BiometricTest.swift */; }; 18F5657D204DD7AF00F128ED /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 18F5657C204DD7AF00F128ED /* LaunchScreen.storyboard */; }; 48DC83E42012A5D600F82C5D /* FriendCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48DC83E22012A5D600F82C5D /* FriendCell.swift */; }; 48DC83E52012A5D600F82C5D /* FriendCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 48DC83E32012A5D600F82C5D /* FriendCell.xib */; }; @@ -32,6 +33,7 @@ /* Begin PBXFileReference section */ 123D62D121A3148300D5CD74 /* NoteBiometricViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteBiometricViewController.swift; sourceTree = ""; }; 123D62D221A3148300D5CD74 /* NoteBiometricViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NoteBiometricViewController.xib; sourceTree = ""; }; + 123D62D521A370AD00D5CD74 /* BiometricTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BiometricTest.swift; sourceTree = ""; }; 18F5657C204DD7AF00F128ED /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; 48DC83E22012A5D600F82C5D /* FriendCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FriendCell.swift; sourceTree = ""; }; 48DC83E32012A5D600F82C5D /* FriendCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FriendCell.xib; sourceTree = ""; }; @@ -138,6 +140,7 @@ 48EA9AF020117C9000146CF7 /* NavigationController.swift */, 48EA9AD3200FC48100146CF7 /* SplashViewController.swift */, 123D62D121A3148300D5CD74 /* NoteBiometricViewController.swift */, + 123D62D521A370AD00D5CD74 /* BiometricTest.swift */, 123D62D221A3148300D5CD74 /* NoteBiometricViewController.xib */, ); name = ViewControllers; @@ -200,7 +203,6 @@ 48EA9ABA200FC22200146CF7 /* Frameworks */, 48EA9ABB200FC22200146CF7 /* Resources */, 52B361095004F9533772F347 /* [CP] Embed Pods Frameworks */, - CCE08048E2F58DCDD1B52E7E /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -269,10 +271,12 @@ inputPaths = ( "${SRCROOT}/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars-frameworks.sh", "${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework", + "${BUILT_PRODUCTS_DIR}/KeychainAccess/KeychainAccess.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CryptoSwift.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/KeychainAccess.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -297,21 +301,6 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - CCE08048E2F58DCDD1B52E7E /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -331,6 +320,7 @@ 48EA9AE220110FEC00146CF7 /* Settings.swift in Sources */, 48EA9AEB2011172800146CF7 /* DispatchQueue+Delay.swift in Sources */, 48EA9AC1200FC22200146CF7 /* AppDelegate.swift in Sources */, + 123D62D621A370AD00D5CD74 /* BiometricTest.swift in Sources */, 48DC83E42012A5D600F82C5D /* FriendCell.swift in Sources */, 48EA9AD7200FC8B800146CF7 /* AppController.swift in Sources */, ); diff --git a/Friendvatars.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/xcschememanagement.plist b/Friendvatars.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/xcschememanagement.plist index cce748e..97dff02 100644 --- a/Friendvatars.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Friendvatars.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,7 +7,7 @@ Friendvatars.xcscheme_^#shared#^_ orderHint - 0 + 2 diff --git a/Friendvatars.xcworkspace/xcuserdata/dawidkubicki.xcuserdatad/UserInterfaceState.xcuserstate b/Friendvatars.xcworkspace/xcuserdata/dawidkubicki.xcuserdatad/UserInterfaceState.xcuserstate index 602167c26d3d5823a87f7229ec76836ea1c779bf..1c438c5f2fb5079d652ec229e3f817451b9ae254 100644 GIT binary patch delta 19237 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%0DdEPA>nd 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 L)3^Ck|M33+mLOz* diff --git a/Friendvatars/Assets.xcassets/Contents.json b/Friendvatars/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Friendvatars/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Friendvatars/Assets.xcassets/FaceID.imageset/Contents.json b/Friendvatars/Assets.xcassets/FaceID.imageset/Contents.json new file mode 100644 index 0000000..28451a0 --- /dev/null +++ b/Friendvatars/Assets.xcassets/FaceID.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "FaceID.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Friendvatars/Assets.xcassets/FaceID.imageset/FaceID.png b/Friendvatars/Assets.xcassets/FaceID.imageset/FaceID.png new file mode 100644 index 0000000000000000000000000000000000000000..bc95aceb4f72d7f349c2d0fa09389217f38e000a GIT binary patch literal 2165 zcmV-*2#WWKP)tl{C|e}8{bQBmsZ>N+|)l9Gjmg=J-B3=9l%a&p<(*&iPtyu7@ss;X#cXc!n6 zpP!#CEiJdVw@64x{G#{d000NLNkl?SiTx5Qep^v^KM{wyd=F>}l`+4o__# z4hRYe8Jv0kWl8gv!U!{i=hYCWLAF~Ld!NhaA+Kvd1Nq^T|MmM~y~~0$R%^N+7W}3G zTfK@Xwn8=(VPCf4d?VEIFGCZ`?hM7v*vMQ>$BB5u7mVriJSjUSN5NM63#oQ}U-}9W z<|t{&Ld2ADB-yI(2gVcz(zZn7rZ!K~ZJN9hC2qqfr}`$B3QhXv28>+AoMlae?g`oO`7z{bIh~c;&ZXtY#ADs+uY_wlXR3B5|c;)s)p1=N~MhP1fU*Fq_iK zG~s`Jwuv~77vo=KT@Q=xbYNUTTL#lDYXGlaTGdV_9Ccu?8l$jc{ha?#??;IzdOJIr5~91A+>R0MT2z0&1rWXF&3Pjxo$MP2 zX^4?;^Lq#$>2++L4hZk&dVm-z>~huE%%Gs_fB~J>uxsnIKr4a|SoSuik&kLW}{>lzBViu5<*@d+y+z ztNk9^1K_!>q1;W^hG_#hqJ;;Ru(PfW(+22V_RuSJ!704~T~kzOC#cYVP@(;xLi<65 z_Ja!T2Nl{6DzqO|Xg{dXeo&$PphElk&lG~pFx!KLNERh~SMAWKl zyEIZp_~&5J+x~ECD&%I_m3s~-$aC%e9$d>EKZ8$=KUK@bG7 z50#ir;d9;~AoRQN{YdV~GQXyC9t1r7*)=BptJ_C{!3sR22=aJbJ2!ps5s}`h1N{u- zJPMz3h7YH8l##w2{)=T8d?m4%OF6+XssCUZkN(xt%oc!1RnZ4bn4(jk=?Lb?+FPm$ z2%#1&Z~}7!>TfXNpTZ;)g9>55eRsJ$sE`3Fe1ZyJ11e;I3ZJ0D*MJHcpu#7p@HL=9 z2B`4Kdnk1O2^h>`h)yVqEBsS_u)U?KlrvF#(Nn|~zQs(G_wz8Kaq{zlxWe*A?6Nl3 z;P1@_@sK!ih3_#Vd^R zsL*~;q5Ysj`$2{Fg9`1(eTCo7D}-f?B_^;e0&b@0Mqy@>87K(rPR-jZ{cv}M+;z~Q zq}7Ib0+nPBz4)w=;@9wHfNW-QAm8nt-B9F5ClOG1VIoZBy-;{+Skua zK7D_#y9}p}ntSm*d0^3Q0w%ui&iJSGJPxS2r>AaWxqn-mxa@M*>6RP$!McfhYG0nf zEQR{QCoGzAYW_GMSo=~_{n8&`oAPd-aCgmilm4)NsiqpVr?$VOUNL)4(v zR7ZGDS|^@E^Msm^lc;!8g{UJ8+H5n6xufj!Be~mp9MKKzT3BPE+BIWwA{3uC9E8== z+k`O~spoy5Exa};HmJot#<{JQrp#0<|6-Wwe>L}BQ}&6iY%x@mo%K&#Tdi}Ka^6Y$ zOwn0&e#o}=(rKJnD)UpNdwL+6a?8V5UHzQ46i_U)rF}XLwH*K#p-x{niy8FWiJ32^|iI$8}!~0usI~)Ppb}@HM@8H4mP=t{1 zg6c89N6DDw;WVLf@%t6Ku#9E@$57|u{%iJ`83YSqd5b{r;{MBa(#d;u&5OD=OdDWAYz>!GS}wc3 z5#Yky!AsVed_b6olo6T7u4E#?^oM|07E@iFemCH1dFsXBl`FYOaQY-B?n*~;9!EgY zwfBURVqw?DX@OP*V_19_Qa)x-&~I!HJm7+BN-Vnm9wE|n?N7QQ(j9M(D6y_-zvo6Q zVcutAiS;nsw;xZSn8%)3M|jY3$A--2JU$MS3k=;?wN>YXP*Qp@#DHP5L{cCO1Em5C zY`svagk#ui(h22ub~g#7f*AQu)SHr#h3`Nmx{(SpuB?Ie>~i2{mGH48{Si6@_TseK z^Q1AVuBlf8a9On-7Tf9jPizdPTh?+q<2K_2r4`X8>v2iUce~Ss|Ml4>;;f@H7tT3V zRvK8D?UTl~-=QsU% rFgH}($Pb_VuiqEzT^6LZ$w&VHrEgH>!RX<%00000NkvXXu0mjfE|@j` literal 0 HcmV?d00001 diff --git a/Friendvatars/Assets.xcassets/TouchID.imageset/Contents.json b/Friendvatars/Assets.xcassets/TouchID.imageset/Contents.json new file mode 100644 index 0000000..8bef4cf --- /dev/null +++ b/Friendvatars/Assets.xcassets/TouchID.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "TouchID.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Friendvatars/Assets.xcassets/TouchID.imageset/TouchID.png b/Friendvatars/Assets.xcassets/TouchID.imageset/TouchID.png new file mode 100644 index 0000000000000000000000000000000000000000..de43579d6c2865c8c033c6f411d907f41303eff4 GIT binary patch literal 43401 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 - @@ -84,20 +83,9 @@ - - - @@ -114,21 +102,22 @@ - - - - - - - - - - + + @@ -138,6 +127,7 @@ + diff --git a/Friendvatars/BiometricTest.swift b/Friendvatars/BiometricTest.swift new file mode 100644 index 0000000..eeea98f --- /dev/null +++ b/Friendvatars/BiometricTest.swift @@ -0,0 +1,15 @@ +// +// BiometricTest.swift +// Friendvatars +// +// Created by Dawid Kubicki on 19/11/2018. +// Copyright © 2018 Razeware. All rights reserved. +// + +import Foundation +import LocalAuthentication + +var biometricType: LABiometryType { + let authContext = LAContext() + return authContext.biometryType +} diff --git a/Friendvatars/FriendsViewController.swift b/Friendvatars/FriendsViewController.swift index 12458f3..9b4bc3f 100644 --- a/Friendvatars/FriendsViewController.swift +++ b/Friendvatars/FriendsViewController.swift @@ -70,7 +70,7 @@ final class FriendsViewController: UITableViewController { } else { let emailHash = user.email.trimmingCharacters(in: .whitespacesAndNewlines) .lowercased() - .md5() + .sha1() if let url = URL(string: "https://www.gravatar.com/avatar/" + emailHash) { URLSession.shared.dataTask(with: url) { data, response, error in diff --git a/Friendvatars/NoteBiometricViewController.swift b/Friendvatars/NoteBiometricViewController.swift index e79fc7d..a6bfd4c 100644 --- a/Friendvatars/NoteBiometricViewController.swift +++ b/Friendvatars/NoteBiometricViewController.swift @@ -7,16 +7,55 @@ // import UIKit +import KeychainAccess class NoteBiometricViewController: UIViewController { + @IBAction func isSignOut(_ sender: Any) { + try? AuthController.signOut() + } + @IBOutlet weak var txtSecret: UITextField! + @IBOutlet weak var imgBio: UIImageView! + @IBOutlet weak var lblSecret: UILabel! + + let keychain = Keychain(service: "com.dawidkubicki.Friendvatars") + override func viewDidLoad() { super.viewDidLoad() - // Do any additional setup after loading the view. + if(biometricType == .touchID) { + imgBio.image = UIImage(named: "TouchID") + } else if(biometricType == .faceID) { + imgBio.image = UIImage(named: "FaceID") + } else if(biometricType == .none) { + print("Nie ma możliwości użycia biometrycznego uwierzytelniania") + } } - + @IBAction func storeSecret(_ sender: Any) { + DispatchQueue.global().async { + do { + try self.keychain + .accessibility(.whenPasscodeSetThisDeviceOnly, authenticationPolicy: .userPresence) + .set(self.txtSecret.text!, key: "secret") + } catch let error { + print(error) + } + } + } + + @IBAction func getSecret(_ sender: Any) { + DispatchQueue.global().async { + do { + let secret = try self.keychain + .authenticationPrompt("Zaloguj się biometrycznie, aby zobaczyć notatkę") + .get("secret") + self.lblSecret.text = "Twoja ukryta notatka to: \(secret!)" + } catch let error { + print(error) + } + } + } /* // MARK: - Navigation diff --git a/Friendvatars/NoteBiometricViewController.xib b/Friendvatars/NoteBiometricViewController.xib index 1d4e26a..ec8080d 100644 --- a/Friendvatars/NoteBiometricViewController.xib +++ b/Friendvatars/NoteBiometricViewController.xib @@ -12,6 +12,9 @@ + + + @@ -20,14 +23,52 @@ - + + + + + + + + + + + + + + - + + diff --git a/Podfile b/Podfile index 9f06147..b62ad0b 100644 --- a/Podfile +++ b/Podfile @@ -3,4 +3,5 @@ use_frameworks! target 'Friendvatars' do pod 'CryptoSwift' + pod 'KeychainAccess' end diff --git a/Podfile.lock b/Podfile.lock index 5e4b8be..843b910 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,12 +1,20 @@ PODS: - CryptoSwift (0.8.1) + - KeychainAccess (3.1.2) DEPENDENCIES: - CryptoSwift + - KeychainAccess + +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - CryptoSwift + - KeychainAccess SPEC CHECKSUMS: CryptoSwift: 4b07d5b508c1eb67bfa314a727b705f8048a85de + KeychainAccess: b3816fddcf28aa29d94b10ec305cd52be14c472b -PODFILE CHECKSUM: bbf4ad9f3f2f1429ecda282ecb446c084363a23f +PODFILE CHECKSUM: 2ccd80ba9984103c7eb7f1175a88d0a90df6c731 -COCOAPODS: 1.3.1 +COCOAPODS: 1.5.3 diff --git a/Pods/KeychainAccess/LICENSE b/Pods/KeychainAccess/LICENSE new file mode 100644 index 0000000..7ab2a8e --- /dev/null +++ b/Pods/KeychainAccess/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014 kishikawa katsumi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/Pods/KeychainAccess/Lib/KeychainAccess/Keychain.swift b/Pods/KeychainAccess/Lib/KeychainAccess/Keychain.swift new file mode 100644 index 0000000..8d1721e --- /dev/null +++ b/Pods/KeychainAccess/Lib/KeychainAccess/Keychain.swift @@ -0,0 +1,2921 @@ +// +// Keychain.swift +// KeychainAccess +// +// Created by kishikawa katsumi on 2014/12/24. +// Copyright (c) 2014 kishikawa katsumi. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation +import Security +#if os(iOS) || os(OSX) +import LocalAuthentication +#endif + +public let KeychainAccessErrorDomain = "com.kishikawakatsumi.KeychainAccess.error" + +public enum ItemClass { + case genericPassword + case internetPassword +} + +public enum ProtocolType { + case ftp + case ftpAccount + case http + case irc + case nntp + case pop3 + case smtp + case socks + case imap + case ldap + case appleTalk + case afp + case telnet + case ssh + case ftps + case https + case httpProxy + case httpsProxy + case ftpProxy + case smb + case rtsp + case rtspProxy + case daap + case eppc + case ipp + case nntps + case ldaps + case telnetS + case imaps + case ircs + case pop3S +} + +public enum AuthenticationType { + case ntlm + case msn + case dpa + case rpa + case httpBasic + case httpDigest + case htmlForm + case `default` +} + +public enum Accessibility { + /** + Item data can only be accessed + while the device is unlocked. This is recommended for items that only + need be accesible while the application is in the foreground. Items + with this attribute will migrate to a new device when using encrypted + backups. + */ + case whenUnlocked + + /** + Item data can only be + accessed once the device has been unlocked after a restart. This is + recommended for items that need to be accesible by background + applications. Items with this attribute will migrate to a new device + when using encrypted backups. + */ + case afterFirstUnlock + + /** + Item data can always be accessed + regardless of the lock state of the device. This is not recommended + for anything except system use. Items with this attribute will migrate + to a new device when using encrypted backups. + */ + case always + + /** + Item data can + only be accessed while the device is unlocked. This class is only + available if a passcode is set on the device. This is recommended for + items that only need to be accessible while the application is in the + foreground. Items with this attribute will never migrate to a new + device, so after a backup is restored to a new device, these items + will be missing. No items can be stored in this class on devices + without a passcode. Disabling the device passcode will cause all + items in this class to be deleted. + */ + @available(iOS 8.0, OSX 10.10, *) + case whenPasscodeSetThisDeviceOnly + + /** + Item data can only + be accessed while the device is unlocked. This is recommended for items + that only need be accesible while the application is in the foreground. + Items with this attribute will never migrate to a new device, so after + a backup is restored to a new device, these items will be missing. + */ + case whenUnlockedThisDeviceOnly + + /** + Item data can + only be accessed once the device has been unlocked after a restart. + This is recommended for items that need to be accessible by background + applications. Items with this attribute will never migrate to a new + device, so after a backup is restored to a new device these items will + be missing. + */ + case afterFirstUnlockThisDeviceOnly + + /** + Item data can always + be accessed regardless of the lock state of the device. This option + is not recommended for anything except system use. Items with this + attribute will never migrate to a new device, so after a backup is + restored to a new device, these items will be missing. + */ + case alwaysThisDeviceOnly +} + +public struct AuthenticationPolicy: OptionSet { + /** + User presence policy using Touch ID or Passcode. Touch ID does not + have to be available or enrolled. Item is still accessible by Touch ID + even if fingers are added or removed. + */ + @available(iOS 8.0, OSX 10.10, *) + @available(watchOS, unavailable) + public static let userPresence = AuthenticationPolicy(rawValue: 1 << 0) + + /** + Constraint: Touch ID (any finger). Touch ID must be available and + at least one finger must be enrolled. Item is still accessible by + Touch ID even if fingers are added or removed. + */ + @available(iOS 9.0, *) + @available(OSX, unavailable) + @available(watchOS, unavailable) + public static let touchIDAny = AuthenticationPolicy(rawValue: 1 << 1) + + /** + Constraint: Touch ID from the set of currently enrolled fingers. + Touch ID must be available and at least one finger must be enrolled. + When fingers are added or removed, the item is invalidated. + */ + @available(iOS 9.0, *) + @available(OSX, unavailable) + @available(watchOS, unavailable) + public static let touchIDCurrentSet = AuthenticationPolicy(rawValue: 1 << 3) + + /** + Constraint: Device passcode + */ + @available(iOS 9.0, OSX 10.11, *) + @available(watchOS, unavailable) + public static let devicePasscode = AuthenticationPolicy(rawValue: 1 << 4) + + /** + Constraint logic operation: when using more than one constraint, + at least one of them must be satisfied. + */ + @available(iOS 9.0, *) + @available(OSX, unavailable) + @available(watchOS, unavailable) + public static let or = AuthenticationPolicy(rawValue: 1 << 14) + + /** + Constraint logic operation: when using more than one constraint, + all must be satisfied. + */ + @available(iOS 9.0, *) + @available(OSX, unavailable) + @available(watchOS, unavailable) + public static let and = AuthenticationPolicy(rawValue: 1 << 15) + + /** + Create access control for private key operations (i.e. sign operation) + */ + @available(iOS 9.0, *) + @available(OSX, unavailable) + @available(watchOS, unavailable) + public static let privateKeyUsage = AuthenticationPolicy(rawValue: 1 << 30) + + /** + Security: Application provided password for data encryption key generation. + This is not a constraint but additional item encryption mechanism. + */ + @available(iOS 9.0, *) + @available(OSX, unavailable) + @available(watchOS, unavailable) + public static let applicationPassword = AuthenticationPolicy(rawValue: 1 << 31) + + #if swift(>=2.3) + public let rawValue: UInt + + public init(rawValue: UInt) { + self.rawValue = rawValue + } + #else + public let rawValue: Int + + public init(rawValue: Int) { + self.rawValue = rawValue + } + #endif +} + +public struct Attributes { + public var `class`: String? { + return attributes[Class] as? String + } + public var data: Data? { + return attributes[ValueData] as? Data + } + public var ref: Data? { + return attributes[ValueRef] as? Data + } + public var persistentRef: Data? { + return attributes[ValuePersistentRef] as? Data + } + + public var accessible: String? { + return attributes[AttributeAccessible] as? String + } + public var accessControl: SecAccessControl? { + if #available(OSX 10.10, *) { + if let accessControl = attributes[AttributeAccessControl] { + return (accessControl as! SecAccessControl) + } + return nil + } else { + return nil + } + } + public var accessGroup: String? { + return attributes[AttributeAccessGroup] as? String + } + public var synchronizable: Bool? { + return attributes[AttributeSynchronizable] as? Bool + } + public var creationDate: Date? { + return attributes[AttributeCreationDate] as? Date + } + public var modificationDate: Date? { + return attributes[AttributeModificationDate] as? Date + } + public var attributeDescription: String? { + return attributes[AttributeDescription] as? String + } + public var comment: String? { + return attributes[AttributeComment] as? String + } + public var creator: String? { + return attributes[AttributeCreator] as? String + } + public var type: String? { + return attributes[AttributeType] as? String + } + public var label: String? { + return attributes[AttributeLabel] as? String + } + public var isInvisible: Bool? { + return attributes[AttributeIsInvisible] as? Bool + } + public var isNegative: Bool? { + return attributes[AttributeIsNegative] as? Bool + } + public var account: String? { + return attributes[AttributeAccount] as? String + } + public var service: String? { + return attributes[AttributeService] as? String + } + public var generic: Data? { + return attributes[AttributeGeneric] as? Data + } + public var securityDomain: String? { + return attributes[AttributeSecurityDomain] as? String + } + public var server: String? { + return attributes[AttributeServer] as? String + } + public var `protocol`: String? { + return attributes[AttributeProtocol] as? String + } + public var authenticationType: String? { + return attributes[AttributeAuthenticationType] as? String + } + public var port: Int? { + return attributes[AttributePort] as? Int + } + public var path: String? { + return attributes[AttributePath] as? String + } + + fileprivate let attributes: [String: Any] + + init(attributes: [String: Any]) { + self.attributes = attributes + } + + public subscript(key: String) -> Any? { + get { + return attributes[key] + } + } +} + +public final class Keychain { + public var itemClass: ItemClass { + return options.itemClass + } + + public var service: String { + return options.service + } + + public var accessGroup: String? { + return options.accessGroup + } + + public var server: URL { + return options.server + } + + public var protocolType: ProtocolType { + return options.protocolType + } + + public var authenticationType: AuthenticationType { + return options.authenticationType + } + + public var accessibility: Accessibility { + return options.accessibility + } + + @available(iOS 8.0, OSX 10.10, *) + @available(watchOS, unavailable) + public var authenticationPolicy: AuthenticationPolicy? { + return options.authenticationPolicy + } + + public var synchronizable: Bool { + return options.synchronizable + } + + public var label: String? { + return options.label + } + + public var comment: String? { + return options.comment + } + + @available(iOS 8.0, OSX 10.10, *) + @available(watchOS, unavailable) + public var authenticationPrompt: String? { + return options.authenticationPrompt + } + + #if os(iOS) || os(OSX) + @available(iOS 9.0, OSX 10.11, *) + public var authenticationContext: LAContext? { + return options.authenticationContext as? LAContext + } + #endif + + fileprivate let options: Options + + // MARK: + + public convenience init() { + var options = Options() + if let bundleIdentifier = Bundle.main.bundleIdentifier { + options.service = bundleIdentifier + } + self.init(options) + } + + public convenience init(service: String) { + var options = Options() + options.service = service + self.init(options) + } + + public convenience init(accessGroup: String) { + var options = Options() + if let bundleIdentifier = Bundle.main.bundleIdentifier { + options.service = bundleIdentifier + } + options.accessGroup = accessGroup + self.init(options) + } + + public convenience init(service: String, accessGroup: String) { + var options = Options() + options.service = service + options.accessGroup = accessGroup + self.init(options) + } + + public convenience init(server: String, protocolType: ProtocolType, authenticationType: AuthenticationType = .default) { + self.init(server: URL(string: server)!, protocolType: protocolType, authenticationType: authenticationType) + } + + public convenience init(server: URL, protocolType: ProtocolType, authenticationType: AuthenticationType = .default) { + var options = Options() + options.itemClass = .internetPassword + options.server = server + options.protocolType = protocolType + options.authenticationType = authenticationType + self.init(options) + } + + fileprivate init(_ opts: Options) { + options = opts + } + + // MARK: + + public func accessibility(_ accessibility: Accessibility) -> Keychain { + var options = self.options + options.accessibility = accessibility + return Keychain(options) + } + + @available(iOS 8.0, OSX 10.10, *) + @available(watchOS, unavailable) + public func accessibility(_ accessibility: Accessibility, authenticationPolicy: AuthenticationPolicy) -> Keychain { + var options = self.options + options.accessibility = accessibility + options.authenticationPolicy = authenticationPolicy + return Keychain(options) + } + + public func synchronizable(_ synchronizable: Bool) -> Keychain { + var options = self.options + options.synchronizable = synchronizable + return Keychain(options) + } + + public func label(_ label: String) -> Keychain { + var options = self.options + options.label = label + return Keychain(options) + } + + public func comment(_ comment: String) -> Keychain { + var options = self.options + options.comment = comment + return Keychain(options) + } + + public func attributes(_ attributes: [String: Any]) -> Keychain { + var options = self.options + attributes.forEach { options.attributes.updateValue($1, forKey: $0) } + return Keychain(options) + } + + @available(iOS 8.0, OSX 10.10, *) + @available(watchOS, unavailable) + public func authenticationPrompt(_ authenticationPrompt: String) -> Keychain { + var options = self.options + options.authenticationPrompt = authenticationPrompt + return Keychain(options) + } + + #if os(iOS) || os(OSX) + @available(iOS 9.0, OSX 10.11, *) + public func authenticationContext(_ authenticationContext: LAContext) -> Keychain { + var options = self.options + options.authenticationContext = authenticationContext + return Keychain(options) + } + #endif + + // MARK: + + public func get(_ key: String) throws -> String? { + return try getString(key) + } + + public func getString(_ key: String) throws -> String? { + guard let data = try getData(key) else { + return nil + } + guard let string = String(data: data, encoding: .utf8) else { + print("failed to convert data to string") + throw Status.conversionError + } + return string + } + + public func getData(_ key: String) throws -> Data? { + var query = options.query() + + query[MatchLimit] = MatchLimitOne + query[ReturnData] = kCFBooleanTrue + + query[AttributeAccount] = key + + var result: AnyObject? + let status = SecItemCopyMatching(query as CFDictionary, &result) + + switch status { + case errSecSuccess: + guard let data = result as? Data else { + throw Status.unexpectedError + } + return data + case errSecItemNotFound: + return nil + default: + throw securityError(status: status) + } + } + + public func get(_ key: String, handler: (Attributes?) -> T) throws -> T { + var query = options.query() + + query[MatchLimit] = MatchLimitOne + + query[ReturnData] = kCFBooleanTrue + query[ReturnAttributes] = kCFBooleanTrue + query[ReturnRef] = kCFBooleanTrue + query[ReturnPersistentRef] = kCFBooleanTrue + + query[AttributeAccount] = key + + var result: AnyObject? + let status = SecItemCopyMatching(query as CFDictionary, &result) + + switch status { + case errSecSuccess: + guard let attributes = result as? [String: Any] else { + throw Status.unexpectedError + } + return handler(Attributes(attributes: attributes)) + case errSecItemNotFound: + return handler(nil) + default: + throw securityError(status: status) + } + } + + // MARK: + + public func set(_ value: String, key: String) throws { + guard let data = value.data(using: .utf8, allowLossyConversion: false) else { + print("failed to convert string to data") + throw Status.conversionError + } + try set(data, key: key) + } + + public func set(_ value: Data, key: String) throws { + var query = options.query() + query[AttributeAccount] = key + #if os(iOS) + if #available(iOS 9.0, *) { + query[UseAuthenticationUI] = UseAuthenticationUIFail + } else { + query[UseNoAuthenticationUI] = kCFBooleanTrue + } + #elseif os(OSX) + query[ReturnData] = kCFBooleanTrue + if #available(OSX 10.11, *) { + query[UseAuthenticationUI] = UseAuthenticationUIFail + } + #endif + + var status = SecItemCopyMatching(query as CFDictionary, nil) + switch status { + case errSecSuccess, errSecInteractionNotAllowed: + var query = options.query() + query[AttributeAccount] = key + + var (attributes, error) = options.attributes(key: nil, value: value) + if let error = error { + print(error.localizedDescription) + throw error + } + + options.attributes.forEach { attributes.updateValue($1, forKey: $0) } + + #if os(iOS) + if status == errSecInteractionNotAllowed && floor(NSFoundationVersionNumber) <= floor(NSFoundationVersionNumber_iOS_8_0) { + try remove(key) + try set(value, key: key) + } else { + status = SecItemUpdate(query as CFDictionary, attributes as CFDictionary) + if status != errSecSuccess { + throw securityError(status: status) + } + } + #else + status = SecItemUpdate(query as CFDictionary, attributes as CFDictionary) + if status != errSecSuccess { + throw securityError(status: status) + } + #endif + case errSecItemNotFound: + var (attributes, error) = options.attributes(key: key, value: value) + if let error = error { + print(error.localizedDescription) + throw error + } + + options.attributes.forEach { attributes.updateValue($1, forKey: $0) } + + status = SecItemAdd(attributes as CFDictionary, nil) + if status != errSecSuccess { + throw securityError(status: status) + } + default: + throw securityError(status: status) + } + } + + public subscript(key: String) -> String? { + get { + return (try? get(key)).flatMap { $0 } + } + + set { + if let value = newValue { + do { + try set(value, key: key) + } catch {} + } else { + do { + try remove(key) + } catch {} + } + } + } + + public subscript(string key: String) -> String? { + get { + return self[key] + } + + set { + self[key] = newValue + } + } + + public subscript(data key: String) -> Data? { + get { + return (try? getData(key)).flatMap { $0 } + } + + set { + if let value = newValue { + do { + try set(value, key: key) + } catch {} + } else { + do { + try remove(key) + } catch {} + } + } + } + + public subscript(attributes key: String) -> Attributes? { + get { + return (try? get(key) { $0 }).flatMap { $0 } + } + } + + // MARK: + + public func remove(_ key: String) throws { + var query = options.query() + query[AttributeAccount] = key + + let status = SecItemDelete(query as CFDictionary) + if status != errSecSuccess && status != errSecItemNotFound { + throw securityError(status: status) + } + } + + public func removeAll() throws { + var query = options.query() + #if !os(iOS) && !os(watchOS) && !os(tvOS) + query[MatchLimit] = MatchLimitAll + #endif + + let status = SecItemDelete(query as CFDictionary) + if status != errSecSuccess && status != errSecItemNotFound { + throw securityError(status: status) + } + } + + // MARK: + + public func contains(_ key: String) throws -> Bool { + var query = options.query() + query[AttributeAccount] = key + + let status = SecItemCopyMatching(query as CFDictionary, nil) + switch status { + case errSecSuccess: + return true + case errSecItemNotFound: + return false + default: + throw securityError(status: status) + } + } + + // MARK: + + public class func allKeys(_ itemClass: ItemClass) -> [(String, String)] { + var query = [String: Any]() + query[Class] = itemClass.rawValue + query[AttributeSynchronizable] = SynchronizableAny + query[MatchLimit] = MatchLimitAll + query[ReturnAttributes] = kCFBooleanTrue + + var result: AnyObject? + let status = SecItemCopyMatching(query as CFDictionary, &result) + + switch status { + case errSecSuccess: + if let items = result as? [[String: Any]] { + return prettify(itemClass: itemClass, items: items).map { + switch itemClass { + case .genericPassword: + return (($0["service"] ?? "") as! String, ($0["key"] ?? "") as! String) + case .internetPassword: + return (($0["server"] ?? "") as! String, ($0["key"] ?? "") as! String) + } + } + } + case errSecItemNotFound: + return [] + default: () + } + + securityError(status: status) + return [] + } + + public func allKeys() -> [String] { + let allItems = type(of: self).prettify(itemClass: itemClass, items: items()) + let filter: ([String: Any]) -> String? = { $0["key"] as? String } + + #if swift(>=4.1) + return allItems.compactMap(filter) + #else + return allItems.flatMap(filter) + #endif + } + + public class func allItems(_ itemClass: ItemClass) -> [[String: Any]] { + var query = [String: Any]() + query[Class] = itemClass.rawValue + query[MatchLimit] = MatchLimitAll + query[ReturnAttributes] = kCFBooleanTrue + #if os(iOS) || os(watchOS) || os(tvOS) + query[ReturnData] = kCFBooleanTrue + #endif + + var result: AnyObject? + let status = SecItemCopyMatching(query as CFDictionary, &result) + + switch status { + case errSecSuccess: + if let items = result as? [[String: Any]] { + return prettify(itemClass: itemClass, items: items) + } + case errSecItemNotFound: + return [] + default: () + } + + securityError(status: status) + return [] + } + + public func allItems() -> [[String: Any]] { + return type(of: self).prettify(itemClass: itemClass, items: items()) + } + + #if os(iOS) + @available(iOS 8.0, *) + public func getSharedPassword(_ completion: @escaping (_ account: String?, _ password: String?, _ error: Error?) -> () = { account, password, error -> () in }) { + if let domain = server.host { + type(of: self).requestSharedWebCredential(domain: domain, account: nil) { (credentials, error) -> () in + if let credential = credentials.first { + let account = credential["account"] + let password = credential["password"] + completion(account, password, error) + } else { + completion(nil, nil, error) + } + } + } else { + let error = securityError(status: Status.param.rawValue) + completion(nil, nil, error) + } + } + #endif + + #if os(iOS) + @available(iOS 8.0, *) + public func getSharedPassword(_ account: String, completion: @escaping (_ password: String?, _ error: Error?) -> () = { password, error -> () in }) { + if let domain = server.host { + type(of: self).requestSharedWebCredential(domain: domain, account: account) { (credentials, error) -> () in + if let credential = credentials.first { + if let password = credential["password"] { + completion(password, error) + } else { + completion(nil, error) + } + } else { + completion(nil, error) + } + } + } else { + let error = securityError(status: Status.param.rawValue) + completion(nil, error) + } + } + #endif + + #if os(iOS) + @available(iOS 8.0, *) + public func setSharedPassword(_ password: String, account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in }) { + setSharedPassword(password as String?, account: account, completion: completion) + } + #endif + + #if os(iOS) + @available(iOS 8.0, *) + fileprivate func setSharedPassword(_ password: String?, account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in }) { + if let domain = server.host { + SecAddSharedWebCredential(domain as CFString, account as CFString, password as CFString?) { error -> () in + if let error = error { + completion(error.error) + } else { + completion(nil) + } + } + } else { + let error = securityError(status: Status.param.rawValue) + completion(error) + } + } + #endif + + #if os(iOS) + @available(iOS 8.0, *) + public func removeSharedPassword(_ account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in }) { + setSharedPassword(nil, account: account, completion: completion) + } + #endif + + #if os(iOS) + @available(iOS 8.0, *) + public class func requestSharedWebCredential(_ completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in }) { + requestSharedWebCredential(domain: nil, account: nil, completion: completion) + } + #endif + + #if os(iOS) + @available(iOS 8.0, *) + public class func requestSharedWebCredential(domain: String, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in }) { + requestSharedWebCredential(domain: domain, account: nil, completion: completion) + } + #endif + + #if os(iOS) + @available(iOS 8.0, *) + public class func requestSharedWebCredential(domain: String, account: String, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in }) { + requestSharedWebCredential(domain: Optional(domain), account: Optional(account)!, completion: completion) + } + #endif + + #if os(iOS) + @available(iOS 8.0, *) + fileprivate class func requestSharedWebCredential(domain: String?, account: String?, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> ()) { + SecRequestSharedWebCredential(domain as CFString?, account as CFString?) { (credentials, error) -> () in + var remoteError: NSError? + if let error = error { + remoteError = error.error + if remoteError?.code != Int(errSecItemNotFound) { + print("error:[\(remoteError!.code)] \(remoteError!.localizedDescription)") + } + } + if let credentials = credentials { + let credentials = (credentials as NSArray).map { credentials -> [String: String] in + var credential = [String: String]() + if let credentials = credentials as? [String: String] { + if let server = credentials[AttributeServer] { + credential["server"] = server + } + if let account = credentials[AttributeAccount] { + credential["account"] = account + } + if let password = credentials[SharedPassword] { + credential["password"] = password + } + } + return credential + } + completion(credentials, remoteError) + } else { + completion([], remoteError) + } + } + } + #endif + + #if os(iOS) + /** + @abstract Returns a randomly generated password. + @return String password in the form xxx-xxx-xxx-xxx where x is taken from the sets "abcdefghkmnopqrstuvwxy", "ABCDEFGHJKLMNPQRSTUVWXYZ", "3456789" with at least one character from each set being present. + */ + @available(iOS 8.0, *) + public class func generatePassword() -> String { + return SecCreateSharedWebCredentialPassword()! as String + } + #endif + + // MARK: + + fileprivate func items() -> [[String: Any]] { + var query = options.query() + query[MatchLimit] = MatchLimitAll + query[ReturnAttributes] = kCFBooleanTrue + #if os(iOS) || os(watchOS) || os(tvOS) + query[ReturnData] = kCFBooleanTrue + #endif + + var result: AnyObject? + let status = SecItemCopyMatching(query as CFDictionary, &result) + + switch status { + case errSecSuccess: + if let items = result as? [[String: Any]] { + return items + } + case errSecItemNotFound: + return [] + default: () + } + + securityError(status: status) + return [] + } + + fileprivate class func prettify(itemClass: ItemClass, items: [[String: Any]]) -> [[String: Any]] { + let items = items.map { attributes -> [String: Any] in + var item = [String: Any]() + + item["class"] = itemClass.description + + switch itemClass { + case .genericPassword: + if let service = attributes[AttributeService] as? String { + item["service"] = service + } + if let accessGroup = attributes[AttributeAccessGroup] as? String { + item["accessGroup"] = accessGroup + } + case .internetPassword: + if let server = attributes[AttributeServer] as? String { + item["server"] = server + } + if let proto = attributes[AttributeProtocol] as? String { + if let protocolType = ProtocolType(rawValue: proto) { + item["protocol"] = protocolType.description + } + } + if let auth = attributes[AttributeAuthenticationType] as? String { + if let authenticationType = AuthenticationType(rawValue: auth) { + item["authenticationType"] = authenticationType.description + } + } + } + + if let key = attributes[AttributeAccount] as? String { + item["key"] = key + } + if let data = attributes[ValueData] as? Data { + if let text = String(data: data, encoding: .utf8) { + item["value"] = text + } else { + item["value"] = data + } + } + + if let accessible = attributes[AttributeAccessible] as? String { + if let accessibility = Accessibility(rawValue: accessible) { + item["accessibility"] = accessibility.description + } + } + if let synchronizable = attributes[AttributeSynchronizable] as? Bool { + item["synchronizable"] = synchronizable ? "true" : "false" + } + + return item + } + return items + } + + // MARK: + + @discardableResult + fileprivate class func securityError(status: OSStatus) -> Error { + let error = Status(status: status) + print("OSStatus error:[\(error.errorCode)] \(error.description)") + + return error + } + + @discardableResult + fileprivate func securityError(status: OSStatus) -> Error { + return type(of: self).securityError(status: status) + } +} + +struct Options { + var itemClass: ItemClass = .genericPassword + + var service: String = "" + var accessGroup: String? = nil + + var server: URL! + var protocolType: ProtocolType! + var authenticationType: AuthenticationType = .default + + var accessibility: Accessibility = .afterFirstUnlock + var authenticationPolicy: AuthenticationPolicy? + + var synchronizable: Bool = false + + var label: String? + var comment: String? + + var authenticationPrompt: String? + var authenticationContext: AnyObject? + + var attributes = [String: Any]() +} + +/** Class Key Constant */ +private let Class = String(kSecClass) + +/** Attribute Key Constants */ +private let AttributeAccessible = String(kSecAttrAccessible) + +@available(iOS 8.0, OSX 10.10, *) +private let AttributeAccessControl = String(kSecAttrAccessControl) + +private let AttributeAccessGroup = String(kSecAttrAccessGroup) +private let AttributeSynchronizable = String(kSecAttrSynchronizable) +private let AttributeCreationDate = String(kSecAttrCreationDate) +private let AttributeModificationDate = String(kSecAttrModificationDate) +private let AttributeDescription = String(kSecAttrDescription) +private let AttributeComment = String(kSecAttrComment) +private let AttributeCreator = String(kSecAttrCreator) +private let AttributeType = String(kSecAttrType) +private let AttributeLabel = String(kSecAttrLabel) +private let AttributeIsInvisible = String(kSecAttrIsInvisible) +private let AttributeIsNegative = String(kSecAttrIsNegative) +private let AttributeAccount = String(kSecAttrAccount) +private let AttributeService = String(kSecAttrService) +private let AttributeGeneric = String(kSecAttrGeneric) +private let AttributeSecurityDomain = String(kSecAttrSecurityDomain) +private let AttributeServer = String(kSecAttrServer) +private let AttributeProtocol = String(kSecAttrProtocol) +private let AttributeAuthenticationType = String(kSecAttrAuthenticationType) +private let AttributePort = String(kSecAttrPort) +private let AttributePath = String(kSecAttrPath) + +private let SynchronizableAny = kSecAttrSynchronizableAny + +/** Search Constants */ +private let MatchLimit = String(kSecMatchLimit) +private let MatchLimitOne = kSecMatchLimitOne +private let MatchLimitAll = kSecMatchLimitAll + +/** Return Type Key Constants */ +private let ReturnData = String(kSecReturnData) +private let ReturnAttributes = String(kSecReturnAttributes) +private let ReturnRef = String(kSecReturnRef) +private let ReturnPersistentRef = String(kSecReturnPersistentRef) + +/** Value Type Key Constants */ +private let ValueData = String(kSecValueData) +private let ValueRef = String(kSecValueRef) +private let ValuePersistentRef = String(kSecValuePersistentRef) + +/** Other Constants */ +@available(iOS 8.0, OSX 10.10, *) +private let UseOperationPrompt = String(kSecUseOperationPrompt) + +#if os(iOS) +@available(iOS, introduced: 8.0, deprecated: 9.0, message: "Use a UseAuthenticationUI instead.") +private let UseNoAuthenticationUI = String(kSecUseNoAuthenticationUI) +#endif + +@available(iOS 9.0, OSX 10.11, *) +@available(watchOS, unavailable) +private let UseAuthenticationUI = String(kSecUseAuthenticationUI) + +@available(iOS 9.0, OSX 10.11, *) +@available(watchOS, unavailable) +private let UseAuthenticationContext = String(kSecUseAuthenticationContext) + +@available(iOS 9.0, OSX 10.11, *) +@available(watchOS, unavailable) +private let UseAuthenticationUIAllow = String(kSecUseAuthenticationUIAllow) + +@available(iOS 9.0, OSX 10.11, *) +@available(watchOS, unavailable) +private let UseAuthenticationUIFail = String(kSecUseAuthenticationUIFail) + +@available(iOS 9.0, OSX 10.11, *) +@available(watchOS, unavailable) +private let UseAuthenticationUISkip = String(kSecUseAuthenticationUISkip) + +#if os(iOS) +/** Credential Key Constants */ +private let SharedPassword = String(kSecSharedPassword) +#endif + +extension Keychain: CustomStringConvertible, CustomDebugStringConvertible { + public var description: String { + let items = allItems() + if items.isEmpty { + return "[]" + } + var description = "[\n" + for item in items { + description += " " + description += "\(item)\n" + } + description += "]" + return description + } + + public var debugDescription: String { + return "\(items())" + } +} + +extension Options { + + func query() -> [String: Any] { + var query = [String: Any]() + + query[Class] = itemClass.rawValue + query[AttributeSynchronizable] = SynchronizableAny + + switch itemClass { + case .genericPassword: + query[AttributeService] = service + // Access group is not supported on any simulators. + #if (!arch(i386) && !arch(x86_64)) || (!os(iOS) && !os(watchOS) && !os(tvOS)) + if let accessGroup = self.accessGroup { + query[AttributeAccessGroup] = accessGroup + } + #endif + case .internetPassword: + query[AttributeServer] = server.host + query[AttributePort] = server.port + query[AttributeProtocol] = protocolType.rawValue + query[AttributeAuthenticationType] = authenticationType.rawValue + } + + if #available(OSX 10.10, *) { + if authenticationPrompt != nil { + query[UseOperationPrompt] = authenticationPrompt + } + } + + #if !os(watchOS) + if #available(iOS 9.0, OSX 10.11, *) { + if authenticationContext != nil { + query[UseAuthenticationContext] = authenticationContext + } + } + #endif + + return query + } + + func attributes(key: String?, value: Data) -> ([String: Any], Error?) { + var attributes: [String: Any] + + if key != nil { + attributes = query() + attributes[AttributeAccount] = key + } else { + attributes = [String: Any]() + } + + attributes[ValueData] = value + + if label != nil { + attributes[AttributeLabel] = label + } + if comment != nil { + attributes[AttributeComment] = comment + } + + if let policy = authenticationPolicy { + if #available(OSX 10.10, *) { + var error: Unmanaged? + guard let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, SecAccessControlCreateFlags(rawValue: CFOptionFlags(policy.rawValue)), &error) else { + if let error = error?.takeUnretainedValue() { + return (attributes, error.error) + } + + return (attributes, Status.unexpectedError) + } + attributes[AttributeAccessControl] = accessControl + } else { + print("Unavailable 'Touch ID integration' on OS X versions prior to 10.10.") + } + } else { + attributes[AttributeAccessible] = accessibility.rawValue + } + + attributes[AttributeSynchronizable] = synchronizable ? kCFBooleanTrue : kCFBooleanFalse + + return (attributes, nil) + } +} + +// MARK: + +extension Attributes: CustomStringConvertible, CustomDebugStringConvertible { + public var description: String { + return "\(attributes)" + } + + public var debugDescription: String { + return description + } +} + +extension ItemClass: RawRepresentable, CustomStringConvertible { + + public init?(rawValue: String) { + switch rawValue { + case String(kSecClassGenericPassword): + self = .genericPassword + case String(kSecClassInternetPassword): + self = .internetPassword + default: + return nil + } + } + + public var rawValue: String { + switch self { + case .genericPassword: + return String(kSecClassGenericPassword) + case .internetPassword: + return String(kSecClassInternetPassword) + } + } + + public var description: String { + switch self { + case .genericPassword: + return "GenericPassword" + case .internetPassword: + return "InternetPassword" + } + } +} + +extension ProtocolType: RawRepresentable, CustomStringConvertible { + + public init?(rawValue: String) { + switch rawValue { + case String(kSecAttrProtocolFTP): + self = .ftp + case String(kSecAttrProtocolFTPAccount): + self = .ftpAccount + case String(kSecAttrProtocolHTTP): + self = .http + case String(kSecAttrProtocolIRC): + self = .irc + case String(kSecAttrProtocolNNTP): + self = .nntp + case String(kSecAttrProtocolPOP3): + self = .pop3 + case String(kSecAttrProtocolSMTP): + self = .smtp + case String(kSecAttrProtocolSOCKS): + self = .socks + case String(kSecAttrProtocolIMAP): + self = .imap + case String(kSecAttrProtocolLDAP): + self = .ldap + case String(kSecAttrProtocolAppleTalk): + self = .appleTalk + case String(kSecAttrProtocolAFP): + self = .afp + case String(kSecAttrProtocolTelnet): + self = .telnet + case String(kSecAttrProtocolSSH): + self = .ssh + case String(kSecAttrProtocolFTPS): + self = .ftps + case String(kSecAttrProtocolHTTPS): + self = .https + case String(kSecAttrProtocolHTTPProxy): + self = .httpProxy + case String(kSecAttrProtocolHTTPSProxy): + self = .httpsProxy + case String(kSecAttrProtocolFTPProxy): + self = .ftpProxy + case String(kSecAttrProtocolSMB): + self = .smb + case String(kSecAttrProtocolRTSP): + self = .rtsp + case String(kSecAttrProtocolRTSPProxy): + self = .rtspProxy + case String(kSecAttrProtocolDAAP): + self = .daap + case String(kSecAttrProtocolEPPC): + self = .eppc + case String(kSecAttrProtocolIPP): + self = .ipp + case String(kSecAttrProtocolNNTPS): + self = .nntps + case String(kSecAttrProtocolLDAPS): + self = .ldaps + case String(kSecAttrProtocolTelnetS): + self = .telnetS + case String(kSecAttrProtocolIMAPS): + self = .imaps + case String(kSecAttrProtocolIRCS): + self = .ircs + case String(kSecAttrProtocolPOP3S): + self = .pop3S + default: + return nil + } + } + + public var rawValue: String { + switch self { + case .ftp: + return String(kSecAttrProtocolFTP) + case .ftpAccount: + return String(kSecAttrProtocolFTPAccount) + case .http: + return String(kSecAttrProtocolHTTP) + case .irc: + return String(kSecAttrProtocolIRC) + case .nntp: + return String(kSecAttrProtocolNNTP) + case .pop3: + return String(kSecAttrProtocolPOP3) + case .smtp: + return String(kSecAttrProtocolSMTP) + case .socks: + return String(kSecAttrProtocolSOCKS) + case .imap: + return String(kSecAttrProtocolIMAP) + case .ldap: + return String(kSecAttrProtocolLDAP) + case .appleTalk: + return String(kSecAttrProtocolAppleTalk) + case .afp: + return String(kSecAttrProtocolAFP) + case .telnet: + return String(kSecAttrProtocolTelnet) + case .ssh: + return String(kSecAttrProtocolSSH) + case .ftps: + return String(kSecAttrProtocolFTPS) + case .https: + return String(kSecAttrProtocolHTTPS) + case .httpProxy: + return String(kSecAttrProtocolHTTPProxy) + case .httpsProxy: + return String(kSecAttrProtocolHTTPSProxy) + case .ftpProxy: + return String(kSecAttrProtocolFTPProxy) + case .smb: + return String(kSecAttrProtocolSMB) + case .rtsp: + return String(kSecAttrProtocolRTSP) + case .rtspProxy: + return String(kSecAttrProtocolRTSPProxy) + case .daap: + return String(kSecAttrProtocolDAAP) + case .eppc: + return String(kSecAttrProtocolEPPC) + case .ipp: + return String(kSecAttrProtocolIPP) + case .nntps: + return String(kSecAttrProtocolNNTPS) + case .ldaps: + return String(kSecAttrProtocolLDAPS) + case .telnetS: + return String(kSecAttrProtocolTelnetS) + case .imaps: + return String(kSecAttrProtocolIMAPS) + case .ircs: + return String(kSecAttrProtocolIRCS) + case .pop3S: + return String(kSecAttrProtocolPOP3S) + } + } + + public var description: String { + switch self { + case .ftp: + return "FTP" + case .ftpAccount: + return "FTPAccount" + case .http: + return "HTTP" + case .irc: + return "IRC" + case .nntp: + return "NNTP" + case .pop3: + return "POP3" + case .smtp: + return "SMTP" + case .socks: + return "SOCKS" + case .imap: + return "IMAP" + case .ldap: + return "LDAP" + case .appleTalk: + return "AppleTalk" + case .afp: + return "AFP" + case .telnet: + return "Telnet" + case .ssh: + return "SSH" + case .ftps: + return "FTPS" + case .https: + return "HTTPS" + case .httpProxy: + return "HTTPProxy" + case .httpsProxy: + return "HTTPSProxy" + case .ftpProxy: + return "FTPProxy" + case .smb: + return "SMB" + case .rtsp: + return "RTSP" + case .rtspProxy: + return "RTSPProxy" + case .daap: + return "DAAP" + case .eppc: + return "EPPC" + case .ipp: + return "IPP" + case .nntps: + return "NNTPS" + case .ldaps: + return "LDAPS" + case .telnetS: + return "TelnetS" + case .imaps: + return "IMAPS" + case .ircs: + return "IRCS" + case .pop3S: + return "POP3S" + } + } +} + +extension AuthenticationType: RawRepresentable, CustomStringConvertible { + + public init?(rawValue: String) { + switch rawValue { + case String(kSecAttrAuthenticationTypeNTLM): + self = .ntlm + case String(kSecAttrAuthenticationTypeMSN): + self = .msn + case String(kSecAttrAuthenticationTypeDPA): + self = .dpa + case String(kSecAttrAuthenticationTypeRPA): + self = .rpa + case String(kSecAttrAuthenticationTypeHTTPBasic): + self = .httpBasic + case String(kSecAttrAuthenticationTypeHTTPDigest): + self = .httpDigest + case String(kSecAttrAuthenticationTypeHTMLForm): + self = .htmlForm + case String(kSecAttrAuthenticationTypeDefault): + self = .`default` + default: + return nil + } + } + + public var rawValue: String { + switch self { + case .ntlm: + return String(kSecAttrAuthenticationTypeNTLM) + case .msn: + return String(kSecAttrAuthenticationTypeMSN) + case .dpa: + return String(kSecAttrAuthenticationTypeDPA) + case .rpa: + return String(kSecAttrAuthenticationTypeRPA) + case .httpBasic: + return String(kSecAttrAuthenticationTypeHTTPBasic) + case .httpDigest: + return String(kSecAttrAuthenticationTypeHTTPDigest) + case .htmlForm: + return String(kSecAttrAuthenticationTypeHTMLForm) + case .`default`: + return String(kSecAttrAuthenticationTypeDefault) + } + } + + public var description: String { + switch self { + case .ntlm: + return "NTLM" + case .msn: + return "MSN" + case .dpa: + return "DPA" + case .rpa: + return "RPA" + case .httpBasic: + return "HTTPBasic" + case .httpDigest: + return "HTTPDigest" + case .htmlForm: + return "HTMLForm" + case .`default`: + return "Default" + } + } +} + +extension Accessibility: RawRepresentable, CustomStringConvertible { + + public init?(rawValue: String) { + if #available(OSX 10.10, *) { + switch rawValue { + case String(kSecAttrAccessibleWhenUnlocked): + self = .whenUnlocked + case String(kSecAttrAccessibleAfterFirstUnlock): + self = .afterFirstUnlock + case String(kSecAttrAccessibleAlways): + self = .always + case String(kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly): + self = .whenPasscodeSetThisDeviceOnly + case String(kSecAttrAccessibleWhenUnlockedThisDeviceOnly): + self = .whenUnlockedThisDeviceOnly + case String(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly): + self = .afterFirstUnlockThisDeviceOnly + case String(kSecAttrAccessibleAlwaysThisDeviceOnly): + self = .alwaysThisDeviceOnly + default: + return nil + } + } else { + switch rawValue { + case String(kSecAttrAccessibleWhenUnlocked): + self = .whenUnlocked + case String(kSecAttrAccessibleAfterFirstUnlock): + self = .afterFirstUnlock + case String(kSecAttrAccessibleAlways): + self = .always + case String(kSecAttrAccessibleWhenUnlockedThisDeviceOnly): + self = .whenUnlockedThisDeviceOnly + case String(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly): + self = .afterFirstUnlockThisDeviceOnly + case String(kSecAttrAccessibleAlwaysThisDeviceOnly): + self = .alwaysThisDeviceOnly + default: + return nil + } + } + } + + public var rawValue: String { + switch self { + case .whenUnlocked: + return String(kSecAttrAccessibleWhenUnlocked) + case .afterFirstUnlock: + return String(kSecAttrAccessibleAfterFirstUnlock) + case .always: + return String(kSecAttrAccessibleAlways) + case .whenPasscodeSetThisDeviceOnly: + if #available(OSX 10.10, *) { + return String(kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly) + } else { + fatalError("'Accessibility.WhenPasscodeSetThisDeviceOnly' is not available on this version of OS.") + } + case .whenUnlockedThisDeviceOnly: + return String(kSecAttrAccessibleWhenUnlockedThisDeviceOnly) + case .afterFirstUnlockThisDeviceOnly: + return String(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly) + case .alwaysThisDeviceOnly: + return String(kSecAttrAccessibleAlwaysThisDeviceOnly) + } + } + + public var description: String { + switch self { + case .whenUnlocked: + return "WhenUnlocked" + case .afterFirstUnlock: + return "AfterFirstUnlock" + case .always: + return "Always" + case .whenPasscodeSetThisDeviceOnly: + return "WhenPasscodeSetThisDeviceOnly" + case .whenUnlockedThisDeviceOnly: + return "WhenUnlockedThisDeviceOnly" + case .afterFirstUnlockThisDeviceOnly: + return "AfterFirstUnlockThisDeviceOnly" + case .alwaysThisDeviceOnly: + return "AlwaysThisDeviceOnly" + } + } +} + +extension CFError { + var error: NSError { + let domain = CFErrorGetDomain(self) as String + let code = CFErrorGetCode(self) + let userInfo = CFErrorCopyUserInfo(self) as! [String: Any] + + return NSError(domain: domain, code: code, userInfo: userInfo) + } +} + +public enum Status: OSStatus, Error { + case success = 0 + case unimplemented = -4 + case diskFull = -34 + case io = -36 + case opWr = -49 + case param = -50 + case wrPerm = -61 + case allocate = -108 + case userCanceled = -128 + case badReq = -909 + case internalComponent = -2070 + case notAvailable = -25291 + case readOnly = -25292 + case authFailed = -25293 + case noSuchKeychain = -25294 + case invalidKeychain = -25295 + case duplicateKeychain = -25296 + case duplicateCallback = -25297 + case invalidCallback = -25298 + case duplicateItem = -25299 + case itemNotFound = -25300 + case bufferTooSmall = -25301 + case dataTooLarge = -25302 + case noSuchAttr = -25303 + case invalidItemRef = -25304 + case invalidSearchRef = -25305 + case noSuchClass = -25306 + case noDefaultKeychain = -25307 + case interactionNotAllowed = -25308 + case readOnlyAttr = -25309 + case wrongSecVersion = -25310 + case keySizeNotAllowed = -25311 + case noStorageModule = -25312 + case noCertificateModule = -25313 + case noPolicyModule = -25314 + case interactionRequired = -25315 + case dataNotAvailable = -25316 + case dataNotModifiable = -25317 + case createChainFailed = -25318 + case invalidPrefsDomain = -25319 + case inDarkWake = -25320 + case aclNotSimple = -25240 + case policyNotFound = -25241 + case invalidTrustSetting = -25242 + case noAccessForItem = -25243 + case invalidOwnerEdit = -25244 + case trustNotAvailable = -25245 + case unsupportedFormat = -25256 + case unknownFormat = -25257 + case keyIsSensitive = -25258 + case multiplePrivKeys = -25259 + case passphraseRequired = -25260 + case invalidPasswordRef = -25261 + case invalidTrustSettings = -25262 + case noTrustSettings = -25263 + case pkcs12VerifyFailure = -25264 + case invalidCertificate = -26265 + case notSigner = -26267 + case policyDenied = -26270 + case invalidKey = -26274 + case decode = -26275 + case `internal` = -26276 + case unsupportedAlgorithm = -26268 + case unsupportedOperation = -26271 + case unsupportedPadding = -26273 + case itemInvalidKey = -34000 + case itemInvalidKeyType = -34001 + case itemInvalidValue = -34002 + case itemClassMissing = -34003 + case itemMatchUnsupported = -34004 + case useItemListUnsupported = -34005 + case useKeychainUnsupported = -34006 + case useKeychainListUnsupported = -34007 + case returnDataUnsupported = -34008 + case returnAttributesUnsupported = -34009 + case returnRefUnsupported = -34010 + case returnPersitentRefUnsupported = -34011 + case valueRefUnsupported = -34012 + case valuePersistentRefUnsupported = -34013 + case returnMissingPointer = -34014 + case matchLimitUnsupported = -34015 + case itemIllegalQuery = -34016 + case waitForCallback = -34017 + case missingEntitlement = -34018 + case upgradePending = -34019 + case mpSignatureInvalid = -25327 + case otrTooOld = -25328 + case otrIDTooNew = -25329 + case serviceNotAvailable = -67585 + case insufficientClientID = -67586 + case deviceReset = -67587 + case deviceFailed = -67588 + case appleAddAppACLSubject = -67589 + case applePublicKeyIncomplete = -67590 + case appleSignatureMismatch = -67591 + case appleInvalidKeyStartDate = -67592 + case appleInvalidKeyEndDate = -67593 + case conversionError = -67594 + case appleSSLv2Rollback = -67595 + case quotaExceeded = -67596 + case fileTooBig = -67597 + case invalidDatabaseBlob = -67598 + case invalidKeyBlob = -67599 + case incompatibleDatabaseBlob = -67600 + case incompatibleKeyBlob = -67601 + case hostNameMismatch = -67602 + case unknownCriticalExtensionFlag = -67603 + case noBasicConstraints = -67604 + case noBasicConstraintsCA = -67605 + case invalidAuthorityKeyID = -67606 + case invalidSubjectKeyID = -67607 + case invalidKeyUsageForPolicy = -67608 + case invalidExtendedKeyUsage = -67609 + case invalidIDLinkage = -67610 + case pathLengthConstraintExceeded = -67611 + case invalidRoot = -67612 + case crlExpired = -67613 + case crlNotValidYet = -67614 + case crlNotFound = -67615 + case crlServerDown = -67616 + case crlBadURI = -67617 + case unknownCertExtension = -67618 + case unknownCRLExtension = -67619 + case crlNotTrusted = -67620 + case crlPolicyFailed = -67621 + case idpFailure = -67622 + case smimeEmailAddressesNotFound = -67623 + case smimeBadExtendedKeyUsage = -67624 + case smimeBadKeyUsage = -67625 + case smimeKeyUsageNotCritical = -67626 + case smimeNoEmailAddress = -67627 + case smimeSubjAltNameNotCritical = -67628 + case sslBadExtendedKeyUsage = -67629 + case ocspBadResponse = -67630 + case ocspBadRequest = -67631 + case ocspUnavailable = -67632 + case ocspStatusUnrecognized = -67633 + case endOfData = -67634 + case incompleteCertRevocationCheck = -67635 + case networkFailure = -67636 + case ocspNotTrustedToAnchor = -67637 + case recordModified = -67638 + case ocspSignatureError = -67639 + case ocspNoSigner = -67640 + case ocspResponderMalformedReq = -67641 + case ocspResponderInternalError = -67642 + case ocspResponderTryLater = -67643 + case ocspResponderSignatureRequired = -67644 + case ocspResponderUnauthorized = -67645 + case ocspResponseNonceMismatch = -67646 + case codeSigningBadCertChainLength = -67647 + case codeSigningNoBasicConstraints = -67648 + case codeSigningBadPathLengthConstraint = -67649 + case codeSigningNoExtendedKeyUsage = -67650 + case codeSigningDevelopment = -67651 + case resourceSignBadCertChainLength = -67652 + case resourceSignBadExtKeyUsage = -67653 + case trustSettingDeny = -67654 + case invalidSubjectName = -67655 + case unknownQualifiedCertStatement = -67656 + case mobileMeRequestQueued = -67657 + case mobileMeRequestRedirected = -67658 + case mobileMeServerError = -67659 + case mobileMeServerNotAvailable = -67660 + case mobileMeServerAlreadyExists = -67661 + case mobileMeServerServiceErr = -67662 + case mobileMeRequestAlreadyPending = -67663 + case mobileMeNoRequestPending = -67664 + case mobileMeCSRVerifyFailure = -67665 + case mobileMeFailedConsistencyCheck = -67666 + case notInitialized = -67667 + case invalidHandleUsage = -67668 + case pvcReferentNotFound = -67669 + case functionIntegrityFail = -67670 + case internalError = -67671 + case memoryError = -67672 + case invalidData = -67673 + case mdsError = -67674 + case invalidPointer = -67675 + case selfCheckFailed = -67676 + case functionFailed = -67677 + case moduleManifestVerifyFailed = -67678 + case invalidGUID = -67679 + case invalidHandle = -67680 + case invalidDBList = -67681 + case invalidPassthroughID = -67682 + case invalidNetworkAddress = -67683 + case crlAlreadySigned = -67684 + case invalidNumberOfFields = -67685 + case verificationFailure = -67686 + case unknownTag = -67687 + case invalidSignature = -67688 + case invalidName = -67689 + case invalidCertificateRef = -67690 + case invalidCertificateGroup = -67691 + case tagNotFound = -67692 + case invalidQuery = -67693 + case invalidValue = -67694 + case callbackFailed = -67695 + case aclDeleteFailed = -67696 + case aclReplaceFailed = -67697 + case aclAddFailed = -67698 + case aclChangeFailed = -67699 + case invalidAccessCredentials = -67700 + case invalidRecord = -67701 + case invalidACL = -67702 + case invalidSampleValue = -67703 + case incompatibleVersion = -67704 + case privilegeNotGranted = -67705 + case invalidScope = -67706 + case pvcAlreadyConfigured = -67707 + case invalidPVC = -67708 + case emmLoadFailed = -67709 + case emmUnloadFailed = -67710 + case addinLoadFailed = -67711 + case invalidKeyRef = -67712 + case invalidKeyHierarchy = -67713 + case addinUnloadFailed = -67714 + case libraryReferenceNotFound = -67715 + case invalidAddinFunctionTable = -67716 + case invalidServiceMask = -67717 + case moduleNotLoaded = -67718 + case invalidSubServiceID = -67719 + case attributeNotInContext = -67720 + case moduleManagerInitializeFailed = -67721 + case moduleManagerNotFound = -67722 + case eventNotificationCallbackNotFound = -67723 + case inputLengthError = -67724 + case outputLengthError = -67725 + case privilegeNotSupported = -67726 + case deviceError = -67727 + case attachHandleBusy = -67728 + case notLoggedIn = -67729 + case algorithmMismatch = -67730 + case keyUsageIncorrect = -67731 + case keyBlobTypeIncorrect = -67732 + case keyHeaderInconsistent = -67733 + case unsupportedKeyFormat = -67734 + case unsupportedKeySize = -67735 + case invalidKeyUsageMask = -67736 + case unsupportedKeyUsageMask = -67737 + case invalidKeyAttributeMask = -67738 + case unsupportedKeyAttributeMask = -67739 + case invalidKeyLabel = -67740 + case unsupportedKeyLabel = -67741 + case invalidKeyFormat = -67742 + case unsupportedVectorOfBuffers = -67743 + case invalidInputVector = -67744 + case invalidOutputVector = -67745 + case invalidContext = -67746 + case invalidAlgorithm = -67747 + case invalidAttributeKey = -67748 + case missingAttributeKey = -67749 + case invalidAttributeInitVector = -67750 + case missingAttributeInitVector = -67751 + case invalidAttributeSalt = -67752 + case missingAttributeSalt = -67753 + case invalidAttributePadding = -67754 + case missingAttributePadding = -67755 + case invalidAttributeRandom = -67756 + case missingAttributeRandom = -67757 + case invalidAttributeSeed = -67758 + case missingAttributeSeed = -67759 + case invalidAttributePassphrase = -67760 + case missingAttributePassphrase = -67761 + case invalidAttributeKeyLength = -67762 + case missingAttributeKeyLength = -67763 + case invalidAttributeBlockSize = -67764 + case missingAttributeBlockSize = -67765 + case invalidAttributeOutputSize = -67766 + case missingAttributeOutputSize = -67767 + case invalidAttributeRounds = -67768 + case missingAttributeRounds = -67769 + case invalidAlgorithmParms = -67770 + case missingAlgorithmParms = -67771 + case invalidAttributeLabel = -67772 + case missingAttributeLabel = -67773 + case invalidAttributeKeyType = -67774 + case missingAttributeKeyType = -67775 + case invalidAttributeMode = -67776 + case missingAttributeMode = -67777 + case invalidAttributeEffectiveBits = -67778 + case missingAttributeEffectiveBits = -67779 + case invalidAttributeStartDate = -67780 + case missingAttributeStartDate = -67781 + case invalidAttributeEndDate = -67782 + case missingAttributeEndDate = -67783 + case invalidAttributeVersion = -67784 + case missingAttributeVersion = -67785 + case invalidAttributePrime = -67786 + case missingAttributePrime = -67787 + case invalidAttributeBase = -67788 + case missingAttributeBase = -67789 + case invalidAttributeSubprime = -67790 + case missingAttributeSubprime = -67791 + case invalidAttributeIterationCount = -67792 + case missingAttributeIterationCount = -67793 + case invalidAttributeDLDBHandle = -67794 + case missingAttributeDLDBHandle = -67795 + case invalidAttributeAccessCredentials = -67796 + case missingAttributeAccessCredentials = -67797 + case invalidAttributePublicKeyFormat = -67798 + case missingAttributePublicKeyFormat = -67799 + case invalidAttributePrivateKeyFormat = -67800 + case missingAttributePrivateKeyFormat = -67801 + case invalidAttributeSymmetricKeyFormat = -67802 + case missingAttributeSymmetricKeyFormat = -67803 + case invalidAttributeWrappedKeyFormat = -67804 + case missingAttributeWrappedKeyFormat = -67805 + case stagedOperationInProgress = -67806 + case stagedOperationNotStarted = -67807 + case verifyFailed = -67808 + case querySizeUnknown = -67809 + case blockSizeMismatch = -67810 + case publicKeyInconsistent = -67811 + case deviceVerifyFailed = -67812 + case invalidLoginName = -67813 + case alreadyLoggedIn = -67814 + case invalidDigestAlgorithm = -67815 + case invalidCRLGroup = -67816 + case certificateCannotOperate = -67817 + case certificateExpired = -67818 + case certificateNotValidYet = -67819 + case certificateRevoked = -67820 + case certificateSuspended = -67821 + case insufficientCredentials = -67822 + case invalidAction = -67823 + case invalidAuthority = -67824 + case verifyActionFailed = -67825 + case invalidCertAuthority = -67826 + case invaldCRLAuthority = -67827 + case invalidCRLEncoding = -67828 + case invalidCRLType = -67829 + case invalidCRL = -67830 + case invalidFormType = -67831 + case invalidID = -67832 + case invalidIdentifier = -67833 + case invalidIndex = -67834 + case invalidPolicyIdentifiers = -67835 + case invalidTimeString = -67836 + case invalidReason = -67837 + case invalidRequestInputs = -67838 + case invalidResponseVector = -67839 + case invalidStopOnPolicy = -67840 + case invalidTuple = -67841 + case multipleValuesUnsupported = -67842 + case notTrusted = -67843 + case noDefaultAuthority = -67844 + case rejectedForm = -67845 + case requestLost = -67846 + case requestRejected = -67847 + case unsupportedAddressType = -67848 + case unsupportedService = -67849 + case invalidTupleGroup = -67850 + case invalidBaseACLs = -67851 + case invalidTupleCredendtials = -67852 + case invalidEncoding = -67853 + case invalidValidityPeriod = -67854 + case invalidRequestor = -67855 + case requestDescriptor = -67856 + case invalidBundleInfo = -67857 + case invalidCRLIndex = -67858 + case noFieldValues = -67859 + case unsupportedFieldFormat = -67860 + case unsupportedIndexInfo = -67861 + case unsupportedLocality = -67862 + case unsupportedNumAttributes = -67863 + case unsupportedNumIndexes = -67864 + case unsupportedNumRecordTypes = -67865 + case fieldSpecifiedMultiple = -67866 + case incompatibleFieldFormat = -67867 + case invalidParsingModule = -67868 + case databaseLocked = -67869 + case datastoreIsOpen = -67870 + case missingValue = -67871 + case unsupportedQueryLimits = -67872 + case unsupportedNumSelectionPreds = -67873 + case unsupportedOperator = -67874 + case invalidDBLocation = -67875 + case invalidAccessRequest = -67876 + case invalidIndexInfo = -67877 + case invalidNewOwner = -67878 + case invalidModifyMode = -67879 + case missingRequiredExtension = -67880 + case extendedKeyUsageNotCritical = -67881 + case timestampMissing = -67882 + case timestampInvalid = -67883 + case timestampNotTrusted = -67884 + case timestampServiceNotAvailable = -67885 + case timestampBadAlg = -67886 + case timestampBadRequest = -67887 + case timestampBadDataFormat = -67888 + case timestampTimeNotAvailable = -67889 + case timestampUnacceptedPolicy = -67890 + case timestampUnacceptedExtension = -67891 + case timestampAddInfoNotAvailable = -67892 + case timestampSystemFailure = -67893 + case signingTimeMissing = -67894 + case timestampRejection = -67895 + case timestampWaiting = -67896 + case timestampRevocationWarning = -67897 + case timestampRevocationNotification = -67898 + case unexpectedError = -99999 +} + +extension Status: RawRepresentable, CustomStringConvertible { + + public init(status: OSStatus) { + if let mappedStatus = Status(rawValue: status) { + self = mappedStatus + } else { + self = .unexpectedError + } + } + + public var description: String { + switch self { + case .success: + return "No error." + case .unimplemented: + return "Function or operation not implemented." + case .diskFull: + return "The disk is full." + case .io: + return "I/O error (bummers)" + case .opWr: + return "file already open with with write permission" + case .param: + return "One or more parameters passed to a function were not valid." + case .wrPerm: + return "write permissions error" + case .allocate: + return "Failed to allocate memory." + case .userCanceled: + return "User canceled the operation." + case .badReq: + return "Bad parameter or invalid state for operation." + case .internalComponent: + return "" + case .notAvailable: + return "No keychain is available. You may need to restart your computer." + case .readOnly: + return "This keychain cannot be modified." + case .authFailed: + return "The user name or passphrase you entered is not correct." + case .noSuchKeychain: + return "The specified keychain could not be found." + case .invalidKeychain: + return "The specified keychain is not a valid keychain file." + case .duplicateKeychain: + return "A keychain with the same name already exists." + case .duplicateCallback: + return "The specified callback function is already installed." + case .invalidCallback: + return "The specified callback function is not valid." + case .duplicateItem: + return "The specified item already exists in the keychain." + case .itemNotFound: + return "The specified item could not be found in the keychain." + case .bufferTooSmall: + return "There is not enough memory available to use the specified item." + case .dataTooLarge: + return "This item contains information which is too large or in a format that cannot be displayed." + case .noSuchAttr: + return "The specified attribute does not exist." + case .invalidItemRef: + return "The specified item is no longer valid. It may have been deleted from the keychain." + case .invalidSearchRef: + return "Unable to search the current keychain." + case .noSuchClass: + return "The specified item does not appear to be a valid keychain item." + case .noDefaultKeychain: + return "A default keychain could not be found." + case .interactionNotAllowed: + return "User interaction is not allowed." + case .readOnlyAttr: + return "The specified attribute could not be modified." + case .wrongSecVersion: + return "This keychain was created by a different version of the system software and cannot be opened." + case .keySizeNotAllowed: + return "This item specifies a key size which is too large." + case .noStorageModule: + return "A required component (data storage module) could not be loaded. You may need to restart your computer." + case .noCertificateModule: + return "A required component (certificate module) could not be loaded. You may need to restart your computer." + case .noPolicyModule: + return "A required component (policy module) could not be loaded. You may need to restart your computer." + case .interactionRequired: + return "User interaction is required, but is currently not allowed." + case .dataNotAvailable: + return "The contents of this item cannot be retrieved." + case .dataNotModifiable: + return "The contents of this item cannot be modified." + case .createChainFailed: + return "One or more certificates required to validate this certificate cannot be found." + case .invalidPrefsDomain: + return "The specified preferences domain is not valid." + case .inDarkWake: + return "In dark wake, no UI possible" + case .aclNotSimple: + return "The specified access control list is not in standard (simple) form." + case .policyNotFound: + return "The specified policy cannot be found." + case .invalidTrustSetting: + return "The specified trust setting is invalid." + case .noAccessForItem: + return "The specified item has no access control." + case .invalidOwnerEdit: + return "Invalid attempt to change the owner of this item." + case .trustNotAvailable: + return "No trust results are available." + case .unsupportedFormat: + return "Import/Export format unsupported." + case .unknownFormat: + return "Unknown format in import." + case .keyIsSensitive: + return "Key material must be wrapped for export." + case .multiplePrivKeys: + return "An attempt was made to import multiple private keys." + case .passphraseRequired: + return "Passphrase is required for import/export." + case .invalidPasswordRef: + return "The password reference was invalid." + case .invalidTrustSettings: + return "The Trust Settings Record was corrupted." + case .noTrustSettings: + return "No Trust Settings were found." + case .pkcs12VerifyFailure: + return "MAC verification failed during PKCS12 import (wrong password?)" + case .invalidCertificate: + return "This certificate could not be decoded." + case .notSigner: + return "A certificate was not signed by its proposed parent." + case .policyDenied: + return "The certificate chain was not trusted due to a policy not accepting it." + case .invalidKey: + return "The provided key material was not valid." + case .decode: + return "Unable to decode the provided data." + case .`internal`: + return "An internal error occurred in the Security framework." + case .unsupportedAlgorithm: + return "An unsupported algorithm was encountered." + case .unsupportedOperation: + return "The operation you requested is not supported by this key." + case .unsupportedPadding: + return "The padding you requested is not supported." + case .itemInvalidKey: + return "A string key in dictionary is not one of the supported keys." + case .itemInvalidKeyType: + return "A key in a dictionary is neither a CFStringRef nor a CFNumberRef." + case .itemInvalidValue: + return "A value in a dictionary is an invalid (or unsupported) CF type." + case .itemClassMissing: + return "No kSecItemClass key was specified in a dictionary." + case .itemMatchUnsupported: + return "The caller passed one or more kSecMatch keys to a function which does not support matches." + case .useItemListUnsupported: + return "The caller passed in a kSecUseItemList key to a function which does not support it." + case .useKeychainUnsupported: + return "The caller passed in a kSecUseKeychain key to a function which does not support it." + case .useKeychainListUnsupported: + return "The caller passed in a kSecUseKeychainList key to a function which does not support it." + case .returnDataUnsupported: + return "The caller passed in a kSecReturnData key to a function which does not support it." + case .returnAttributesUnsupported: + return "The caller passed in a kSecReturnAttributes key to a function which does not support it." + case .returnRefUnsupported: + return "The caller passed in a kSecReturnRef key to a function which does not support it." + case .returnPersitentRefUnsupported: + return "The caller passed in a kSecReturnPersistentRef key to a function which does not support it." + case .valueRefUnsupported: + return "The caller passed in a kSecValueRef key to a function which does not support it." + case .valuePersistentRefUnsupported: + return "The caller passed in a kSecValuePersistentRef key to a function which does not support it." + case .returnMissingPointer: + return "The caller passed asked for something to be returned but did not pass in a result pointer." + case .matchLimitUnsupported: + return "The caller passed in a kSecMatchLimit key to a call which does not support limits." + case .itemIllegalQuery: + return "The caller passed in a query which contained too many keys." + case .waitForCallback: + return "This operation is incomplete, until the callback is invoked (not an error)." + case .missingEntitlement: + return "Internal error when a required entitlement isn't present, client has neither application-identifier nor keychain-access-groups entitlements." + case .upgradePending: + return "Error returned if keychain database needs a schema migration but the device is locked, clients should wait for a device unlock notification and retry the command." + case .mpSignatureInvalid: + return "Signature invalid on MP message" + case .otrTooOld: + return "Message is too old to use" + case .otrIDTooNew: + return "Key ID is too new to use! Message from the future?" + case .serviceNotAvailable: + return "The required service is not available." + case .insufficientClientID: + return "The client ID is not correct." + case .deviceReset: + return "A device reset has occurred." + case .deviceFailed: + return "A device failure has occurred." + case .appleAddAppACLSubject: + return "Adding an application ACL subject failed." + case .applePublicKeyIncomplete: + return "The public key is incomplete." + case .appleSignatureMismatch: + return "A signature mismatch has occurred." + case .appleInvalidKeyStartDate: + return "The specified key has an invalid start date." + case .appleInvalidKeyEndDate: + return "The specified key has an invalid end date." + case .conversionError: + return "A conversion error has occurred." + case .appleSSLv2Rollback: + return "A SSLv2 rollback error has occurred." + case .quotaExceeded: + return "The quota was exceeded." + case .fileTooBig: + return "The file is too big." + case .invalidDatabaseBlob: + return "The specified database has an invalid blob." + case .invalidKeyBlob: + return "The specified database has an invalid key blob." + case .incompatibleDatabaseBlob: + return "The specified database has an incompatible blob." + case .incompatibleKeyBlob: + return "The specified database has an incompatible key blob." + case .hostNameMismatch: + return "A host name mismatch has occurred." + case .unknownCriticalExtensionFlag: + return "There is an unknown critical extension flag." + case .noBasicConstraints: + return "No basic constraints were found." + case .noBasicConstraintsCA: + return "No basic CA constraints were found." + case .invalidAuthorityKeyID: + return "The authority key ID is not valid." + case .invalidSubjectKeyID: + return "The subject key ID is not valid." + case .invalidKeyUsageForPolicy: + return "The key usage is not valid for the specified policy." + case .invalidExtendedKeyUsage: + return "The extended key usage is not valid." + case .invalidIDLinkage: + return "The ID linkage is not valid." + case .pathLengthConstraintExceeded: + return "The path length constraint was exceeded." + case .invalidRoot: + return "The root or anchor certificate is not valid." + case .crlExpired: + return "The CRL has expired." + case .crlNotValidYet: + return "The CRL is not yet valid." + case .crlNotFound: + return "The CRL was not found." + case .crlServerDown: + return "The CRL server is down." + case .crlBadURI: + return "The CRL has a bad Uniform Resource Identifier." + case .unknownCertExtension: + return "An unknown certificate extension was encountered." + case .unknownCRLExtension: + return "An unknown CRL extension was encountered." + case .crlNotTrusted: + return "The CRL is not trusted." + case .crlPolicyFailed: + return "The CRL policy failed." + case .idpFailure: + return "The issuing distribution point was not valid." + case .smimeEmailAddressesNotFound: + return "An email address mismatch was encountered." + case .smimeBadExtendedKeyUsage: + return "The appropriate extended key usage for SMIME was not found." + case .smimeBadKeyUsage: + return "The key usage is not compatible with SMIME." + case .smimeKeyUsageNotCritical: + return "The key usage extension is not marked as critical." + case .smimeNoEmailAddress: + return "No email address was found in the certificate." + case .smimeSubjAltNameNotCritical: + return "The subject alternative name extension is not marked as critical." + case .sslBadExtendedKeyUsage: + return "The appropriate extended key usage for SSL was not found." + case .ocspBadResponse: + return "The OCSP response was incorrect or could not be parsed." + case .ocspBadRequest: + return "The OCSP request was incorrect or could not be parsed." + case .ocspUnavailable: + return "OCSP service is unavailable." + case .ocspStatusUnrecognized: + return "The OCSP server did not recognize this certificate." + case .endOfData: + return "An end-of-data was detected." + case .incompleteCertRevocationCheck: + return "An incomplete certificate revocation check occurred." + case .networkFailure: + return "A network failure occurred." + case .ocspNotTrustedToAnchor: + return "The OCSP response was not trusted to a root or anchor certificate." + case .recordModified: + return "The record was modified." + case .ocspSignatureError: + return "The OCSP response had an invalid signature." + case .ocspNoSigner: + return "The OCSP response had no signer." + case .ocspResponderMalformedReq: + return "The OCSP responder was given a malformed request." + case .ocspResponderInternalError: + return "The OCSP responder encountered an internal error." + case .ocspResponderTryLater: + return "The OCSP responder is busy, try again later." + case .ocspResponderSignatureRequired: + return "The OCSP responder requires a signature." + case .ocspResponderUnauthorized: + return "The OCSP responder rejected this request as unauthorized." + case .ocspResponseNonceMismatch: + return "The OCSP response nonce did not match the request." + case .codeSigningBadCertChainLength: + return "Code signing encountered an incorrect certificate chain length." + case .codeSigningNoBasicConstraints: + return "Code signing found no basic constraints." + case .codeSigningBadPathLengthConstraint: + return "Code signing encountered an incorrect path length constraint." + case .codeSigningNoExtendedKeyUsage: + return "Code signing found no extended key usage." + case .codeSigningDevelopment: + return "Code signing indicated use of a development-only certificate." + case .resourceSignBadCertChainLength: + return "Resource signing has encountered an incorrect certificate chain length." + case .resourceSignBadExtKeyUsage: + return "Resource signing has encountered an error in the extended key usage." + case .trustSettingDeny: + return "The trust setting for this policy was set to Deny." + case .invalidSubjectName: + return "An invalid certificate subject name was encountered." + case .unknownQualifiedCertStatement: + return "An unknown qualified certificate statement was encountered." + case .mobileMeRequestQueued: + return "The MobileMe request will be sent during the next connection." + case .mobileMeRequestRedirected: + return "The MobileMe request was redirected." + case .mobileMeServerError: + return "A MobileMe server error occurred." + case .mobileMeServerNotAvailable: + return "The MobileMe server is not available." + case .mobileMeServerAlreadyExists: + return "The MobileMe server reported that the item already exists." + case .mobileMeServerServiceErr: + return "A MobileMe service error has occurred." + case .mobileMeRequestAlreadyPending: + return "A MobileMe request is already pending." + case .mobileMeNoRequestPending: + return "MobileMe has no request pending." + case .mobileMeCSRVerifyFailure: + return "A MobileMe CSR verification failure has occurred." + case .mobileMeFailedConsistencyCheck: + return "MobileMe has found a failed consistency check." + case .notInitialized: + return "A function was called without initializing CSSM." + case .invalidHandleUsage: + return "The CSSM handle does not match with the service type." + case .pvcReferentNotFound: + return "A reference to the calling module was not found in the list of authorized callers." + case .functionIntegrityFail: + return "A function address was not within the verified module." + case .internalError: + return "An internal error has occurred." + case .memoryError: + return "A memory error has occurred." + case .invalidData: + return "Invalid data was encountered." + case .mdsError: + return "A Module Directory Service error has occurred." + case .invalidPointer: + return "An invalid pointer was encountered." + case .selfCheckFailed: + return "Self-check has failed." + case .functionFailed: + return "A function has failed." + case .moduleManifestVerifyFailed: + return "A module manifest verification failure has occurred." + case .invalidGUID: + return "An invalid GUID was encountered." + case .invalidHandle: + return "An invalid handle was encountered." + case .invalidDBList: + return "An invalid DB list was encountered." + case .invalidPassthroughID: + return "An invalid passthrough ID was encountered." + case .invalidNetworkAddress: + return "An invalid network address was encountered." + case .crlAlreadySigned: + return "The certificate revocation list is already signed." + case .invalidNumberOfFields: + return "An invalid number of fields were encountered." + case .verificationFailure: + return "A verification failure occurred." + case .unknownTag: + return "An unknown tag was encountered." + case .invalidSignature: + return "An invalid signature was encountered." + case .invalidName: + return "An invalid name was encountered." + case .invalidCertificateRef: + return "An invalid certificate reference was encountered." + case .invalidCertificateGroup: + return "An invalid certificate group was encountered." + case .tagNotFound: + return "The specified tag was not found." + case .invalidQuery: + return "The specified query was not valid." + case .invalidValue: + return "An invalid value was detected." + case .callbackFailed: + return "A callback has failed." + case .aclDeleteFailed: + return "An ACL delete operation has failed." + case .aclReplaceFailed: + return "An ACL replace operation has failed." + case .aclAddFailed: + return "An ACL add operation has failed." + case .aclChangeFailed: + return "An ACL change operation has failed." + case .invalidAccessCredentials: + return "Invalid access credentials were encountered." + case .invalidRecord: + return "An invalid record was encountered." + case .invalidACL: + return "An invalid ACL was encountered." + case .invalidSampleValue: + return "An invalid sample value was encountered." + case .incompatibleVersion: + return "An incompatible version was encountered." + case .privilegeNotGranted: + return "The privilege was not granted." + case .invalidScope: + return "An invalid scope was encountered." + case .pvcAlreadyConfigured: + return "The PVC is already configured." + case .invalidPVC: + return "An invalid PVC was encountered." + case .emmLoadFailed: + return "The EMM load has failed." + case .emmUnloadFailed: + return "The EMM unload has failed." + case .addinLoadFailed: + return "The add-in load operation has failed." + case .invalidKeyRef: + return "An invalid key was encountered." + case .invalidKeyHierarchy: + return "An invalid key hierarchy was encountered." + case .addinUnloadFailed: + return "The add-in unload operation has failed." + case .libraryReferenceNotFound: + return "A library reference was not found." + case .invalidAddinFunctionTable: + return "An invalid add-in function table was encountered." + case .invalidServiceMask: + return "An invalid service mask was encountered." + case .moduleNotLoaded: + return "A module was not loaded." + case .invalidSubServiceID: + return "An invalid subservice ID was encountered." + case .attributeNotInContext: + return "An attribute was not in the context." + case .moduleManagerInitializeFailed: + return "A module failed to initialize." + case .moduleManagerNotFound: + return "A module was not found." + case .eventNotificationCallbackNotFound: + return "An event notification callback was not found." + case .inputLengthError: + return "An input length error was encountered." + case .outputLengthError: + return "An output length error was encountered." + case .privilegeNotSupported: + return "The privilege is not supported." + case .deviceError: + return "A device error was encountered." + case .attachHandleBusy: + return "The CSP handle was busy." + case .notLoggedIn: + return "You are not logged in." + case .algorithmMismatch: + return "An algorithm mismatch was encountered." + case .keyUsageIncorrect: + return "The key usage is incorrect." + case .keyBlobTypeIncorrect: + return "The key blob type is incorrect." + case .keyHeaderInconsistent: + return "The key header is inconsistent." + case .unsupportedKeyFormat: + return "The key header format is not supported." + case .unsupportedKeySize: + return "The key size is not supported." + case .invalidKeyUsageMask: + return "The key usage mask is not valid." + case .unsupportedKeyUsageMask: + return "The key usage mask is not supported." + case .invalidKeyAttributeMask: + return "The key attribute mask is not valid." + case .unsupportedKeyAttributeMask: + return "The key attribute mask is not supported." + case .invalidKeyLabel: + return "The key label is not valid." + case .unsupportedKeyLabel: + return "The key label is not supported." + case .invalidKeyFormat: + return "The key format is not valid." + case .unsupportedVectorOfBuffers: + return "The vector of buffers is not supported." + case .invalidInputVector: + return "The input vector is not valid." + case .invalidOutputVector: + return "The output vector is not valid." + case .invalidContext: + return "An invalid context was encountered." + case .invalidAlgorithm: + return "An invalid algorithm was encountered." + case .invalidAttributeKey: + return "A key attribute was not valid." + case .missingAttributeKey: + return "A key attribute was missing." + case .invalidAttributeInitVector: + return "An init vector attribute was not valid." + case .missingAttributeInitVector: + return "An init vector attribute was missing." + case .invalidAttributeSalt: + return "A salt attribute was not valid." + case .missingAttributeSalt: + return "A salt attribute was missing." + case .invalidAttributePadding: + return "A padding attribute was not valid." + case .missingAttributePadding: + return "A padding attribute was missing." + case .invalidAttributeRandom: + return "A random number attribute was not valid." + case .missingAttributeRandom: + return "A random number attribute was missing." + case .invalidAttributeSeed: + return "A seed attribute was not valid." + case .missingAttributeSeed: + return "A seed attribute was missing." + case .invalidAttributePassphrase: + return "A passphrase attribute was not valid." + case .missingAttributePassphrase: + return "A passphrase attribute was missing." + case .invalidAttributeKeyLength: + return "A key length attribute was not valid." + case .missingAttributeKeyLength: + return "A key length attribute was missing." + case .invalidAttributeBlockSize: + return "A block size attribute was not valid." + case .missingAttributeBlockSize: + return "A block size attribute was missing." + case .invalidAttributeOutputSize: + return "An output size attribute was not valid." + case .missingAttributeOutputSize: + return "An output size attribute was missing." + case .invalidAttributeRounds: + return "The number of rounds attribute was not valid." + case .missingAttributeRounds: + return "The number of rounds attribute was missing." + case .invalidAlgorithmParms: + return "An algorithm parameters attribute was not valid." + case .missingAlgorithmParms: + return "An algorithm parameters attribute was missing." + case .invalidAttributeLabel: + return "A label attribute was not valid." + case .missingAttributeLabel: + return "A label attribute was missing." + case .invalidAttributeKeyType: + return "A key type attribute was not valid." + case .missingAttributeKeyType: + return "A key type attribute was missing." + case .invalidAttributeMode: + return "A mode attribute was not valid." + case .missingAttributeMode: + return "A mode attribute was missing." + case .invalidAttributeEffectiveBits: + return "An effective bits attribute was not valid." + case .missingAttributeEffectiveBits: + return "An effective bits attribute was missing." + case .invalidAttributeStartDate: + return "A start date attribute was not valid." + case .missingAttributeStartDate: + return "A start date attribute was missing." + case .invalidAttributeEndDate: + return "An end date attribute was not valid." + case .missingAttributeEndDate: + return "An end date attribute was missing." + case .invalidAttributeVersion: + return "A version attribute was not valid." + case .missingAttributeVersion: + return "A version attribute was missing." + case .invalidAttributePrime: + return "A prime attribute was not valid." + case .missingAttributePrime: + return "A prime attribute was missing." + case .invalidAttributeBase: + return "A base attribute was not valid." + case .missingAttributeBase: + return "A base attribute was missing." + case .invalidAttributeSubprime: + return "A subprime attribute was not valid." + case .missingAttributeSubprime: + return "A subprime attribute was missing." + case .invalidAttributeIterationCount: + return "An iteration count attribute was not valid." + case .missingAttributeIterationCount: + return "An iteration count attribute was missing." + case .invalidAttributeDLDBHandle: + return "A database handle attribute was not valid." + case .missingAttributeDLDBHandle: + return "A database handle attribute was missing." + case .invalidAttributeAccessCredentials: + return "An access credentials attribute was not valid." + case .missingAttributeAccessCredentials: + return "An access credentials attribute was missing." + case .invalidAttributePublicKeyFormat: + return "A public key format attribute was not valid." + case .missingAttributePublicKeyFormat: + return "A public key format attribute was missing." + case .invalidAttributePrivateKeyFormat: + return "A private key format attribute was not valid." + case .missingAttributePrivateKeyFormat: + return "A private key format attribute was missing." + case .invalidAttributeSymmetricKeyFormat: + return "A symmetric key format attribute was not valid." + case .missingAttributeSymmetricKeyFormat: + return "A symmetric key format attribute was missing." + case .invalidAttributeWrappedKeyFormat: + return "A wrapped key format attribute was not valid." + case .missingAttributeWrappedKeyFormat: + return "A wrapped key format attribute was missing." + case .stagedOperationInProgress: + return "A staged operation is in progress." + case .stagedOperationNotStarted: + return "A staged operation was not started." + case .verifyFailed: + return "A cryptographic verification failure has occurred." + case .querySizeUnknown: + return "The query size is unknown." + case .blockSizeMismatch: + return "A block size mismatch occurred." + case .publicKeyInconsistent: + return "The public key was inconsistent." + case .deviceVerifyFailed: + return "A device verification failure has occurred." + case .invalidLoginName: + return "An invalid login name was detected." + case .alreadyLoggedIn: + return "The user is already logged in." + case .invalidDigestAlgorithm: + return "An invalid digest algorithm was detected." + case .invalidCRLGroup: + return "An invalid CRL group was detected." + case .certificateCannotOperate: + return "The certificate cannot operate." + case .certificateExpired: + return "An expired certificate was detected." + case .certificateNotValidYet: + return "The certificate is not yet valid." + case .certificateRevoked: + return "The certificate was revoked." + case .certificateSuspended: + return "The certificate was suspended." + case .insufficientCredentials: + return "Insufficient credentials were detected." + case .invalidAction: + return "The action was not valid." + case .invalidAuthority: + return "The authority was not valid." + case .verifyActionFailed: + return "A verify action has failed." + case .invalidCertAuthority: + return "The certificate authority was not valid." + case .invaldCRLAuthority: + return "The CRL authority was not valid." + case .invalidCRLEncoding: + return "The CRL encoding was not valid." + case .invalidCRLType: + return "The CRL type was not valid." + case .invalidCRL: + return "The CRL was not valid." + case .invalidFormType: + return "The form type was not valid." + case .invalidID: + return "The ID was not valid." + case .invalidIdentifier: + return "The identifier was not valid." + case .invalidIndex: + return "The index was not valid." + case .invalidPolicyIdentifiers: + return "The policy identifiers are not valid." + case .invalidTimeString: + return "The time specified was not valid." + case .invalidReason: + return "The trust policy reason was not valid." + case .invalidRequestInputs: + return "The request inputs are not valid." + case .invalidResponseVector: + return "The response vector was not valid." + case .invalidStopOnPolicy: + return "The stop-on policy was not valid." + case .invalidTuple: + return "The tuple was not valid." + case .multipleValuesUnsupported: + return "Multiple values are not supported." + case .notTrusted: + return "The trust policy was not trusted." + case .noDefaultAuthority: + return "No default authority was detected." + case .rejectedForm: + return "The trust policy had a rejected form." + case .requestLost: + return "The request was lost." + case .requestRejected: + return "The request was rejected." + case .unsupportedAddressType: + return "The address type is not supported." + case .unsupportedService: + return "The service is not supported." + case .invalidTupleGroup: + return "The tuple group was not valid." + case .invalidBaseACLs: + return "The base ACLs are not valid." + case .invalidTupleCredendtials: + return "The tuple credentials are not valid." + case .invalidEncoding: + return "The encoding was not valid." + case .invalidValidityPeriod: + return "The validity period was not valid." + case .invalidRequestor: + return "The requestor was not valid." + case .requestDescriptor: + return "The request descriptor was not valid." + case .invalidBundleInfo: + return "The bundle information was not valid." + case .invalidCRLIndex: + return "The CRL index was not valid." + case .noFieldValues: + return "No field values were detected." + case .unsupportedFieldFormat: + return "The field format is not supported." + case .unsupportedIndexInfo: + return "The index information is not supported." + case .unsupportedLocality: + return "The locality is not supported." + case .unsupportedNumAttributes: + return "The number of attributes is not supported." + case .unsupportedNumIndexes: + return "The number of indexes is not supported." + case .unsupportedNumRecordTypes: + return "The number of record types is not supported." + case .fieldSpecifiedMultiple: + return "Too many fields were specified." + case .incompatibleFieldFormat: + return "The field format was incompatible." + case .invalidParsingModule: + return "The parsing module was not valid." + case .databaseLocked: + return "The database is locked." + case .datastoreIsOpen: + return "The data store is open." + case .missingValue: + return "A missing value was detected." + case .unsupportedQueryLimits: + return "The query limits are not supported." + case .unsupportedNumSelectionPreds: + return "The number of selection predicates is not supported." + case .unsupportedOperator: + return "The operator is not supported." + case .invalidDBLocation: + return "The database location is not valid." + case .invalidAccessRequest: + return "The access request is not valid." + case .invalidIndexInfo: + return "The index information is not valid." + case .invalidNewOwner: + return "The new owner is not valid." + case .invalidModifyMode: + return "The modify mode is not valid." + case .missingRequiredExtension: + return "A required certificate extension is missing." + case .extendedKeyUsageNotCritical: + return "The extended key usage extension was not marked critical." + case .timestampMissing: + return "A timestamp was expected but was not found." + case .timestampInvalid: + return "The timestamp was not valid." + case .timestampNotTrusted: + return "The timestamp was not trusted." + case .timestampServiceNotAvailable: + return "The timestamp service is not available." + case .timestampBadAlg: + return "An unrecognized or unsupported Algorithm Identifier in timestamp." + case .timestampBadRequest: + return "The timestamp transaction is not permitted or supported." + case .timestampBadDataFormat: + return "The timestamp data submitted has the wrong format." + case .timestampTimeNotAvailable: + return "The time source for the Timestamp Authority is not available." + case .timestampUnacceptedPolicy: + return "The requested policy is not supported by the Timestamp Authority." + case .timestampUnacceptedExtension: + return "The requested extension is not supported by the Timestamp Authority." + case .timestampAddInfoNotAvailable: + return "The additional information requested is not available." + case .timestampSystemFailure: + return "The timestamp request cannot be handled due to system failure." + case .signingTimeMissing: + return "A signing time was expected but was not found." + case .timestampRejection: + return "A timestamp transaction was rejected." + case .timestampWaiting: + return "A timestamp transaction is waiting." + case .timestampRevocationWarning: + return "A timestamp authority revocation warning was issued." + case .timestampRevocationNotification: + return "A timestamp authority revocation notification was issued." + case .unexpectedError: + return "Unexpected error has occurred." + } + } +} + +extension Status: CustomNSError { + public static let errorDomain = KeychainAccessErrorDomain + + public var errorCode: Int { + return Int(rawValue) + } + + public var errorUserInfo: [String : Any] { + return [NSLocalizedDescriptionKey: description] + } +} diff --git a/Pods/KeychainAccess/README.md b/Pods/KeychainAccess/README.md new file mode 100644 index 0000000..838ef2c --- /dev/null +++ b/Pods/KeychainAccess/README.md @@ -0,0 +1,602 @@ +# KeychainAccess +[![CI Status](http://img.shields.io/travis/kishikawakatsumi/KeychainAccess.svg)](https://travis-ci.org/kishikawakatsumi/KeychainAccess) +[![codecov](https://codecov.io/gh/kishikawakatsumi/KeychainAccess/branch/master/graph/badge.svg)](https://codecov.io/gh/kishikawakatsumi/KeychainAccess) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) +[![Version](https://img.shields.io/cocoapods/v/KeychainAccess.svg)](http://cocoadocs.org/docsets/KeychainAccess) +[![Platform](https://img.shields.io/cocoapods/p/KeychainAccess.svg)](http://cocoadocs.org/docsets/KeychainAccess) +[![Swift 3.x](https://img.shields.io/badge/Swift-3.x-orange.svg?style=flat)](https://swift.org/) +[![Swift 4.0](https://img.shields.io/badge/Swift-4.0-orange.svg?style=flat)](https://swift.org/) +[![Swift 4.1](https://img.shields.io/badge/Swift-4.1-orange.svg?style=flat)](https://swift.org/) +[![Swift 4.2](https://img.shields.io/badge/Swift-4.2-orange.svg?style=flat)](https://swift.org/) + +KeychainAccess is a simple Swift wrapper for Keychain that works on iOS and OS X. Makes using Keychain APIs extremely easy and much more palatable to use in Swift. + + + + + +## :bulb: Features + +- Simple interface +- Support access group +- [Support accessibility](#accessibility) +- [Support iCloud sharing](#icloud_sharing) +- **[Support TouchID and Keychain integration (iOS 8+)](#touch_id_integration)** +- **[Support Shared Web Credentials (iOS 8+)](#shared_web_credentials)** +- [Works on both iOS & OS X](#requirements) +- [watchOS and tvOS are supported](#requirements) +- **[Swift 4 & Swift 3 compatible](#requirements)** + +## :book: Usage + +##### :eyes: See also: +- [:link: iOS Example Project](https://github.com/kishikawakatsumi/KeychainAccess/tree/master/Examples/Example-iOS) + +### :key: Basics + +#### Saving Application Password + +```swift +let keychain = Keychain(service: "com.example.github-token") +keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef" +``` + +#### Saving Internet Password + +```swift +let keychain = Keychain(server: "https://github.com", protocolType: .https) +keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef" +``` + +### :key: Instantiation + +#### Create Keychain for Application Password + +```swift +let keychain = Keychain(service: "com.example.github-token") +``` + +```swift +let keychain = Keychain(service: "com.example.github-token", accessGroup: "12ABCD3E4F.shared") +``` + +#### Create Keychain for Internet Password + +```swift +let keychain = Keychain(server: "https://github.com", protocolType: .https) +``` + +```swift +let keychain = Keychain(server: "https://github.com", protocolType: .https, authenticationType: .htmlForm) +``` + +### :key: Adding an item + +#### subscripting + +##### for String + +```swift +keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef" +``` + +```swift +keychain[string: "kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef" +``` + +##### for NSData + +```swift +keychain[data: "secret"] = NSData(contentsOfFile: "secret.bin") +``` + +#### set method + +```swift +keychain.set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi") +``` + +#### error handling + +```swift +do { + try keychain.set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi") +} +catch let error { + print(error) +} +``` + +### :key: Obtaining an item + +#### subscripting + +##### for String (If the value is NSData, attempt to convert to String) + +```swift +let token = keychain["kishikawakatsumi"] +``` + +```swift +let token = keychain[string: "kishikawakatsumi"] +``` + +##### for NSData + +```swift +let secretData = keychain[data: "secret"] +``` + +#### get methods + +##### as String + +```swift +let token = try? keychain.get("kishikawakatsumi") +``` + +```swift +let token = try? keychain.getString("kishikawakatsumi") +``` + +##### as NSData + +```swift +let data = try? keychain.getData("kishikawakatsumi") +``` + +### :key: Removing an item + +#### subscripting + +```swift +keychain["kishikawakatsumi"] = nil +``` + +#### remove method + +```swift +do { + try keychain.remove("kishikawakatsumi") +} catch let error { + print("error: \(error)") +} +``` + +### :key: Set Label and Comment + +```swift +let keychain = Keychain(server: "https://github.com", protocolType: .https) +do { + try keychain + .label("github.com (kishikawakatsumi)") + .comment("github access token") + .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi") +} catch let error { + print("error: \(error)") +} +``` + +### :key: Obtaining Other Attributes + +#### PersistentRef + +```swift +let keychain = Keychain() +let persistentRef = keychain[attributes: "kishikawakatsumi"].persistentRef +... +``` + +#### Creation Date + +```swift +let keychain = Keychain() +let creationDate = keychain[attributes: "kishikawakatsumi"].creationDate +... +``` + +#### All Attributes + +```swift +let keychain = Keychain() +do { + let attributes = try keychain.get("kishikawakatsumi") { $0 } + print(attributes.comment) + print(attributes.label) + print(attributes.creator) + ... +} catch let error { + print("error: \(error)") +} +``` + +##### subscripting + +```swift +let keychain = Keychain() +let attributes = keychain[attributes: "kishikawakatsumi"] +print(attributes.comment) +print(attributes.label) +print(attributes.creator) +``` + +### :key: Configuration (Accessibility, Sharing, iCloud Sync) + +**Provides fluent interfaces** + +```swift +let keychain = Keychain(service: "com.example.github-token") + .label("github.com (kishikawakatsumi)") + .synchronizable(true) + .accessibility(.afterFirstUnlock) +``` + +#### Accessibility + +##### Default accessibility matches background application (=kSecAttrAccessibleAfterFirstUnlock) + +```swift +let keychain = Keychain(service: "com.example.github-token") +``` + +##### For background application + +###### Creating instance + +```swift +let keychain = Keychain(service: "com.example.github-token") + .accessibility(.afterFirstUnlock) + +keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef" +``` + +###### One-shot + +```swift +let keychain = Keychain(service: "com.example.github-token") + +do { + try keychain + .accessibility(.afterFirstUnlock) + .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi") +} catch let error { + print("error: \(error)") +} +``` + +##### For foreground application + +###### Creating instance + +```swift +let keychain = Keychain(service: "com.example.github-token") + .accessibility(.whenUnlocked) + +keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef" +``` + +###### One-shot + +```swift +let keychain = Keychain(service: "com.example.github-token") + +do { + try keychain + .accessibility(.whenUnlocked) + .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi") +} catch let error { + print("error: \(error)") +} +``` + +#### :couple: Sharing Keychain items + +```swift +let keychain = Keychain(service: "com.example.github-token", accessGroup: "12ABCD3E4F.shared") +``` + +#### :arrows_counterclockwise: Synchronizing Keychain items with iCloud + +###### Creating instance + +```swift +let keychain = Keychain(service: "com.example.github-token") + .synchronizable(true) + +keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef" +``` + +###### One-shot + +```swift +let keychain = Keychain(service: "com.example.github-token") + +do { + try keychain + .synchronizable(true) + .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi") +} catch let error { + print("error: \(error)") +} +``` + +### :fu: Touch ID integration + +**Any Operation that require authentication must be run in the background thread.** +**If you run in the main thread, UI thread will lock for the system to try to display the authentication dialog.** + +#### :closed_lock_with_key: Adding a Touch ID protected item + +If you want to store the Touch ID protected Keychain item, specify `accessibility` and `authenticationPolicy` attributes. + +```swift +let keychain = Keychain(service: "com.example.github-token") + +DispatchQueue.global().async { + do { + // Should be the secret invalidated when passcode is removed? If not then use `.WhenUnlocked` + try keychain + .accessibility(.whenPasscodeSetThisDeviceOnly, authenticationPolicy: .userPresence) + .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi") + } catch let error { + // Error handling if needed... + } +} +``` + +#### :closed_lock_with_key: Updating a Touch ID protected item + +The same way as when adding. + +**Do not run in the main thread if there is a possibility that the item you are trying to add already exists, and protected.** +**Because updating protected items requires authentication.** + +Additionally, you want to show custom authentication prompt message when updating, specify an `authenticationPrompt` attribute. +If the item not protected, the `authenticationPrompt` parameter just be ignored. + +```swift +let keychain = Keychain(service: "com.example.github-token") + +DispatchQueue.global().async { + do { + // Should be the secret invalidated when passcode is removed? If not then use `.WhenUnlocked` + try keychain + .accessibility(.whenPasscodeSetThisDeviceOnly, authenticationPolicy: .userPresence) + .authenticationPrompt("Authenticate to update your access token") + .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi") + } catch let error { + // Error handling if needed... + } +} +``` + +#### :closed_lock_with_key: Obtaining a Touch ID protected item + +The same way as when you get a normal item. It will be displayed automatically Touch ID or passcode authentication If the item you try to get is protected. +If you want to show custom authentication prompt message, specify an `authenticationPrompt` attribute. +If the item not protected, the `authenticationPrompt` parameter just be ignored. + +```swift +let keychain = Keychain(service: "com.example.github-token") + +DispatchQueue.global().async { + do { + let password = try keychain + .authenticationPrompt("Authenticate to login to server") + .get("kishikawakatsumi") + + print("password: \(password)") + } catch let error { + // Error handling if needed... + } +} +``` + +#### :closed_lock_with_key: Removing a Touch ID protected item + +The same way as when you remove a normal item. +There is no way to show Touch ID or passcode authentication when removing Keychain items. + +```swift +let keychain = Keychain(service: "com.example.github-token") + +do { + try keychain.remove("kishikawakatsumi") +} catch let error { + // Error handling if needed... +} +``` + +### :key: Shared Web Credentials + +> Shared web credentials is a programming interface that enables native iOS apps to share credentials with their website counterparts. For example, a user may log in to a website in Safari, entering a user name and password, and save those credentials using the iCloud Keychain. Later, the user may run a native app from the same developer, and instead of the app requiring the user to reenter a user name and password, shared web credentials gives it access to the credentials that were entered earlier in Safari. The user can also create new accounts, update passwords, or delete her account from within the app. These changes are then saved and used by Safari. + + + +```swift +let keychain = Keychain(server: "https://www.kishikawakatsumi.com", protocolType: .HTTPS) + +let username = "kishikawakatsumi@mac.com" + +// First, check the credential in the app's Keychain +if let password = try? keychain.get(username) { + // If found password in the Keychain, + // then log into the server +} else { + // If not found password in the Keychain, + // try to read from Shared Web Credentials + keychain.getSharedPassword(username) { (password, error) -> () in + if password != nil { + // If found password in the Shared Web Credentials, + // then log into the server + // and save the password to the Keychain + + keychain[username] = password + } else { + // If not found password either in the Keychain also Shared Web Credentials, + // prompt for username and password + + // Log into server + + // If the login is successful, + // save the credentials to both the Keychain and the Shared Web Credentials. + + keychain[username] = inputPassword + keychain.setSharedPassword(inputPassword, account: username) + } + } +} +``` + +#### Request all associated domain's credentials + +```swift +Keychain.requestSharedWebCredential { (credentials, error) -> () in + +} +``` + +#### Generate strong random password + +Generate strong random password that is in the same format used by Safari autofill (xxx-xxx-xxx-xxx). + +```swift +let password = Keychain.generatePassword() // => Nhu-GKm-s3n-pMx +``` + +#### How to set up Shared Web Credentials + +> 1. Add a com.apple.developer.associated-domains entitlement to your app. This entitlement must include all the domains with which you want to share credentials. + +> 2. Add an apple-app-site-association file to your website. This file must include application identifiers for all the apps with which the site wants to share credentials, and it must be properly signed. + +> 3. When the app is installed, the system downloads and verifies the site association file for each of its associated domains. If the verification is successful, the app is associated with the domain. + +**More details:** + + +### :key: Debugging + +#### Display all stored items if print keychain object + +```swift +let keychain = Keychain(server: "https://github.com", protocolType: .https) +print("\(keychain)") +``` + +``` +=> +[ + [authenticationType: default, key: kishikawakatsumi, server: github.com, class: internetPassword, protocol: https] + [authenticationType: default, key: hirohamada, server: github.com, class: internetPassword, protocol: https] + [authenticationType: default, key: honeylemon, server: github.com, class: internetPassword, protocol: https] +] +``` + +#### Obtaining all stored keys + +```swift +let keychain = Keychain(server: "https://github.com", protocolType: .https) + +let keys = keychain.allKeys() +for key in keys { + print("key: \(key)") +} +``` + +``` +=> +key: kishikawakatsumi +key: hirohamada +key: honeylemon +``` + +#### Obtaining all stored items + +```swift +let keychain = Keychain(server: "https://github.com", protocolType: .https) + +let items = keychain.allItems() +for item in items { + print("item: \(item)") +} +``` + +``` +=> +item: [authenticationType: Default, key: kishikawakatsumi, server: github.com, class: InternetPassword, protocol: https] +item: [authenticationType: Default, key: hirohamada, server: github.com, class: InternetPassword, protocol: https] +item: [authenticationType: Default, key: honeylemon, server: github.com, class: InternetPassword, protocol: https] +``` + +## Requirements + +| | OS | Swift | +|------------|----------------------------------------|---------------| +| **v1.1.x** | iOS 7+, OSX 10.9+ | 1.1 | +| **v1.2.x** | iOS 7+, OSX 10.9+ | 1.2 | +| **v2.0.x** | iOS 7+, OSX 10.9+, watchOS 2+ | 2.0 | +| **v2.1.x** | iOS 7+, OSX 10.9+, watchOS 2+ | 2.0 | +| **v2.2.x** | iOS 8+, OSX 10.9+, watchOS 2+, tvOS 9+ | 2.0, 2.1 | +| **v2.3.x** | iOS 8+, OSX 10.9+, watchOS 2+, tvOS 9+ | 2.0, 2.1, 2.2 | +| **v2.4.x** | iOS 8+, OSX 10.9+, watchOS 2+, tvOS 9+ | 2.2, 2.3 | +| **v3.0.x** | iOS 8+, OSX 10.9+, watchOS 2+, tvOS 9+ | 3.x | +| **v3.1.x** | iOS 8+, OSX 10.9+, watchOS 2+, tvOS 9+ | 4.0, 4.1, 4.2 | + +## Installation + +### CocoaPods + +KeychainAccess is available through [CocoaPods](http://cocoapods.org). To install +it, simply add the following lines to your Podfile: + +```ruby +use_frameworks! +pod 'KeychainAccess' +``` + +### Carthage + +KeychainAccess is available through [Carthage](https://github.com/Carthage/Carthage). To install +it, simply add the following line to your Cartfile: + +`github "kishikawakatsumi/KeychainAccess"` + +### Swift Package Manager + +KeychainAccess is also available through [Swift Package Manager](https://github.com/apple/swift-package-manager/). +First, create `Package.swift` that its package declaration includes: + +```swift +import PackageDescription + +let package = Package( + dependencies: [ + .Package(url: "https://github.com/kishikawakatsumi/KeychainAccess.git", majorVersion: 2) + ] +) +``` + +Then, type + +```shell +$ swift build +``` + +### To manually add to your project + +1. Add `Lib/KeychainAccess.xcodeproj` to your project +2. Link `KeychainAccess.framework` with your target +3. Add `Copy Files Build Phase` to include the framework to your application bundle + +_See [iOS Example Project](https://github.com/kishikawakatsumi/KeychainAccess/tree/master/Examples/Example-iOS) as reference._ + + + +## Author + +kishikawa katsumi, kishikawakatsumi@mac.com + +## License + +KeychainAccess is available under the MIT license. See the LICENSE file for more info. diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock index 5e4b8be..843b910 100644 --- a/Pods/Manifest.lock +++ b/Pods/Manifest.lock @@ -1,12 +1,20 @@ PODS: - CryptoSwift (0.8.1) + - KeychainAccess (3.1.2) DEPENDENCIES: - CryptoSwift + - KeychainAccess + +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - CryptoSwift + - KeychainAccess SPEC CHECKSUMS: CryptoSwift: 4b07d5b508c1eb67bfa314a727b705f8048a85de + KeychainAccess: b3816fddcf28aa29d94b10ec305cd52be14c472b -PODFILE CHECKSUM: bbf4ad9f3f2f1429ecda282ecb446c084363a23f +PODFILE CHECKSUM: 2ccd80ba9984103c7eb7f1175a88d0a90df6c731 -COCOAPODS: 1.3.1 +COCOAPODS: 1.5.3 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index 8731b30..a001d87 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -7,199 +7,262 @@ objects = { /* Begin PBXBuildFile section */ - 04ED4CBE1683A039945AE21E71657DCE /* SHA1.swift in Sources */ = {isa = PBXBuildFile; fileRef = E923A37930CBC57D57B8A58D34037E06 /* SHA1.swift */; }; - 08C450BB03BE7BFD888431D1751132F8 /* RandomAccessBlockModeWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 259F606BDF24A4DDF819F79A4355CE83 /* RandomAccessBlockModeWorker.swift */; }; - 152BA68678A9161227766CE6A75C19D4 /* NoPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17EB19E1EF889F2602A6CD4BFA3B9610 /* NoPadding.swift */; }; - 19F209E95649F61A5101303CA297098B /* UInt8+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F9E69F3EC6CC5A1B9811A830EDA7FB /* UInt8+Extension.swift */; }; - 1BCBD814F3A819CFEDD5B621CD6BC6E0 /* Array+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20983313641ED544FC46B0316BF79926 /* Array+Foundation.swift */; }; - 1C9A485DA2FE04B657D7E3D8D0FF17AB /* Digest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A313DC180F5A42AFDCF5F4D9E6B0E3E /* Digest.swift */; }; - 1D0578185B1E764BC61EC316C3D29B02 /* Utils+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9FEC5C85271D8F16DFD9D29CD4175FB /* Utils+Foundation.swift */; }; - 32508A477EB8DE4F4EA066315511C4EF /* Authenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04EFD937AD6D622C4D5016DC92956436 /* Authenticator.swift */; }; - 338E92A59022E6035872D94CB3AA57BF /* Array+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E483B3851B6079DF39ABBF182139303 /* Array+Extensions.swift */; }; - 35C90BEF2F9B2EF2AFF5C902B6D42AF1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */; }; - 3703B6E48C92A9CA9485B91125942BA9 /* AES+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4930683B08C33AF0F305F47695EBEA3A /* AES+Foundation.swift */; }; - 395968454CBE736B64F63A633E0B68E4 /* String+FoundationExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B9C9576330A2201FA5FA2A66FC0596D /* String+FoundationExtension.swift */; }; - 3C8A5FD4672DBB6ED5B8E8FBC12C633D /* Poly1305.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF8297B20577E1B5B1EDF1DE71AAEAC /* Poly1305.swift */; }; - 3D87B3B0FD6435BB315EFC905422302C /* UInt16+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF4F14E3B549084EED6396285CD9C4A /* UInt16+Extension.swift */; }; - 3DC2810AEA96A3728F4BF638C0371E8A /* Bit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7891438183174B010849EE16EC0B68 /* Bit.swift */; }; - 3EB15695F4BE7EBCE4ABF6B31BA04CA9 /* ChaCha20+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0D87F44520FD278A8382D8DDBCA119C /* ChaCha20+Foundation.swift */; }; - 44751BA17838B5BDE6AA88A7D19CDC35 /* PKCS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF4FDD82CE4B9195C6D126CCCE57090E /* PKCS5.swift */; }; - 473DABC63FCEDEAC6C02E4AFE687DB31 /* BatchedCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F42D5916AB8A1FC4FA408997817AE86 /* BatchedCollection.swift */; }; - 48E770EAFA3730666D434C9AC7E48496 /* Generics.swift in Sources */ = {isa = PBXBuildFile; fileRef = E723BB881B28C7F2E108E93FEBE1A46C /* Generics.swift */; }; - 494751D9321DF2E06F6FAF41A6017E7F /* HKDF.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05AAD9CD5929ABE280DF39FDA2D57A3D /* HKDF.swift */; }; - 49C6022FFB654F025AE6247765EFD40C /* ECB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A8F5DD177A733404CDE172BCFE6DEDC /* ECB.swift */; }; - 5E77A3F633DBBD4C39776F6744EDC308 /* SecureBytes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B87549D1373695DA7935EB604B95FB0D /* SecureBytes.swift */; }; - 65D826FD61BD6BD47FECFFA148216844 /* Blowfish.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F45932496A1D1AF5A9B5D11AA1B6379 /* Blowfish.swift */; }; - 68DB82CA9203E9108F79F47AED2E8E6A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */; }; - 69086E943FDA1EF21D24289B1D5C60D2 /* BlockCipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = E10424AA36CE05FD512761FFEDCBAF6C /* BlockCipher.swift */; }; - 69E4627B6E2338D2F586FA167CDC6E95 /* Int+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 191FCA13BFC587807608EE78E641B78D /* Int+Extension.swift */; }; - 6C715228EFC892AD90E07CE6517BC9D4 /* Checksum.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20673D47BADAAE371A6D1D4AB2C079D5 /* Checksum.swift */; }; - 6F5501B927A46CCF4F52A4CD7C1E33EC /* SHA3.swift in Sources */ = {isa = PBXBuildFile; fileRef = D034CF51EE8F6519BB0FE897047E1CD8 /* SHA3.swift */; }; - 7073740DBB60483C88302F708F2F0039 /* CBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0A770514358B491E856A8C73934B0E7 /* CBC.swift */; }; - 74DE9C0DBED7C14ED409BFAA17158E73 /* CryptoSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 31CE01D5451A5240FC1937D0D1073E96 /* CryptoSwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 779811AAB014C57EAB3A43BB83A42F9E /* Rabbit+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75638B1B53CD11CC43C7F09ADBA88D98 /* Rabbit+Foundation.swift */; }; - 790B502A5E39B63AB1CD72638362BDDD /* CTR.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CC36BFD1E124638BBE348967908C6A /* CTR.swift */; }; - 7C4FE99E01C8A635B3CE77F05B74B2DA /* PKCS7.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B0228ADBEA7D5A1E0FACD4C7C07E15 /* PKCS7.swift */; }; - 7C93878B47BE664097F3A63B89D1A862 /* RandomAccessCryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B24D0F45827DAE0BC296B7D2ABBEB94 /* RandomAccessCryptor.swift */; }; - 7DF98DF4ECF09A73ABE5B1092628461F /* PCBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BC5E9FDC0794915C037F7D0B9A92655 /* PCBC.swift */; }; - 7E38C53CC00067C7A5FA953B9261BF29 /* CryptoSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 75F7B84503F41364555CFC6945B75C53 /* CryptoSwift-dummy.m */; }; - 80763ECA711BA3777C09B81B21E288C8 /* ChaCha20.swift in Sources */ = {isa = PBXBuildFile; fileRef = 474F2FD4F2E5FCF33A3C2B10229F55E2 /* ChaCha20.swift */; }; - 8131E626B940699512588EDA2CAEBD34 /* UInt64+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20E52385C4802542C0CA766B3F129C20 /* UInt64+Extension.swift */; }; - 848B237EB31C02719899A90111FB08DA /* HMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5406734B12796208095D0CB213BBEAD8 /* HMAC.swift */; }; - 85F41150DC5EA8413BEE3F2608F11991 /* Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4591ED7D4B6A682FD57C96167D225BD7 /* Padding.swift */; }; - 87FAA6BD98D8B8712821DB532CDFF447 /* AES.Cryptors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52FF99CDBD8674CE2D14381B432C4E6D /* AES.Cryptors.swift */; }; - 8E9D8397BA554CE359B42FBAE1BCBD08 /* SHA2.swift in Sources */ = {isa = PBXBuildFile; fileRef = D048A4807948A5565AA7BFC6EDC8858E /* SHA2.swift */; }; - 934B3EA778B62DB2D5D8F0B02777E3F5 /* BlockModeWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0745C4390DFD61D27C2F3499B2F3D2E7 /* BlockModeWorker.swift */; }; - 94DA4265D2AF0A4CA879A7F6D5B5A820 /* BlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ACA19A307F2B21F931FD6DDF87356D2 /* BlockMode.swift */; }; - 960978CE23EE23DC0AF7E5954D6CB2A3 /* CFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6D0B6BA8036ED273D9027F2C740F1A5 /* CFB.swift */; }; - 97B2B4AFFA86BA7E0F85F53DC0F0B466 /* Collection+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17AF38AABF71297F2FE6B5CD5375A2EA /* Collection+Extension.swift */; }; - 9985EDF7C8CA28B64DFC22F3716C59C5 /* Pods-Friendvatars-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = F90EE9B48157BDCBAE77E93C7A59E50B /* Pods-Friendvatars-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A300671F55DD95AE86819358B2C6DE32 /* Cryptors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C93EBBCC4BE9F5C1F1EED483E76929A /* Cryptors.swift */; }; - B2F16B6F4D5D5944929BF9B416772565 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = E236D7F3DE185A040EA09B9BFC56188E /* Utils.swift */; }; - B856B5034004C190E8B2B8A2F038527D /* UInt32+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EBFAE3C75105602890BD9A047D689EC /* UInt32+Extension.swift */; }; - B90AA1D193D9DA983C60B24EB3B5A189 /* Updatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBF814346C0E5BFDE8D4559FE6294F6 /* Updatable.swift */; }; - BD7F3C923AC47D15F51AD07D359BBDA4 /* Array+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 206294523958ED48244DEB8DCB4CF023 /* Array+Extension.swift */; }; - C745A2AA05FA14326388532157D59FD2 /* Rabbit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 603C9968D4F76B3C922BCB6AD6BBCE4B /* Rabbit.swift */; }; - C953641D50BEADDEC1E341FE87247AF8 /* HMAC+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = E06127188259CDD74B9E186703788F84 /* HMAC+Foundation.swift */; }; - CA44F79721F689C434DEFA89D31ECD53 /* Blowfish+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = F81032203334F0F82DE8BAD6CDBDA0E5 /* Blowfish+Foundation.swift */; }; - CAA3F0F3507AB5798B490B49D95E3809 /* DigestType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 116BE809A8BBF8F709926DDC28236638 /* DigestType.swift */; }; - CABB4A3C203CD9D6721E52111BDB6A89 /* Pods-Friendvatars-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 853933329993C6F99DEF07589D2E4F88 /* Pods-Friendvatars-dummy.m */; }; - CBBE1B5655CD83A70E2856B7D33D3103 /* PBKDF1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9913797121D44D906414A1F51BA3AF4F /* PBKDF1.swift */; }; - CD11E1CA4EC90EB672AB603B3BD82EAE /* ZeroPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71E3DED970010B6C6E14D42D39702D05 /* ZeroPadding.swift */; }; - D0CC6EF77721FDC29F558F2B6ACEEDCF /* Data+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA5DD41E358E01C837004B16A0212C24 /* Data+Extension.swift */; }; - D7CA1999F4D69F97C9042949C5E02286 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4CA579D6B6E98CEE82B19109E58815 /* Operators.swift */; }; - DBBC0B3E2A77C465F817B4CB91C7CA6E /* RandomBytesSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE3239BE51129F9B1A0D69D90B31A0C1 /* RandomBytesSequence.swift */; }; - E039B801D197986FE25FD3011D2A324D /* PBKDF2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74184CDFE882702363A6B155483AD804 /* PBKDF2.swift */; }; - E780BDD3E588068FF869701FDC2D6BBE /* OFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9605A1A7D44A6AFA150179262A998D31 /* OFB.swift */; }; - E99E9C0D8889E1ABED1BB66EA5E26F6B /* AES.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A28550EFD88321FB1C5FF15DA5C62D /* AES.swift */; }; - E9DDCBC12D0C48E9072371632E2EE354 /* BlockModeOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B93AADC6BCC5141024213D3D2111DD2 /* BlockModeOptions.swift */; }; - EC44355442C7E895D8BDD437C8FC1A50 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E5B910E685A01D78A440C32F40D1F80 /* String+Extension.swift */; }; - EEBE924BD06D6681AAA6003C3A6DBB33 /* MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97497923A52857052C39C3C1F5384057 /* MD5.swift */; }; - EEC95E134BF6663B52A72D8B53375C00 /* PKCS7Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193F3BAC26CCDDE2D5AD828DD924C805 /* PKCS7Padding.swift */; }; - FFEFA357A2ECFD2C8696A7D9B6559CAC /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D5417AD168033723D327DBF2B77B2F3 /* Cipher.swift */; }; + 029CCDE6075BC29CE715C255CF60EBED /* CFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = E51B68AF254C6AD8A6ACCD9FC50ADE3F /* CFB.swift */; }; + 0956811701EC202F2F69628EDCBB9EFD /* SHA2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83760D11E74EBD3B2EB24D0F9FF8B3B3 /* SHA2.swift */; }; + 09873F77E269091531A2000295876ED3 /* UInt8+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 161CAB2E0F3185C58480D32D8C1E1B2E /* UInt8+Extension.swift */; }; + 0CB63DF68E61516B91FDCDCBE4519EFC /* RandomAccessBlockModeWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79A7E3E41B22DFA5C7ABC3109DAF83E3 /* RandomAccessBlockModeWorker.swift */; }; + 0CD5836CA8A6C1C7C38E51F95B0EC027 /* BlockMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 273AD107D3DCE9B2F5FDD0B6304772B8 /* BlockMode.swift */; }; + 0D11FC42AE9E341FE113D5FAEEED8C04 /* CryptoSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1CA428AC99ABECD85EF401A66ABC7696 /* CryptoSwift-dummy.m */; }; + 0FE198D97026CEA7FED2C43521BB9501 /* Blowfish.swift in Sources */ = {isa = PBXBuildFile; fileRef = 888FFC9B9D087C7D71D00FB4DB0CE591 /* Blowfish.swift */; }; + 11DA82F1D104F6DBA7592F3F9F53AACB /* CTR.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64CD0C9C7241F26A15C9783D847AFEBD /* CTR.swift */; }; + 18C1AA22F5B3651F114294733FDF5B2A /* SecureBytes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 473C8EDB81BDF1DF3D47F1DB093B4EB9 /* SecureBytes.swift */; }; + 21CE5B0F01F8E58E9EABCA1B6ED154BA /* Rabbit+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47CC1CCF8B4E2A7AF6B5325D050F5427 /* Rabbit+Foundation.swift */; }; + 2672625ED4BD11DB4DD83A4E9BDDF6F9 /* Cryptors.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE4E900C0626571AC366D9B0092E8CE2 /* Cryptors.swift */; }; + 270B917A023E92844CFDFBE7E44797D1 /* ChaCha20.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4606993A043F5C0BA70481A2392E966D /* ChaCha20.swift */; }; + 29EF96F51B6027797F0760320DCA6BD5 /* String+FoundationExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE6BD41C35B26AC0B8E61CC549BBC8BB /* String+FoundationExtension.swift */; }; + 2BF51761B945E33FA10C59EA934B8088 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A8C42D2DD20BA6A96369288B8D61AA7 /* String+Extension.swift */; }; + 2FB8C4D3042DF4A50C1FF99BD5D6A38F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6DFF15000AFE2A371BF499E7AFDA808 /* Foundation.framework */; }; + 360667D5B252324DEA6B75898D382381 /* BlockCipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21F4E25671FA5462E18A72A2088E3679 /* BlockCipher.swift */; }; + 39787DCF5D9423D45E4C5369F0FB53BA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6DFF15000AFE2A371BF499E7AFDA808 /* Foundation.framework */; }; + 3FCC64403F8DE2D2B3BAE71F3F0CC1C7 /* BlockModeWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76FDAD94210C27931310F31EF70F01FA /* BlockModeWorker.swift */; }; + 41642560CA055E8EE8FCA2DCA5313C23 /* MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35D42AE82B529B948EA396E0EFCFBBE2 /* MD5.swift */; }; + 4544D85EA993B42F5915E7AA8F4C0F6C /* DigestType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 494A68AB67E90B3C19E49251229B3CB4 /* DigestType.swift */; }; + 4565031E0304574C7A466B62E73E7478 /* KeychainAccess-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 16E72221FAB44B4B748A00FA0F05304C /* KeychainAccess-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4881DAE730C3678FEA94F8A2622252C1 /* Pods-Friendvatars-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 243C453A941B28D8DC074B9886773BC4 /* Pods-Friendvatars-dummy.m */; }; + 4AB554DF0F4CFA6D8E14FB06A95385D8 /* HMAC+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 481C2E1AF54F246301EF5F049557AD55 /* HMAC+Foundation.swift */; }; + 4B3B8AEAD3654C79DD2984A29DACE5B9 /* PBKDF1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B8080FDAFA546A72CE62CF4236595BD /* PBKDF1.swift */; }; + 4C024CC2A1003237347D216A03A5878C /* Collection+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55EF4E3D2AA6FBB9D1A6415F35E7370B /* Collection+Extension.swift */; }; + 528D7571D85151FF800C4E3654E1FA86 /* Array+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 953F3DF82C04A300C100C78F03A62819 /* Array+Extensions.swift */; }; + 5B5E80A7A1AD0C13169BDDAECA394073 /* Data+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AF125A30F5AD9E69BA6FFC9277F824B /* Data+Extension.swift */; }; + 63A2B87CCC493F65ACEE0001E5CB2B19 /* PKCS7Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C87CC909DB3EC7C512ED8559264DFF8 /* PKCS7Padding.swift */; }; + 645C52C486190C3F39E6D434FACECECD /* RandomAccessCryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0F5B3BD214AC94F881907246D3D8140 /* RandomAccessCryptor.swift */; }; + 6BA9D56D4651F39C19833F1F409D4178 /* PKCS7.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A59AFF41F06F275C7503386778D8B65 /* PKCS7.swift */; }; + 6DD366D4D2E525C12528BE966B822B05 /* Bit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F393841799B8CEF8E73B063769C67E7 /* Bit.swift */; }; + 77055ACA57CE4A39671C183CB60EBCF2 /* BlockModeOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6AD5A201FC9CC29A7AC7393573AB22B /* BlockModeOptions.swift */; }; + 78B30076720C6EC70BDCB49DD3A25BC0 /* ChaCha20+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72A6F75298DE02CCF6A5AD6FA63464F3 /* ChaCha20+Foundation.swift */; }; + 79FFE636BA8AE65FF53BA916856C69C8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6DFF15000AFE2A371BF499E7AFDA808 /* Foundation.framework */; }; + 7CBB1492A9E2DD4F5DFC1BA7A95D3344 /* UInt16+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 683220FE8506C6CA2D26A60A58D2E9C3 /* UInt16+Extension.swift */; }; + 7FD1C9171DE80CDCBE2C974D9EE0991A /* KeychainAccess-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 85C28A2C77E79D203EEB003E3D3722F3 /* KeychainAccess-dummy.m */; }; + 8723CA06E8722D3594EAA1A139A6D803 /* Utils+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1948ED714A1D42260A1B9FDF4E6C5E5 /* Utils+Foundation.swift */; }; + 8E8BA6D0A85A8D3FBC55D447ACF7C156 /* Authenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38A5E783ED32E248C568E3A56D9EF732 /* Authenticator.swift */; }; + 9233A3E22B89BD228FBB3F1DDEEC4EFE /* BatchedCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE64D263EC6A70516407A75328DA2ABC /* BatchedCollection.swift */; }; + 95C37DDA83D94B3B59A40A3426A65684 /* UInt64+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A779A36DA6B6DA2263224A1C96509266 /* UInt64+Extension.swift */; }; + 96704219B31375941271FF02AAC8193C /* Poly1305.swift in Sources */ = {isa = PBXBuildFile; fileRef = B414586449537501C26A5504271D1C05 /* Poly1305.swift */; }; + 9782A81566BFFA815BD6FEEB13D54D06 /* Checksum.swift in Sources */ = {isa = PBXBuildFile; fileRef = 138EC8D2DA441044B77E97F1B9E111AF /* Checksum.swift */; }; + 9CC85DD5BB289CB4F6C01E7952E23CE6 /* CryptoSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D1713133D68D11B16ABA20749418DF7 /* CryptoSwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9EE4737714DE0CDBCC66384EA4982AD8 /* Updatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5678EE6C103997704E23674FBC893360 /* Updatable.swift */; }; + 9EF595A91415241CCB3320594B53F282 /* OFB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 108072927D38C61A0B7D2A551D27241C /* OFB.swift */; }; + 9F80EAE2671115979B9F2BA5A17C04E9 /* Array+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32CEBC58EA4A2357034EDB9ACF1C74D0 /* Array+Foundation.swift */; }; + A73F91DACC3AB17F91D968B03A6FFF33 /* SHA3.swift in Sources */ = {isa = PBXBuildFile; fileRef = 644E76D60A87D86EF20DD3D9801327F0 /* SHA3.swift */; }; + A7DF73F094D79EA40BC71350652C400C /* HKDF.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9237A63642D9303E14B07FE23802DE78 /* HKDF.swift */; }; + A8FC628BC39A85B021B33CD0EDF94E06 /* Keychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1373F0E78BDECEA39078CFC65680876 /* Keychain.swift */; }; + AAD7BE5314AC1DB28A194D05CA74D9D7 /* Generics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A9F971A39BD5E2D7A1BD47CE909801 /* Generics.swift */; }; + AF55FD642987DCEAAE9795808F6267BD /* Int+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 979D367046B64E3F4B36289995A2ECA3 /* Int+Extension.swift */; }; + B0300AF42EB5F8D38F9EA98E95C696E1 /* UInt32+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE3155A4A1AEFD8F6D79D7E9EFE08478 /* UInt32+Extension.swift */; }; + B29D6D60FCCD5C636F33D5CAAA6BF2BB /* HMAC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49E710C03C6E2E1BC8639661CEBD9FE0 /* HMAC.swift */; }; + B6F9DC89BB62F23C6384F6E26ECBD4A9 /* NoPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2353CC599D9B766CB43D57A085D49044 /* NoPadding.swift */; }; + BEE403F4842EC4C88A514E7374E8B417 /* ZeroPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4505CF7E1882B02B054FEE0C70B66D8F /* ZeroPadding.swift */; }; + C0313257B3F8482EAFE428726FD845D9 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0F6E05FAB446A153EE06855CA85DEBA /* Utils.swift */; }; + C1BEDEA59E2E6D70D341E609CAC35E71 /* RandomBytesSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9DE1E11183EECCCCB58A2004427BAA0 /* RandomBytesSequence.swift */; }; + C3232F5FF289636B5085FBD43D5AE6FD /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1524BF10BD1056A5EBDE0CFC40B3FB6A /* Operators.swift */; }; + C668F20671BE60B79CF7B9D1C3791E35 /* Digest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99E931693897E64B6DCBFA9E371F4462 /* Digest.swift */; }; + C7AE9D99B081CD446727F3E8B32317C4 /* CBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E07FF1FD31D0F924F415A44F3FD4B17 /* CBC.swift */; }; + C992CCAE597216BDCDFE491223C06BE1 /* Rabbit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 893EA1F26FBC0EDD4BB740FBF13C8ADC /* Rabbit.swift */; }; + CC59CFB29942D3024B21409F183A41F1 /* Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A3DD025F450875EE3390D46E9690E8F /* Padding.swift */; }; + CCF37A73A04567CD14F94798DB2D4C76 /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBBDEDAE309B6BE53E518555CBABFCF /* Cipher.swift */; }; + CE4A24B14EE10DF8E29E27D17F5FA5DD /* PBKDF2.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC5C14E8DB45F26AD8E5A9826257AF38 /* PBKDF2.swift */; }; + D1953BAD6AD8DFD90F296DCC7E8A5ED7 /* AES.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33DD58A4FE4A2BD008EE428C51053A03 /* AES.swift */; }; + D4D811091053D1871366EC650281DC15 /* PCBC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9027941EF37837F538EA200BA4078FAC /* PCBC.swift */; }; + D9F8C56F455EA541B961F6AD650E3AA2 /* AES.Cryptors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522FF09BA6EB0EE42AB7B0962DD097F2 /* AES.Cryptors.swift */; }; + DB8DEC0D10D2DFD5D9A22F679911FCF9 /* Blowfish+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6308BD6BC265D7B0351C546015E4808E /* Blowfish+Foundation.swift */; }; + E5E39AA990B1E34C79CFE8F90E6AFA97 /* SHA1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97073FF2F9CD5B9872A9ECC9FEF7F1D1 /* SHA1.swift */; }; + EA96722B1A22E50779569D6FB1B2C24A /* ECB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6411A22DE7995511193E4C8D65684EB0 /* ECB.swift */; }; + ED9945DDBD34C37E6A9F4A6FD7A0178A /* AES+Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F2F6D32AEE751B384F4730346F15DA /* AES+Foundation.swift */; }; + F01FB4F122B343BE13963EB262255675 /* PKCS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CC087CCDC0B9F6D0D14EB6ECC0F1C3A /* PKCS5.swift */; }; + F27539EDE127CBB68FF6DF65ACB38D9A /* Array+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 869C1299FF11A862D35D4E0F9BDDEA98 /* Array+Extension.swift */; }; + F3D08773F50E664E51661FCF4274403A /* Pods-Friendvatars-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = D4D46F0CAAE370B836D3A34109465A77 /* Pods-Friendvatars-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - FC21C348DB5F26AD02A6B216B82EFEF5 /* PBXContainerItemProxy */ = { + 12182EA804E368C696A82EA3D0847BB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; - remoteGlobalIDString = DE16D66575B4E29D54F3F5DB5CD606FB; + remoteGlobalIDString = 1630C0AC0CCE2704C3F517D1DFD56586; + remoteInfo = KeychainAccess; + }; + 4E4D75D7D535AA2262C115253513E932 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 16F79934C9B37C10283012C65CA992AB; remoteInfo = CryptoSwift; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 04EFD937AD6D622C4D5016DC92956436 /* Authenticator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Authenticator.swift; path = Sources/CryptoSwift/Authenticator.swift; sourceTree = ""; }; - 05AAD9CD5929ABE280DF39FDA2D57A3D /* HKDF.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HKDF.swift; path = Sources/CryptoSwift/HKDF.swift; sourceTree = ""; }; - 0745C4390DFD61D27C2F3499B2F3D2E7 /* BlockModeWorker.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BlockModeWorker.swift; path = Sources/CryptoSwift/BlockMode/BlockModeWorker.swift; sourceTree = ""; }; - 07F9C623D91918F13560D807485D5154 /* Pods-Friendvatars.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Friendvatars.release.xcconfig"; sourceTree = ""; }; - 097F053EAB3A78D608DA971D6D318270 /* Pods-Friendvatars.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Friendvatars.debug.xcconfig"; sourceTree = ""; }; - 0B24D0F45827DAE0BC296B7D2ABBEB94 /* RandomAccessCryptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RandomAccessCryptor.swift; path = Sources/CryptoSwift/RandomAccessCryptor.swift; sourceTree = ""; }; - 0B93AADC6BCC5141024213D3D2111DD2 /* BlockModeOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BlockModeOptions.swift; path = Sources/CryptoSwift/BlockMode/BlockModeOptions.swift; sourceTree = ""; }; - 0D5417AD168033723D327DBF2B77B2F3 /* Cipher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Cipher.swift; path = Sources/CryptoSwift/Cipher.swift; sourceTree = ""; }; - 0EBFAE3C75105602890BD9A047D689EC /* UInt32+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UInt32+Extension.swift"; path = "Sources/CryptoSwift/UInt32+Extension.swift"; sourceTree = ""; }; - 116BE809A8BBF8F709926DDC28236638 /* DigestType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DigestType.swift; path = Sources/CryptoSwift/DigestType.swift; sourceTree = ""; }; - 17AF38AABF71297F2FE6B5CD5375A2EA /* Collection+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Collection+Extension.swift"; path = "Sources/CryptoSwift/Collection+Extension.swift"; sourceTree = ""; }; - 17EB19E1EF889F2602A6CD4BFA3B9610 /* NoPadding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NoPadding.swift; path = Sources/CryptoSwift/NoPadding.swift; sourceTree = ""; }; - 191FCA13BFC587807608EE78E641B78D /* Int+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Int+Extension.swift"; path = "Sources/CryptoSwift/Int+Extension.swift"; sourceTree = ""; }; - 193F3BAC26CCDDE2D5AD828DD924C805 /* PKCS7Padding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PKCS7Padding.swift; path = Sources/CryptoSwift/PKCS/PKCS7Padding.swift; sourceTree = ""; }; - 1C93EBBCC4BE9F5C1F1EED483E76929A /* Cryptors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Cryptors.swift; path = Sources/CryptoSwift/Cryptors.swift; sourceTree = ""; }; - 206294523958ED48244DEB8DCB4CF023 /* Array+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Array+Extension.swift"; path = "Sources/CryptoSwift/Array+Extension.swift"; sourceTree = ""; }; - 20673D47BADAAE371A6D1D4AB2C079D5 /* Checksum.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Checksum.swift; path = Sources/CryptoSwift/Checksum.swift; sourceTree = ""; }; - 20983313641ED544FC46B0316BF79926 /* Array+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Array+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/Array+Foundation.swift"; sourceTree = ""; }; - 20E52385C4802542C0CA766B3F129C20 /* UInt64+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UInt64+Extension.swift"; path = "Sources/CryptoSwift/UInt64+Extension.swift"; sourceTree = ""; }; - 259F606BDF24A4DDF819F79A4355CE83 /* RandomAccessBlockModeWorker.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RandomAccessBlockModeWorker.swift; path = Sources/CryptoSwift/BlockMode/RandomAccessBlockModeWorker.swift; sourceTree = ""; }; - 25C2A3D020A9CF253BA790C95DE5C85D /* Pods_Friendvatars.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_Friendvatars.framework; path = "Pods-Friendvatars.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; - 303F88462BBA275BDCE3E6F3562217CF /* Pods-Friendvatars-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Friendvatars-acknowledgements.plist"; sourceTree = ""; }; - 31CE01D5451A5240FC1937D0D1073E96 /* CryptoSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CryptoSwift-umbrella.h"; sourceTree = ""; }; - 3ACA19A307F2B21F931FD6DDF87356D2 /* BlockMode.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BlockMode.swift; path = Sources/CryptoSwift/BlockMode/BlockMode.swift; sourceTree = ""; }; - 4591ED7D4B6A682FD57C96167D225BD7 /* Padding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Padding.swift; path = Sources/CryptoSwift/Padding.swift; sourceTree = ""; }; - 474F2FD4F2E5FCF33A3C2B10229F55E2 /* ChaCha20.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ChaCha20.swift; path = Sources/CryptoSwift/ChaCha20.swift; sourceTree = ""; }; - 4930683B08C33AF0F305F47695EBEA3A /* AES+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "AES+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/AES+Foundation.swift"; sourceTree = ""; }; - 4B7891438183174B010849EE16EC0B68 /* Bit.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Bit.swift; path = Sources/CryptoSwift/Bit.swift; sourceTree = ""; }; - 4E5B910E685A01D78A440C32F40D1F80 /* String+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+Extension.swift"; path = "Sources/CryptoSwift/String+Extension.swift"; sourceTree = ""; }; - 517AB0425C00CCB935BD21090EB301BB /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = CryptoSwift.framework; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 52FF99CDBD8674CE2D14381B432C4E6D /* AES.Cryptors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AES.Cryptors.swift; path = Sources/CryptoSwift/AES.Cryptors.swift; sourceTree = ""; }; - 5406734B12796208095D0CB213BBEAD8 /* HMAC.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HMAC.swift; path = Sources/CryptoSwift/HMAC.swift; sourceTree = ""; }; - 559DA49EAEB2B41A456CC65EC9E40676 /* Pods-Friendvatars.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = "Pods-Friendvatars.modulemap"; sourceTree = ""; }; - 5785DF3045F4DCB4D27D3DA7BD4C1579 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5CBF814346C0E5BFDE8D4559FE6294F6 /* Updatable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Updatable.swift; path = Sources/CryptoSwift/Updatable.swift; sourceTree = ""; }; - 5F45932496A1D1AF5A9B5D11AA1B6379 /* Blowfish.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Blowfish.swift; path = Sources/CryptoSwift/Blowfish.swift; sourceTree = ""; }; - 603C9968D4F76B3C922BCB6AD6BBCE4B /* Rabbit.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Rabbit.swift; path = Sources/CryptoSwift/Rabbit.swift; sourceTree = ""; }; - 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; - 67A28550EFD88321FB1C5FF15DA5C62D /* AES.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AES.swift; path = Sources/CryptoSwift/AES.swift; sourceTree = ""; }; - 694C4A993EFE74C83AF54A4ECA2F91AA /* CryptoSwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CryptoSwift-prefix.pch"; sourceTree = ""; }; - 6A8F5DD177A733404CDE172BCFE6DEDC /* ECB.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ECB.swift; path = Sources/CryptoSwift/BlockMode/ECB.swift; sourceTree = ""; }; - 6BC5E9FDC0794915C037F7D0B9A92655 /* PCBC.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PCBC.swift; path = Sources/CryptoSwift/BlockMode/PCBC.swift; sourceTree = ""; }; - 6E483B3851B6079DF39ABBF182139303 /* Array+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Array+Extensions.swift"; path = "Sources/CryptoSwift/Array+Extensions.swift"; sourceTree = ""; }; - 71E3DED970010B6C6E14D42D39702D05 /* ZeroPadding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ZeroPadding.swift; path = Sources/CryptoSwift/ZeroPadding.swift; sourceTree = ""; }; - 74184CDFE882702363A6B155483AD804 /* PBKDF2.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PBKDF2.swift; path = Sources/CryptoSwift/PKCS/PBKDF2.swift; sourceTree = ""; }; - 744ED72F2ADD9975CADAC93B3E5CC907 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 75638B1B53CD11CC43C7F09ADBA88D98 /* Rabbit+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Rabbit+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/Rabbit+Foundation.swift"; sourceTree = ""; }; - 75F7B84503F41364555CFC6945B75C53 /* CryptoSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CryptoSwift-dummy.m"; sourceTree = ""; }; - 764482285D9CADC5E9B6B4AF0E0B4B39 /* Pods-Friendvatars-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Friendvatars-resources.sh"; sourceTree = ""; }; - 7A313DC180F5A42AFDCF5F4D9E6B0E3E /* Digest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Digest.swift; path = Sources/CryptoSwift/Digest.swift; sourceTree = ""; }; - 853933329993C6F99DEF07589D2E4F88 /* Pods-Friendvatars-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Friendvatars-dummy.m"; sourceTree = ""; }; - 8F42D5916AB8A1FC4FA408997817AE86 /* BatchedCollection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BatchedCollection.swift; path = Sources/CryptoSwift/BatchedCollection.swift; sourceTree = ""; }; + 040D077AD29E2F782500310CB98114D0 /* KeychainAccess.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = KeychainAccess.framework; path = KeychainAccess.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 0A3DD025F450875EE3390D46E9690E8F /* Padding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Padding.swift; path = Sources/CryptoSwift/Padding.swift; sourceTree = ""; }; + 0B8080FDAFA546A72CE62CF4236595BD /* PBKDF1.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PBKDF1.swift; path = Sources/CryptoSwift/PKCS/PBKDF1.swift; sourceTree = ""; }; + 0C87CC909DB3EC7C512ED8559264DFF8 /* PKCS7Padding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PKCS7Padding.swift; path = Sources/CryptoSwift/PKCS/PKCS7Padding.swift; sourceTree = ""; }; + 108072927D38C61A0B7D2A551D27241C /* OFB.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = OFB.swift; path = Sources/CryptoSwift/BlockMode/OFB.swift; sourceTree = ""; }; + 138EC8D2DA441044B77E97F1B9E111AF /* Checksum.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Checksum.swift; path = Sources/CryptoSwift/Checksum.swift; sourceTree = ""; }; + 13F5C812210EF5A9F18351D1430B2E39 /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = CryptoSwift.framework; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1524BF10BD1056A5EBDE0CFC40B3FB6A /* Operators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Operators.swift; path = Sources/CryptoSwift/Operators.swift; sourceTree = ""; }; + 161CAB2E0F3185C58480D32D8C1E1B2E /* UInt8+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UInt8+Extension.swift"; path = "Sources/CryptoSwift/UInt8+Extension.swift"; sourceTree = ""; }; + 16E72221FAB44B4B748A00FA0F05304C /* KeychainAccess-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "KeychainAccess-umbrella.h"; sourceTree = ""; }; + 1AF125A30F5AD9E69BA6FFC9277F824B /* Data+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Data+Extension.swift"; path = "Sources/CryptoSwift/Foundation/Data+Extension.swift"; sourceTree = ""; }; + 1CA428AC99ABECD85EF401A66ABC7696 /* CryptoSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CryptoSwift-dummy.m"; sourceTree = ""; }; + 1F393841799B8CEF8E73B063769C67E7 /* Bit.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Bit.swift; path = Sources/CryptoSwift/Bit.swift; sourceTree = ""; }; + 21F4E25671FA5462E18A72A2088E3679 /* BlockCipher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BlockCipher.swift; path = Sources/CryptoSwift/BlockCipher.swift; sourceTree = ""; }; + 2353CC599D9B766CB43D57A085D49044 /* NoPadding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NoPadding.swift; path = Sources/CryptoSwift/NoPadding.swift; sourceTree = ""; }; + 243C453A941B28D8DC074B9886773BC4 /* Pods-Friendvatars-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Friendvatars-dummy.m"; sourceTree = ""; }; + 273AD107D3DCE9B2F5FDD0B6304772B8 /* BlockMode.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BlockMode.swift; path = Sources/CryptoSwift/BlockMode/BlockMode.swift; sourceTree = ""; }; + 28A9F971A39BD5E2D7A1BD47CE909801 /* Generics.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Generics.swift; path = Sources/CryptoSwift/Generics.swift; sourceTree = ""; }; + 2E50A8BC04995E16B293EF27E1EF7D13 /* Pods-Friendvatars-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Friendvatars-acknowledgements.markdown"; sourceTree = ""; }; + 32CEBC58EA4A2357034EDB9ACF1C74D0 /* Array+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Array+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/Array+Foundation.swift"; sourceTree = ""; }; + 33DD58A4FE4A2BD008EE428C51053A03 /* AES.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AES.swift; path = Sources/CryptoSwift/AES.swift; sourceTree = ""; }; + 35D42AE82B529B948EA396E0EFCFBBE2 /* MD5.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MD5.swift; path = Sources/CryptoSwift/MD5.swift; sourceTree = ""; }; + 35FBA3370551A17B5EC53FF4B5482159 /* Pods-Friendvatars.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Friendvatars.debug.xcconfig"; sourceTree = ""; }; + 38A5E783ED32E248C568E3A56D9EF732 /* Authenticator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Authenticator.swift; path = Sources/CryptoSwift/Authenticator.swift; sourceTree = ""; }; + 4505CF7E1882B02B054FEE0C70B66D8F /* ZeroPadding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ZeroPadding.swift; path = Sources/CryptoSwift/ZeroPadding.swift; sourceTree = ""; }; + 4606993A043F5C0BA70481A2392E966D /* ChaCha20.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ChaCha20.swift; path = Sources/CryptoSwift/ChaCha20.swift; sourceTree = ""; }; + 473C8EDB81BDF1DF3D47F1DB093B4EB9 /* SecureBytes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SecureBytes.swift; path = Sources/CryptoSwift/SecureBytes.swift; sourceTree = ""; }; + 47CC1CCF8B4E2A7AF6B5325D050F5427 /* Rabbit+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Rabbit+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/Rabbit+Foundation.swift"; sourceTree = ""; }; + 481C2E1AF54F246301EF5F049557AD55 /* HMAC+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "HMAC+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/HMAC+Foundation.swift"; sourceTree = ""; }; + 494A68AB67E90B3C19E49251229B3CB4 /* DigestType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DigestType.swift; path = Sources/CryptoSwift/DigestType.swift; sourceTree = ""; }; + 49E710C03C6E2E1BC8639661CEBD9FE0 /* HMAC.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HMAC.swift; path = Sources/CryptoSwift/HMAC.swift; sourceTree = ""; }; + 4A8C42D2DD20BA6A96369288B8D61AA7 /* String+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+Extension.swift"; path = "Sources/CryptoSwift/String+Extension.swift"; sourceTree = ""; }; + 522FF09BA6EB0EE42AB7B0962DD097F2 /* AES.Cryptors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AES.Cryptors.swift; path = Sources/CryptoSwift/AES.Cryptors.swift; sourceTree = ""; }; + 55EF4E3D2AA6FBB9D1A6415F35E7370B /* Collection+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Collection+Extension.swift"; path = "Sources/CryptoSwift/Collection+Extension.swift"; sourceTree = ""; }; + 5678EE6C103997704E23674FBC893360 /* Updatable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Updatable.swift; path = Sources/CryptoSwift/Updatable.swift; sourceTree = ""; }; + 5692E05105400962A0A6EAC9958B6493 /* Pods-Friendvatars.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Friendvatars.release.xcconfig"; sourceTree = ""; }; + 5A1961B0A715EA259584BEB18B069B6B /* Pods-Friendvatars-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Friendvatars-resources.sh"; sourceTree = ""; }; + 5A59AFF41F06F275C7503386778D8B65 /* PKCS7.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PKCS7.swift; path = Sources/CryptoSwift/PKCS/PKCS7.swift; sourceTree = ""; }; + 5CBBDEDAE309B6BE53E518555CBABFCF /* Cipher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Cipher.swift; path = Sources/CryptoSwift/Cipher.swift; sourceTree = ""; }; + 61DA07AD6BC1B2035B17FA1AC3A7F0FC /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6308BD6BC265D7B0351C546015E4808E /* Blowfish+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Blowfish+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/Blowfish+Foundation.swift"; sourceTree = ""; }; + 6411A22DE7995511193E4C8D65684EB0 /* ECB.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ECB.swift; path = Sources/CryptoSwift/BlockMode/ECB.swift; sourceTree = ""; }; + 644E76D60A87D86EF20DD3D9801327F0 /* SHA3.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SHA3.swift; path = Sources/CryptoSwift/SHA3.swift; sourceTree = ""; }; + 64CD0C9C7241F26A15C9783D847AFEBD /* CTR.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CTR.swift; path = Sources/CryptoSwift/BlockMode/CTR.swift; sourceTree = ""; }; + 683220FE8506C6CA2D26A60A58D2E9C3 /* UInt16+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UInt16+Extension.swift"; path = "Sources/CryptoSwift/UInt16+Extension.swift"; sourceTree = ""; }; + 6D1713133D68D11B16ABA20749418DF7 /* CryptoSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CryptoSwift-umbrella.h"; sourceTree = ""; }; + 6E475E92B60D094CE1FA6113EBCC2963 /* Pods-Friendvatars-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Friendvatars-acknowledgements.plist"; sourceTree = ""; }; + 6F8EB64FA3271693B974155ED31D30C1 /* CryptoSwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CryptoSwift-prefix.pch"; sourceTree = ""; }; + 72A6F75298DE02CCF6A5AD6FA63464F3 /* ChaCha20+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ChaCha20+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/ChaCha20+Foundation.swift"; sourceTree = ""; }; + 76FDAD94210C27931310F31EF70F01FA /* BlockModeWorker.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BlockModeWorker.swift; path = Sources/CryptoSwift/BlockMode/BlockModeWorker.swift; sourceTree = ""; }; + 79A7E3E41B22DFA5C7ABC3109DAF83E3 /* RandomAccessBlockModeWorker.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RandomAccessBlockModeWorker.swift; path = Sources/CryptoSwift/BlockMode/RandomAccessBlockModeWorker.swift; sourceTree = ""; }; + 83760D11E74EBD3B2EB24D0F9FF8B3B3 /* SHA2.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SHA2.swift; path = Sources/CryptoSwift/SHA2.swift; sourceTree = ""; }; + 85C28A2C77E79D203EEB003E3D3722F3 /* KeychainAccess-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "KeychainAccess-dummy.m"; sourceTree = ""; }; + 85CAA5FA0A398E9731113F2B60BD4F4F /* Pods-Friendvatars.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-Friendvatars.modulemap"; sourceTree = ""; }; + 867BB4D83DFD836A4A6AAC72993C8558 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 869C1299FF11A862D35D4E0F9BDDEA98 /* Array+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Array+Extension.swift"; path = "Sources/CryptoSwift/Array+Extension.swift"; sourceTree = ""; }; + 888FFC9B9D087C7D71D00FB4DB0CE591 /* Blowfish.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Blowfish.swift; path = Sources/CryptoSwift/Blowfish.swift; sourceTree = ""; }; + 893EA1F26FBC0EDD4BB740FBF13C8ADC /* Rabbit.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Rabbit.swift; path = Sources/CryptoSwift/Rabbit.swift; sourceTree = ""; }; + 8CC087CCDC0B9F6D0D14EB6ECC0F1C3A /* PKCS5.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PKCS5.swift; path = Sources/CryptoSwift/PKCS/PKCS5.swift; sourceTree = ""; }; + 8D46A86B5A5464BB537E468E9A69DAB1 /* Pods_Friendvatars.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_Friendvatars.framework; path = "Pods-Friendvatars.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 9027941EF37837F538EA200BA4078FAC /* PCBC.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PCBC.swift; path = Sources/CryptoSwift/BlockMode/PCBC.swift; sourceTree = ""; }; + 9237A63642D9303E14B07FE23802DE78 /* HKDF.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HKDF.swift; path = Sources/CryptoSwift/HKDF.swift; sourceTree = ""; }; 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - 958C3E35DD866E890E4BA5EB00450218 /* CryptoSwift.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CryptoSwift.xcconfig; sourceTree = ""; }; - 9605A1A7D44A6AFA150179262A998D31 /* OFB.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = OFB.swift; path = Sources/CryptoSwift/BlockMode/OFB.swift; sourceTree = ""; }; - 97497923A52857052C39C3C1F5384057 /* MD5.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MD5.swift; path = Sources/CryptoSwift/MD5.swift; sourceTree = ""; }; - 9913797121D44D906414A1F51BA3AF4F /* PBKDF1.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PBKDF1.swift; path = Sources/CryptoSwift/PKCS/PBKDF1.swift; sourceTree = ""; }; - 9B9C9576330A2201FA5FA2A66FC0596D /* String+FoundationExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+FoundationExtension.swift"; path = "Sources/CryptoSwift/Foundation/String+FoundationExtension.swift"; sourceTree = ""; }; - 9D4CA579D6B6E98CEE82B19109E58815 /* Operators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Operators.swift; path = Sources/CryptoSwift/Operators.swift; sourceTree = ""; }; - A1B0228ADBEA7D5A1E0FACD4C7C07E15 /* PKCS7.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PKCS7.swift; path = Sources/CryptoSwift/PKCS/PKCS7.swift; sourceTree = ""; }; - A6D0B6BA8036ED273D9027F2C740F1A5 /* CFB.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CFB.swift; path = Sources/CryptoSwift/BlockMode/CFB.swift; sourceTree = ""; }; - B87549D1373695DA7935EB604B95FB0D /* SecureBytes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SecureBytes.swift; path = Sources/CryptoSwift/SecureBytes.swift; sourceTree = ""; }; - B9FEC5C85271D8F16DFD9D29CD4175FB /* Utils+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Utils+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/Utils+Foundation.swift"; sourceTree = ""; }; - BA5DD41E358E01C837004B16A0212C24 /* Data+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Data+Extension.swift"; path = "Sources/CryptoSwift/Foundation/Data+Extension.swift"; sourceTree = ""; }; - BFF8297B20577E1B5B1EDF1DE71AAEAC /* Poly1305.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Poly1305.swift; path = Sources/CryptoSwift/Poly1305.swift; sourceTree = ""; }; - C4CC36BFD1E124638BBE348967908C6A /* CTR.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CTR.swift; path = Sources/CryptoSwift/BlockMode/CTR.swift; sourceTree = ""; }; - C4F9E69F3EC6CC5A1B9811A830EDA7FB /* UInt8+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UInt8+Extension.swift"; path = "Sources/CryptoSwift/UInt8+Extension.swift"; sourceTree = ""; }; - C517BCD0B8B6D37A4814132B34868A28 /* Pods-Friendvatars-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Friendvatars-frameworks.sh"; sourceTree = ""; }; - CB3EF8E37892DA1555E52583421106FF /* CryptoSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = CryptoSwift.modulemap; sourceTree = ""; }; - CC86EB5C74C82E488D2A3E273D65E6EA /* Pods-Friendvatars-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Friendvatars-acknowledgements.markdown"; sourceTree = ""; }; - D034CF51EE8F6519BB0FE897047E1CD8 /* SHA3.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SHA3.swift; path = Sources/CryptoSwift/SHA3.swift; sourceTree = ""; }; - D048A4807948A5565AA7BFC6EDC8858E /* SHA2.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SHA2.swift; path = Sources/CryptoSwift/SHA2.swift; sourceTree = ""; }; - DE3239BE51129F9B1A0D69D90B31A0C1 /* RandomBytesSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RandomBytesSequence.swift; path = Sources/CryptoSwift/RandomBytesSequence.swift; sourceTree = ""; }; - E06127188259CDD74B9E186703788F84 /* HMAC+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "HMAC+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/HMAC+Foundation.swift"; sourceTree = ""; }; - E10424AA36CE05FD512761FFEDCBAF6C /* BlockCipher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BlockCipher.swift; path = Sources/CryptoSwift/BlockCipher.swift; sourceTree = ""; }; - E236D7F3DE185A040EA09B9BFC56188E /* Utils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Utils.swift; path = Sources/CryptoSwift/Utils.swift; sourceTree = ""; }; - E723BB881B28C7F2E108E93FEBE1A46C /* Generics.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Generics.swift; path = Sources/CryptoSwift/Generics.swift; sourceTree = ""; }; - E923A37930CBC57D57B8A58D34037E06 /* SHA1.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SHA1.swift; path = Sources/CryptoSwift/SHA1.swift; sourceTree = ""; }; - EAF4F14E3B549084EED6396285CD9C4A /* UInt16+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UInt16+Extension.swift"; path = "Sources/CryptoSwift/UInt16+Extension.swift"; sourceTree = ""; }; - F0A770514358B491E856A8C73934B0E7 /* CBC.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CBC.swift; path = Sources/CryptoSwift/BlockMode/CBC.swift; sourceTree = ""; }; - F0D87F44520FD278A8382D8DDBCA119C /* ChaCha20+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ChaCha20+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/ChaCha20+Foundation.swift"; sourceTree = ""; }; - F81032203334F0F82DE8BAD6CDBDA0E5 /* Blowfish+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Blowfish+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/Blowfish+Foundation.swift"; sourceTree = ""; }; - F90EE9B48157BDCBAE77E93C7A59E50B /* Pods-Friendvatars-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Friendvatars-umbrella.h"; sourceTree = ""; }; - FF4FDD82CE4B9195C6D126CCCE57090E /* PKCS5.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PKCS5.swift; path = Sources/CryptoSwift/PKCS/PKCS5.swift; sourceTree = ""; }; + 953F3DF82C04A300C100C78F03A62819 /* Array+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Array+Extensions.swift"; path = "Sources/CryptoSwift/Array+Extensions.swift"; sourceTree = ""; }; + 97073FF2F9CD5B9872A9ECC9FEF7F1D1 /* SHA1.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SHA1.swift; path = Sources/CryptoSwift/SHA1.swift; sourceTree = ""; }; + 979D367046B64E3F4B36289995A2ECA3 /* Int+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Int+Extension.swift"; path = "Sources/CryptoSwift/Int+Extension.swift"; sourceTree = ""; }; + 99E931693897E64B6DCBFA9E371F4462 /* Digest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Digest.swift; path = Sources/CryptoSwift/Digest.swift; sourceTree = ""; }; + 9E07FF1FD31D0F924F415A44F3FD4B17 /* CBC.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CBC.swift; path = Sources/CryptoSwift/BlockMode/CBC.swift; sourceTree = ""; }; + A1373F0E78BDECEA39078CFC65680876 /* Keychain.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Keychain.swift; path = Lib/KeychainAccess/Keychain.swift; sourceTree = ""; }; + A1948ED714A1D42260A1B9FDF4E6C5E5 /* Utils+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Utils+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/Utils+Foundation.swift"; sourceTree = ""; }; + A6AD5A201FC9CC29A7AC7393573AB22B /* BlockModeOptions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BlockModeOptions.swift; path = Sources/CryptoSwift/BlockMode/BlockModeOptions.swift; sourceTree = ""; }; + A779A36DA6B6DA2263224A1C96509266 /* UInt64+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UInt64+Extension.swift"; path = "Sources/CryptoSwift/UInt64+Extension.swift"; sourceTree = ""; }; + AE64D263EC6A70516407A75328DA2ABC /* BatchedCollection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BatchedCollection.swift; path = Sources/CryptoSwift/BatchedCollection.swift; sourceTree = ""; }; + B414586449537501C26A5504271D1C05 /* Poly1305.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Poly1305.swift; path = Sources/CryptoSwift/Poly1305.swift; sourceTree = ""; }; + BA22C2525E89AEF585D429081EE7498E /* CryptoSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = CryptoSwift.modulemap; sourceTree = ""; }; + BE6BD41C35B26AC0B8E61CC549BBC8BB /* String+FoundationExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+FoundationExtension.swift"; path = "Sources/CryptoSwift/Foundation/String+FoundationExtension.swift"; sourceTree = ""; }; + C1F462F1B08124CA39AB1B20611EAB7E /* Pods-Friendvatars-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Friendvatars-frameworks.sh"; sourceTree = ""; }; + C2078CB2A2671FC94EDB53C270D2E455 /* KeychainAccess.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = KeychainAccess.xcconfig; sourceTree = ""; }; + C4F2F6D32AEE751B384F4730346F15DA /* AES+Foundation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "AES+Foundation.swift"; path = "Sources/CryptoSwift/Foundation/AES+Foundation.swift"; sourceTree = ""; }; + D4D46F0CAAE370B836D3A34109465A77 /* Pods-Friendvatars-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Friendvatars-umbrella.h"; sourceTree = ""; }; + D6DFF15000AFE2A371BF499E7AFDA808 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + D9DE1E11183EECCCCB58A2004427BAA0 /* RandomBytesSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RandomBytesSequence.swift; path = Sources/CryptoSwift/RandomBytesSequence.swift; sourceTree = ""; }; + DDF523B86A86A8CF5064567102E5E69F /* KeychainAccess-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "KeychainAccess-prefix.pch"; sourceTree = ""; }; + E0F5B3BD214AC94F881907246D3D8140 /* RandomAccessCryptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RandomAccessCryptor.swift; path = Sources/CryptoSwift/RandomAccessCryptor.swift; sourceTree = ""; }; + E0F6E05FAB446A153EE06855CA85DEBA /* Utils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Utils.swift; path = Sources/CryptoSwift/Utils.swift; sourceTree = ""; }; + E51B68AF254C6AD8A6ACCD9FC50ADE3F /* CFB.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CFB.swift; path = Sources/CryptoSwift/BlockMode/CFB.swift; sourceTree = ""; }; + EC5C14E8DB45F26AD8E5A9826257AF38 /* PBKDF2.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PBKDF2.swift; path = Sources/CryptoSwift/PKCS/PBKDF2.swift; sourceTree = ""; }; + EE3155A4A1AEFD8F6D79D7E9EFE08478 /* UInt32+Extension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UInt32+Extension.swift"; path = "Sources/CryptoSwift/UInt32+Extension.swift"; sourceTree = ""; }; + EE4E900C0626571AC366D9B0092E8CE2 /* Cryptors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Cryptors.swift; path = Sources/CryptoSwift/Cryptors.swift; sourceTree = ""; }; + F0A26E9AE4574ACD9418EC7D7FDB2E42 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F36F2B21056FA24FC41A00B0E7C3608C /* KeychainAccess.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = KeychainAccess.modulemap; sourceTree = ""; }; + F99AC4A7C33349E8C128532FB74A2911 /* CryptoSwift.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = CryptoSwift.xcconfig; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - B78BFDB162C0B5C38B98149696E670D9 /* Frameworks */ = { + 0366D979832FA96B0EBFA8B35C1352E8 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 35C90BEF2F9B2EF2AFF5C902B6D42AF1 /* Foundation.framework in Frameworks */, + 2FB8C4D3042DF4A50C1FF99BD5D6A38F /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - D0A203A87FF7069A35F3AE46AB7618FB /* Frameworks */ = { + 2E560B04A2263EBF6B4B6FDFA42FDA28 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 68DB82CA9203E9108F79F47AED2E8E6A /* Foundation.framework in Frameworks */, + 79FFE636BA8AE65FF53BA916856C69C8 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9A1B5578CFE053DFCDB3D6AF0BCC82B7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 39787DCF5D9423D45E4C5369F0FB53BA /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 2CE31DFE46A71C653D15AA80576DA5BD /* Products */ = { + isa = PBXGroup; + children = ( + 13F5C812210EF5A9F18351D1430B2E39 /* CryptoSwift.framework */, + 040D077AD29E2F782500310CB98114D0 /* KeychainAccess.framework */, + 8D46A86B5A5464BB537E468E9A69DAB1 /* Pods_Friendvatars.framework */, + ); + name = Products; + sourceTree = ""; + }; + 346FEED4B3C8C3AF00A23A2BB750A30A /* Pods-Friendvatars */ = { + isa = PBXGroup; + children = ( + 61DA07AD6BC1B2035B17FA1AC3A7F0FC /* Info.plist */, + 85CAA5FA0A398E9731113F2B60BD4F4F /* Pods-Friendvatars.modulemap */, + 2E50A8BC04995E16B293EF27E1EF7D13 /* Pods-Friendvatars-acknowledgements.markdown */, + 6E475E92B60D094CE1FA6113EBCC2963 /* Pods-Friendvatars-acknowledgements.plist */, + 243C453A941B28D8DC074B9886773BC4 /* Pods-Friendvatars-dummy.m */, + C1F462F1B08124CA39AB1B20611EAB7E /* Pods-Friendvatars-frameworks.sh */, + 5A1961B0A715EA259584BEB18B069B6B /* Pods-Friendvatars-resources.sh */, + D4D46F0CAAE370B836D3A34109465A77 /* Pods-Friendvatars-umbrella.h */, + 35FBA3370551A17B5EC53FF4B5482159 /* Pods-Friendvatars.debug.xcconfig */, + 5692E05105400962A0A6EAC9958B6493 /* Pods-Friendvatars.release.xcconfig */, + ); + name = "Pods-Friendvatars"; + path = "Target Support Files/Pods-Friendvatars"; + sourceTree = ""; + }; + 44D5347904CF754D6785B84253F2574A /* iOS */ = { + isa = PBXGroup; + children = ( + D6DFF15000AFE2A371BF499E7AFDA808 /* Foundation.framework */, + ); + name = iOS; + sourceTree = ""; + }; 7881DE0A5326F42CFB9D7A7A846BA650 /* Targets Support Files */ = { isa = PBXGroup; children = ( - FB5FBB2D6DA41ADB11921F62D92D7238 /* Pods-Friendvatars */, + 346FEED4B3C8C3AF00A23A2BB750A30A /* Pods-Friendvatars */, ); name = "Targets Support Files"; sourceTree = ""; @@ -209,21 +272,113 @@ children = ( 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */, BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */, - E64AF3653C262D78B247B43A1CAE6A30 /* Pods */, - CC7552FB8F3EBB91D9BC133865C8657E /* Products */, + 8A1DE47CA7AF35D8A7616A49B9020C09 /* Pods */, + 2CE31DFE46A71C653D15AA80576DA5BD /* Products */, 7881DE0A5326F42CFB9D7A7A846BA650 /* Targets Support Files */, ); sourceTree = ""; }; - 814D532D2DC4AE90FD27DC40EA98CEC3 /* Support Files */ = { + 8A1DE47CA7AF35D8A7616A49B9020C09 /* Pods */ = { isa = PBXGroup; children = ( - CB3EF8E37892DA1555E52583421106FF /* CryptoSwift.modulemap */, - 958C3E35DD866E890E4BA5EB00450218 /* CryptoSwift.xcconfig */, - 75F7B84503F41364555CFC6945B75C53 /* CryptoSwift-dummy.m */, - 694C4A993EFE74C83AF54A4ECA2F91AA /* CryptoSwift-prefix.pch */, - 31CE01D5451A5240FC1937D0D1073E96 /* CryptoSwift-umbrella.h */, - 5785DF3045F4DCB4D27D3DA7BD4C1579 /* Info.plist */, + 94DC6BECC65956D8125B81448857ACDA /* CryptoSwift */, + A0DB4A9041FFD0F6B4043BB778052B39 /* KeychainAccess */, + ); + name = Pods; + sourceTree = ""; + }; + 94DC6BECC65956D8125B81448857ACDA /* CryptoSwift */ = { + isa = PBXGroup; + children = ( + 33DD58A4FE4A2BD008EE428C51053A03 /* AES.swift */, + C4F2F6D32AEE751B384F4730346F15DA /* AES+Foundation.swift */, + 522FF09BA6EB0EE42AB7B0962DD097F2 /* AES.Cryptors.swift */, + 869C1299FF11A862D35D4E0F9BDDEA98 /* Array+Extension.swift */, + 953F3DF82C04A300C100C78F03A62819 /* Array+Extensions.swift */, + 32CEBC58EA4A2357034EDB9ACF1C74D0 /* Array+Foundation.swift */, + 38A5E783ED32E248C568E3A56D9EF732 /* Authenticator.swift */, + AE64D263EC6A70516407A75328DA2ABC /* BatchedCollection.swift */, + 1F393841799B8CEF8E73B063769C67E7 /* Bit.swift */, + 21F4E25671FA5462E18A72A2088E3679 /* BlockCipher.swift */, + 273AD107D3DCE9B2F5FDD0B6304772B8 /* BlockMode.swift */, + A6AD5A201FC9CC29A7AC7393573AB22B /* BlockModeOptions.swift */, + 76FDAD94210C27931310F31EF70F01FA /* BlockModeWorker.swift */, + 888FFC9B9D087C7D71D00FB4DB0CE591 /* Blowfish.swift */, + 6308BD6BC265D7B0351C546015E4808E /* Blowfish+Foundation.swift */, + 9E07FF1FD31D0F924F415A44F3FD4B17 /* CBC.swift */, + E51B68AF254C6AD8A6ACCD9FC50ADE3F /* CFB.swift */, + 4606993A043F5C0BA70481A2392E966D /* ChaCha20.swift */, + 72A6F75298DE02CCF6A5AD6FA63464F3 /* ChaCha20+Foundation.swift */, + 138EC8D2DA441044B77E97F1B9E111AF /* Checksum.swift */, + 5CBBDEDAE309B6BE53E518555CBABFCF /* Cipher.swift */, + 55EF4E3D2AA6FBB9D1A6415F35E7370B /* Collection+Extension.swift */, + EE4E900C0626571AC366D9B0092E8CE2 /* Cryptors.swift */, + 64CD0C9C7241F26A15C9783D847AFEBD /* CTR.swift */, + 1AF125A30F5AD9E69BA6FFC9277F824B /* Data+Extension.swift */, + 99E931693897E64B6DCBFA9E371F4462 /* Digest.swift */, + 494A68AB67E90B3C19E49251229B3CB4 /* DigestType.swift */, + 6411A22DE7995511193E4C8D65684EB0 /* ECB.swift */, + 28A9F971A39BD5E2D7A1BD47CE909801 /* Generics.swift */, + 9237A63642D9303E14B07FE23802DE78 /* HKDF.swift */, + 49E710C03C6E2E1BC8639661CEBD9FE0 /* HMAC.swift */, + 481C2E1AF54F246301EF5F049557AD55 /* HMAC+Foundation.swift */, + 979D367046B64E3F4B36289995A2ECA3 /* Int+Extension.swift */, + 35D42AE82B529B948EA396E0EFCFBBE2 /* MD5.swift */, + 2353CC599D9B766CB43D57A085D49044 /* NoPadding.swift */, + 108072927D38C61A0B7D2A551D27241C /* OFB.swift */, + 1524BF10BD1056A5EBDE0CFC40B3FB6A /* Operators.swift */, + 0A3DD025F450875EE3390D46E9690E8F /* Padding.swift */, + 0B8080FDAFA546A72CE62CF4236595BD /* PBKDF1.swift */, + EC5C14E8DB45F26AD8E5A9826257AF38 /* PBKDF2.swift */, + 9027941EF37837F538EA200BA4078FAC /* PCBC.swift */, + 8CC087CCDC0B9F6D0D14EB6ECC0F1C3A /* PKCS5.swift */, + 5A59AFF41F06F275C7503386778D8B65 /* PKCS7.swift */, + 0C87CC909DB3EC7C512ED8559264DFF8 /* PKCS7Padding.swift */, + B414586449537501C26A5504271D1C05 /* Poly1305.swift */, + 893EA1F26FBC0EDD4BB740FBF13C8ADC /* Rabbit.swift */, + 47CC1CCF8B4E2A7AF6B5325D050F5427 /* Rabbit+Foundation.swift */, + 79A7E3E41B22DFA5C7ABC3109DAF83E3 /* RandomAccessBlockModeWorker.swift */, + E0F5B3BD214AC94F881907246D3D8140 /* RandomAccessCryptor.swift */, + D9DE1E11183EECCCCB58A2004427BAA0 /* RandomBytesSequence.swift */, + 473C8EDB81BDF1DF3D47F1DB093B4EB9 /* SecureBytes.swift */, + 97073FF2F9CD5B9872A9ECC9FEF7F1D1 /* SHA1.swift */, + 83760D11E74EBD3B2EB24D0F9FF8B3B3 /* SHA2.swift */, + 644E76D60A87D86EF20DD3D9801327F0 /* SHA3.swift */, + 4A8C42D2DD20BA6A96369288B8D61AA7 /* String+Extension.swift */, + BE6BD41C35B26AC0B8E61CC549BBC8BB /* String+FoundationExtension.swift */, + 683220FE8506C6CA2D26A60A58D2E9C3 /* UInt16+Extension.swift */, + EE3155A4A1AEFD8F6D79D7E9EFE08478 /* UInt32+Extension.swift */, + A779A36DA6B6DA2263224A1C96509266 /* UInt64+Extension.swift */, + 161CAB2E0F3185C58480D32D8C1E1B2E /* UInt8+Extension.swift */, + 5678EE6C103997704E23674FBC893360 /* Updatable.swift */, + E0F6E05FAB446A153EE06855CA85DEBA /* Utils.swift */, + A1948ED714A1D42260A1B9FDF4E6C5E5 /* Utils+Foundation.swift */, + 4505CF7E1882B02B054FEE0C70B66D8F /* ZeroPadding.swift */, + B52B518909E4B5FAE142E921148E1B17 /* Support Files */, + ); + name = CryptoSwift; + path = CryptoSwift; + sourceTree = ""; + }; + A0DB4A9041FFD0F6B4043BB778052B39 /* KeychainAccess */ = { + isa = PBXGroup; + children = ( + A1373F0E78BDECEA39078CFC65680876 /* Keychain.swift */, + EA4C15A705072332C3A09B468833C90E /* Support Files */, + ); + name = KeychainAccess; + path = KeychainAccess; + sourceTree = ""; + }; + B52B518909E4B5FAE142E921148E1B17 /* Support Files */ = { + isa = PBXGroup; + children = ( + BA22C2525E89AEF585D429081EE7498E /* CryptoSwift.modulemap */, + F99AC4A7C33349E8C128532FB74A2911 /* CryptoSwift.xcconfig */, + 1CA428AC99ABECD85EF401A66ABC7696 /* CryptoSwift-dummy.m */, + 6F8EB64FA3271693B974155ED31D30C1 /* CryptoSwift-prefix.pch */, + 6D1713133D68D11B16ABA20749418DF7 /* CryptoSwift-umbrella.h */, + 867BB4D83DFD836A4A6AAC72993C8558 /* Info.plist */, ); name = "Support Files"; path = "../Target Support Files/CryptoSwift"; @@ -232,174 +387,81 @@ BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */ = { isa = PBXGroup; children = ( - D35AF013A5F0BAD4F32504907A52519E /* iOS */, + 44D5347904CF754D6785B84253F2574A /* iOS */, ); name = Frameworks; sourceTree = ""; }; - CC7552FB8F3EBB91D9BC133865C8657E /* Products */ = { + EA4C15A705072332C3A09B468833C90E /* Support Files */ = { isa = PBXGroup; children = ( - 517AB0425C00CCB935BD21090EB301BB /* CryptoSwift.framework */, - 25C2A3D020A9CF253BA790C95DE5C85D /* Pods_Friendvatars.framework */, + F0A26E9AE4574ACD9418EC7D7FDB2E42 /* Info.plist */, + F36F2B21056FA24FC41A00B0E7C3608C /* KeychainAccess.modulemap */, + C2078CB2A2671FC94EDB53C270D2E455 /* KeychainAccess.xcconfig */, + 85C28A2C77E79D203EEB003E3D3722F3 /* KeychainAccess-dummy.m */, + DDF523B86A86A8CF5064567102E5E69F /* KeychainAccess-prefix.pch */, + 16E72221FAB44B4B748A00FA0F05304C /* KeychainAccess-umbrella.h */, ); - name = Products; - sourceTree = ""; - }; - D35AF013A5F0BAD4F32504907A52519E /* iOS */ = { - isa = PBXGroup; - children = ( - 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */, - ); - name = iOS; - sourceTree = ""; - }; - E64AF3653C262D78B247B43A1CAE6A30 /* Pods */ = { - isa = PBXGroup; - children = ( - F08DAE68C6F8434816F34F54F2B1B3C2 /* CryptoSwift */, - ); - name = Pods; - sourceTree = ""; - }; - F08DAE68C6F8434816F34F54F2B1B3C2 /* CryptoSwift */ = { - isa = PBXGroup; - children = ( - 67A28550EFD88321FB1C5FF15DA5C62D /* AES.swift */, - 4930683B08C33AF0F305F47695EBEA3A /* AES+Foundation.swift */, - 52FF99CDBD8674CE2D14381B432C4E6D /* AES.Cryptors.swift */, - 206294523958ED48244DEB8DCB4CF023 /* Array+Extension.swift */, - 6E483B3851B6079DF39ABBF182139303 /* Array+Extensions.swift */, - 20983313641ED544FC46B0316BF79926 /* Array+Foundation.swift */, - 04EFD937AD6D622C4D5016DC92956436 /* Authenticator.swift */, - 8F42D5916AB8A1FC4FA408997817AE86 /* BatchedCollection.swift */, - 4B7891438183174B010849EE16EC0B68 /* Bit.swift */, - E10424AA36CE05FD512761FFEDCBAF6C /* BlockCipher.swift */, - 3ACA19A307F2B21F931FD6DDF87356D2 /* BlockMode.swift */, - 0B93AADC6BCC5141024213D3D2111DD2 /* BlockModeOptions.swift */, - 0745C4390DFD61D27C2F3499B2F3D2E7 /* BlockModeWorker.swift */, - 5F45932496A1D1AF5A9B5D11AA1B6379 /* Blowfish.swift */, - F81032203334F0F82DE8BAD6CDBDA0E5 /* Blowfish+Foundation.swift */, - F0A770514358B491E856A8C73934B0E7 /* CBC.swift */, - A6D0B6BA8036ED273D9027F2C740F1A5 /* CFB.swift */, - 474F2FD4F2E5FCF33A3C2B10229F55E2 /* ChaCha20.swift */, - F0D87F44520FD278A8382D8DDBCA119C /* ChaCha20+Foundation.swift */, - 20673D47BADAAE371A6D1D4AB2C079D5 /* Checksum.swift */, - 0D5417AD168033723D327DBF2B77B2F3 /* Cipher.swift */, - 17AF38AABF71297F2FE6B5CD5375A2EA /* Collection+Extension.swift */, - 1C93EBBCC4BE9F5C1F1EED483E76929A /* Cryptors.swift */, - C4CC36BFD1E124638BBE348967908C6A /* CTR.swift */, - BA5DD41E358E01C837004B16A0212C24 /* Data+Extension.swift */, - 7A313DC180F5A42AFDCF5F4D9E6B0E3E /* Digest.swift */, - 116BE809A8BBF8F709926DDC28236638 /* DigestType.swift */, - 6A8F5DD177A733404CDE172BCFE6DEDC /* ECB.swift */, - E723BB881B28C7F2E108E93FEBE1A46C /* Generics.swift */, - 05AAD9CD5929ABE280DF39FDA2D57A3D /* HKDF.swift */, - 5406734B12796208095D0CB213BBEAD8 /* HMAC.swift */, - E06127188259CDD74B9E186703788F84 /* HMAC+Foundation.swift */, - 191FCA13BFC587807608EE78E641B78D /* Int+Extension.swift */, - 97497923A52857052C39C3C1F5384057 /* MD5.swift */, - 17EB19E1EF889F2602A6CD4BFA3B9610 /* NoPadding.swift */, - 9605A1A7D44A6AFA150179262A998D31 /* OFB.swift */, - 9D4CA579D6B6E98CEE82B19109E58815 /* Operators.swift */, - 4591ED7D4B6A682FD57C96167D225BD7 /* Padding.swift */, - 9913797121D44D906414A1F51BA3AF4F /* PBKDF1.swift */, - 74184CDFE882702363A6B155483AD804 /* PBKDF2.swift */, - 6BC5E9FDC0794915C037F7D0B9A92655 /* PCBC.swift */, - FF4FDD82CE4B9195C6D126CCCE57090E /* PKCS5.swift */, - A1B0228ADBEA7D5A1E0FACD4C7C07E15 /* PKCS7.swift */, - 193F3BAC26CCDDE2D5AD828DD924C805 /* PKCS7Padding.swift */, - BFF8297B20577E1B5B1EDF1DE71AAEAC /* Poly1305.swift */, - 603C9968D4F76B3C922BCB6AD6BBCE4B /* Rabbit.swift */, - 75638B1B53CD11CC43C7F09ADBA88D98 /* Rabbit+Foundation.swift */, - 259F606BDF24A4DDF819F79A4355CE83 /* RandomAccessBlockModeWorker.swift */, - 0B24D0F45827DAE0BC296B7D2ABBEB94 /* RandomAccessCryptor.swift */, - DE3239BE51129F9B1A0D69D90B31A0C1 /* RandomBytesSequence.swift */, - B87549D1373695DA7935EB604B95FB0D /* SecureBytes.swift */, - E923A37930CBC57D57B8A58D34037E06 /* SHA1.swift */, - D048A4807948A5565AA7BFC6EDC8858E /* SHA2.swift */, - D034CF51EE8F6519BB0FE897047E1CD8 /* SHA3.swift */, - 4E5B910E685A01D78A440C32F40D1F80 /* String+Extension.swift */, - 9B9C9576330A2201FA5FA2A66FC0596D /* String+FoundationExtension.swift */, - EAF4F14E3B549084EED6396285CD9C4A /* UInt16+Extension.swift */, - 0EBFAE3C75105602890BD9A047D689EC /* UInt32+Extension.swift */, - 20E52385C4802542C0CA766B3F129C20 /* UInt64+Extension.swift */, - C4F9E69F3EC6CC5A1B9811A830EDA7FB /* UInt8+Extension.swift */, - 5CBF814346C0E5BFDE8D4559FE6294F6 /* Updatable.swift */, - E236D7F3DE185A040EA09B9BFC56188E /* Utils.swift */, - B9FEC5C85271D8F16DFD9D29CD4175FB /* Utils+Foundation.swift */, - 71E3DED970010B6C6E14D42D39702D05 /* ZeroPadding.swift */, - 814D532D2DC4AE90FD27DC40EA98CEC3 /* Support Files */, - ); - name = CryptoSwift; - path = CryptoSwift; - sourceTree = ""; - }; - FB5FBB2D6DA41ADB11921F62D92D7238 /* Pods-Friendvatars */ = { - isa = PBXGroup; - children = ( - 744ED72F2ADD9975CADAC93B3E5CC907 /* Info.plist */, - 559DA49EAEB2B41A456CC65EC9E40676 /* Pods-Friendvatars.modulemap */, - CC86EB5C74C82E488D2A3E273D65E6EA /* Pods-Friendvatars-acknowledgements.markdown */, - 303F88462BBA275BDCE3E6F3562217CF /* Pods-Friendvatars-acknowledgements.plist */, - 853933329993C6F99DEF07589D2E4F88 /* Pods-Friendvatars-dummy.m */, - C517BCD0B8B6D37A4814132B34868A28 /* Pods-Friendvatars-frameworks.sh */, - 764482285D9CADC5E9B6B4AF0E0B4B39 /* Pods-Friendvatars-resources.sh */, - F90EE9B48157BDCBAE77E93C7A59E50B /* Pods-Friendvatars-umbrella.h */, - 097F053EAB3A78D608DA971D6D318270 /* Pods-Friendvatars.debug.xcconfig */, - 07F9C623D91918F13560D807485D5154 /* Pods-Friendvatars.release.xcconfig */, - ); - name = "Pods-Friendvatars"; - path = "Target Support Files/Pods-Friendvatars"; + name = "Support Files"; + path = "../Target Support Files/KeychainAccess"; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 3D6B1AE04675FB5C72A1A4168A3C2DA2 /* Headers */ = { + 0F87EB7BEAF7F467DDF34216A73857F1 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 9985EDF7C8CA28B64DFC22F3716C59C5 /* Pods-Friendvatars-umbrella.h in Headers */, + F3D08773F50E664E51661FCF4274403A /* Pods-Friendvatars-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4520A9B79F1A370E217D57A302CC1981 /* Headers */ = { + 3B1DDCF02DAE623B025E4E7CF019C8D9 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 74DE9C0DBED7C14ED409BFAA17158E73 /* CryptoSwift-umbrella.h in Headers */, + 9CC85DD5BB289CB4F6C01E7952E23CE6 /* CryptoSwift-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3DCB50E1EAE76A10559C48D06F53E0EE /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4565031E0304574C7A466B62E73E7478 /* KeychainAccess-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - D975CEC661E2DCD4108AD5E2C0572CC0 /* Pods-Friendvatars */ = { + 1630C0AC0CCE2704C3F517D1DFD56586 /* KeychainAccess */ = { isa = PBXNativeTarget; - buildConfigurationList = C7F52FD6C19C202D3233FF9CF94E0737 /* Build configuration list for PBXNativeTarget "Pods-Friendvatars" */; + buildConfigurationList = 4BC26EB508840B6B2446C27E690E60BC /* Build configuration list for PBXNativeTarget "KeychainAccess" */; buildPhases = ( - C6F1EAA0FB22589AB1354D0A389468F8 /* Sources */, - D0A203A87FF7069A35F3AE46AB7618FB /* Frameworks */, - 3D6B1AE04675FB5C72A1A4168A3C2DA2 /* Headers */, + 3DCB50E1EAE76A10559C48D06F53E0EE /* Headers */, + 6CF23713FC2035F5BD9D246E95236685 /* Sources */, + 0366D979832FA96B0EBFA8B35C1352E8 /* Frameworks */, + 82731D02B1DBAC326E46F5E6E83C1130 /* Resources */, ); buildRules = ( ); dependencies = ( - 3DAFE240C6ED1B623256A9D4FFC83BBE /* PBXTargetDependency */, ); - name = "Pods-Friendvatars"; - productName = "Pods-Friendvatars"; - productReference = 25C2A3D020A9CF253BA790C95DE5C85D /* Pods_Friendvatars.framework */; + name = KeychainAccess; + productName = KeychainAccess; + productReference = 040D077AD29E2F782500310CB98114D0 /* KeychainAccess.framework */; productType = "com.apple.product-type.framework"; }; - DE16D66575B4E29D54F3F5DB5CD606FB /* CryptoSwift */ = { + 16F79934C9B37C10283012C65CA992AB /* CryptoSwift */ = { isa = PBXNativeTarget; - buildConfigurationList = A2A1FC75CCCDCE10818AD7D9284ED293 /* Build configuration list for PBXNativeTarget "CryptoSwift" */; + buildConfigurationList = C5F1ED38B025B97D267FF462BB6FE9E4 /* Build configuration list for PBXNativeTarget "CryptoSwift" */; buildPhases = ( - D3781A86E789739B2F1EE90C420EAA11 /* Sources */, - B78BFDB162C0B5C38B98149696E670D9 /* Frameworks */, - 4520A9B79F1A370E217D57A302CC1981 /* Headers */, + 3B1DDCF02DAE623B025E4E7CF019C8D9 /* Headers */, + 2CE5BF9CBDE68CA05100B3AAACB20E44 /* Sources */, + 2E560B04A2263EBF6B4B6FDFA42FDA28 /* Frameworks */, + DA116F18320293844F239536899BB655 /* Resources */, ); buildRules = ( ); @@ -407,7 +469,27 @@ ); name = CryptoSwift; productName = CryptoSwift; - productReference = 517AB0425C00CCB935BD21090EB301BB /* CryptoSwift.framework */; + productReference = 13F5C812210EF5A9F18351D1430B2E39 /* CryptoSwift.framework */; + productType = "com.apple.product-type.framework"; + }; + 93927B2E03466C85C8B18A3BA96CAE46 /* Pods-Friendvatars */ = { + isa = PBXNativeTarget; + buildConfigurationList = 55768D7603E0ABAF7186C5391B70871A /* Build configuration list for PBXNativeTarget "Pods-Friendvatars" */; + buildPhases = ( + 0F87EB7BEAF7F467DDF34216A73857F1 /* Headers */, + 72C9D05C29DF4E7FF7661D46D83CA6F1 /* Sources */, + 9A1B5578CFE053DFCDB3D6AF0BCC82B7 /* Frameworks */, + 7AC29ADD4C6B639AA52273376658A16F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 73E88593784AE5C82210F2FFCD7D11C3 /* PBXTargetDependency */, + 5FD94ABB484E82B54643238DEEFF037E /* PBXTargetDependency */, + ); + name = "Pods-Friendvatars"; + productName = "Pods-Friendvatars"; + productReference = 8D46A86B5A5464BB537E468E9A69DAB1 /* Pods_Friendvatars.framework */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ @@ -416,8 +498,8 @@ D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 0830; - LastUpgradeCheck = 0700; + LastSwiftUpdateCheck = 0930; + LastUpgradeCheck = 0930; }; buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; compatibilityVersion = "Xcode 3.2"; @@ -427,113 +509,186 @@ en, ); mainGroup = 7DB346D0F39D3F0E887471402A8071AB; - productRefGroup = CC7552FB8F3EBB91D9BC133865C8657E /* Products */; + productRefGroup = 2CE31DFE46A71C653D15AA80576DA5BD /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - DE16D66575B4E29D54F3F5DB5CD606FB /* CryptoSwift */, - D975CEC661E2DCD4108AD5E2C0572CC0 /* Pods-Friendvatars */, + 16F79934C9B37C10283012C65CA992AB /* CryptoSwift */, + 1630C0AC0CCE2704C3F517D1DFD56586 /* KeychainAccess */, + 93927B2E03466C85C8B18A3BA96CAE46 /* Pods-Friendvatars */, ); }; /* End PBXProject section */ -/* Begin PBXSourcesBuildPhase section */ - C6F1EAA0FB22589AB1354D0A389468F8 /* Sources */ = { - isa = PBXSourcesBuildPhase; +/* Begin PBXResourcesBuildPhase section */ + 7AC29ADD4C6B639AA52273376658A16F /* Resources */ = { + isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - CABB4A3C203CD9D6721E52111BDB6A89 /* Pods-Friendvatars-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - D3781A86E789739B2F1EE90C420EAA11 /* Sources */ = { + 82731D02B1DBAC326E46F5E6E83C1130 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DA116F18320293844F239536899BB655 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 2CE5BF9CBDE68CA05100B3AAACB20E44 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 3703B6E48C92A9CA9485B91125942BA9 /* AES+Foundation.swift in Sources */, - 87FAA6BD98D8B8712821DB532CDFF447 /* AES.Cryptors.swift in Sources */, - E99E9C0D8889E1ABED1BB66EA5E26F6B /* AES.swift in Sources */, - BD7F3C923AC47D15F51AD07D359BBDA4 /* Array+Extension.swift in Sources */, - 338E92A59022E6035872D94CB3AA57BF /* Array+Extensions.swift in Sources */, - 1BCBD814F3A819CFEDD5B621CD6BC6E0 /* Array+Foundation.swift in Sources */, - 32508A477EB8DE4F4EA066315511C4EF /* Authenticator.swift in Sources */, - 473DABC63FCEDEAC6C02E4AFE687DB31 /* BatchedCollection.swift in Sources */, - 3DC2810AEA96A3728F4BF638C0371E8A /* Bit.swift in Sources */, - 69086E943FDA1EF21D24289B1D5C60D2 /* BlockCipher.swift in Sources */, - 94DA4265D2AF0A4CA879A7F6D5B5A820 /* BlockMode.swift in Sources */, - E9DDCBC12D0C48E9072371632E2EE354 /* BlockModeOptions.swift in Sources */, - 934B3EA778B62DB2D5D8F0B02777E3F5 /* BlockModeWorker.swift in Sources */, - CA44F79721F689C434DEFA89D31ECD53 /* Blowfish+Foundation.swift in Sources */, - 65D826FD61BD6BD47FECFFA148216844 /* Blowfish.swift in Sources */, - 7073740DBB60483C88302F708F2F0039 /* CBC.swift in Sources */, - 960978CE23EE23DC0AF7E5954D6CB2A3 /* CFB.swift in Sources */, - 3EB15695F4BE7EBCE4ABF6B31BA04CA9 /* ChaCha20+Foundation.swift in Sources */, - 80763ECA711BA3777C09B81B21E288C8 /* ChaCha20.swift in Sources */, - 6C715228EFC892AD90E07CE6517BC9D4 /* Checksum.swift in Sources */, - FFEFA357A2ECFD2C8696A7D9B6559CAC /* Cipher.swift in Sources */, - 97B2B4AFFA86BA7E0F85F53DC0F0B466 /* Collection+Extension.swift in Sources */, - A300671F55DD95AE86819358B2C6DE32 /* Cryptors.swift in Sources */, - 7E38C53CC00067C7A5FA953B9261BF29 /* CryptoSwift-dummy.m in Sources */, - 790B502A5E39B63AB1CD72638362BDDD /* CTR.swift in Sources */, - D0CC6EF77721FDC29F558F2B6ACEEDCF /* Data+Extension.swift in Sources */, - 1C9A485DA2FE04B657D7E3D8D0FF17AB /* Digest.swift in Sources */, - CAA3F0F3507AB5798B490B49D95E3809 /* DigestType.swift in Sources */, - 49C6022FFB654F025AE6247765EFD40C /* ECB.swift in Sources */, - 48E770EAFA3730666D434C9AC7E48496 /* Generics.swift in Sources */, - 494751D9321DF2E06F6FAF41A6017E7F /* HKDF.swift in Sources */, - C953641D50BEADDEC1E341FE87247AF8 /* HMAC+Foundation.swift in Sources */, - 848B237EB31C02719899A90111FB08DA /* HMAC.swift in Sources */, - 69E4627B6E2338D2F586FA167CDC6E95 /* Int+Extension.swift in Sources */, - EEBE924BD06D6681AAA6003C3A6DBB33 /* MD5.swift in Sources */, - 152BA68678A9161227766CE6A75C19D4 /* NoPadding.swift in Sources */, - E780BDD3E588068FF869701FDC2D6BBE /* OFB.swift in Sources */, - D7CA1999F4D69F97C9042949C5E02286 /* Operators.swift in Sources */, - 85F41150DC5EA8413BEE3F2608F11991 /* Padding.swift in Sources */, - CBBE1B5655CD83A70E2856B7D33D3103 /* PBKDF1.swift in Sources */, - E039B801D197986FE25FD3011D2A324D /* PBKDF2.swift in Sources */, - 7DF98DF4ECF09A73ABE5B1092628461F /* PCBC.swift in Sources */, - 44751BA17838B5BDE6AA88A7D19CDC35 /* PKCS5.swift in Sources */, - 7C4FE99E01C8A635B3CE77F05B74B2DA /* PKCS7.swift in Sources */, - EEC95E134BF6663B52A72D8B53375C00 /* PKCS7Padding.swift in Sources */, - 3C8A5FD4672DBB6ED5B8E8FBC12C633D /* Poly1305.swift in Sources */, - 779811AAB014C57EAB3A43BB83A42F9E /* Rabbit+Foundation.swift in Sources */, - C745A2AA05FA14326388532157D59FD2 /* Rabbit.swift in Sources */, - 08C450BB03BE7BFD888431D1751132F8 /* RandomAccessBlockModeWorker.swift in Sources */, - 7C93878B47BE664097F3A63B89D1A862 /* RandomAccessCryptor.swift in Sources */, - DBBC0B3E2A77C465F817B4CB91C7CA6E /* RandomBytesSequence.swift in Sources */, - 5E77A3F633DBBD4C39776F6744EDC308 /* SecureBytes.swift in Sources */, - 04ED4CBE1683A039945AE21E71657DCE /* SHA1.swift in Sources */, - 8E9D8397BA554CE359B42FBAE1BCBD08 /* SHA2.swift in Sources */, - 6F5501B927A46CCF4F52A4CD7C1E33EC /* SHA3.swift in Sources */, - EC44355442C7E895D8BDD437C8FC1A50 /* String+Extension.swift in Sources */, - 395968454CBE736B64F63A633E0B68E4 /* String+FoundationExtension.swift in Sources */, - 3D87B3B0FD6435BB315EFC905422302C /* UInt16+Extension.swift in Sources */, - B856B5034004C190E8B2B8A2F038527D /* UInt32+Extension.swift in Sources */, - 8131E626B940699512588EDA2CAEBD34 /* UInt64+Extension.swift in Sources */, - 19F209E95649F61A5101303CA297098B /* UInt8+Extension.swift in Sources */, - B90AA1D193D9DA983C60B24EB3B5A189 /* Updatable.swift in Sources */, - 1D0578185B1E764BC61EC316C3D29B02 /* Utils+Foundation.swift in Sources */, - B2F16B6F4D5D5944929BF9B416772565 /* Utils.swift in Sources */, - CD11E1CA4EC90EB672AB603B3BD82EAE /* ZeroPadding.swift in Sources */, + ED9945DDBD34C37E6A9F4A6FD7A0178A /* AES+Foundation.swift in Sources */, + D9F8C56F455EA541B961F6AD650E3AA2 /* AES.Cryptors.swift in Sources */, + D1953BAD6AD8DFD90F296DCC7E8A5ED7 /* AES.swift in Sources */, + F27539EDE127CBB68FF6DF65ACB38D9A /* Array+Extension.swift in Sources */, + 528D7571D85151FF800C4E3654E1FA86 /* Array+Extensions.swift in Sources */, + 9F80EAE2671115979B9F2BA5A17C04E9 /* Array+Foundation.swift in Sources */, + 8E8BA6D0A85A8D3FBC55D447ACF7C156 /* Authenticator.swift in Sources */, + 9233A3E22B89BD228FBB3F1DDEEC4EFE /* BatchedCollection.swift in Sources */, + 6DD366D4D2E525C12528BE966B822B05 /* Bit.swift in Sources */, + 360667D5B252324DEA6B75898D382381 /* BlockCipher.swift in Sources */, + 0CD5836CA8A6C1C7C38E51F95B0EC027 /* BlockMode.swift in Sources */, + 77055ACA57CE4A39671C183CB60EBCF2 /* BlockModeOptions.swift in Sources */, + 3FCC64403F8DE2D2B3BAE71F3F0CC1C7 /* BlockModeWorker.swift in Sources */, + DB8DEC0D10D2DFD5D9A22F679911FCF9 /* Blowfish+Foundation.swift in Sources */, + 0FE198D97026CEA7FED2C43521BB9501 /* Blowfish.swift in Sources */, + C7AE9D99B081CD446727F3E8B32317C4 /* CBC.swift in Sources */, + 029CCDE6075BC29CE715C255CF60EBED /* CFB.swift in Sources */, + 78B30076720C6EC70BDCB49DD3A25BC0 /* ChaCha20+Foundation.swift in Sources */, + 270B917A023E92844CFDFBE7E44797D1 /* ChaCha20.swift in Sources */, + 9782A81566BFFA815BD6FEEB13D54D06 /* Checksum.swift in Sources */, + CCF37A73A04567CD14F94798DB2D4C76 /* Cipher.swift in Sources */, + 4C024CC2A1003237347D216A03A5878C /* Collection+Extension.swift in Sources */, + 2672625ED4BD11DB4DD83A4E9BDDF6F9 /* Cryptors.swift in Sources */, + 0D11FC42AE9E341FE113D5FAEEED8C04 /* CryptoSwift-dummy.m in Sources */, + 11DA82F1D104F6DBA7592F3F9F53AACB /* CTR.swift in Sources */, + 5B5E80A7A1AD0C13169BDDAECA394073 /* Data+Extension.swift in Sources */, + C668F20671BE60B79CF7B9D1C3791E35 /* Digest.swift in Sources */, + 4544D85EA993B42F5915E7AA8F4C0F6C /* DigestType.swift in Sources */, + EA96722B1A22E50779569D6FB1B2C24A /* ECB.swift in Sources */, + AAD7BE5314AC1DB28A194D05CA74D9D7 /* Generics.swift in Sources */, + A7DF73F094D79EA40BC71350652C400C /* HKDF.swift in Sources */, + 4AB554DF0F4CFA6D8E14FB06A95385D8 /* HMAC+Foundation.swift in Sources */, + B29D6D60FCCD5C636F33D5CAAA6BF2BB /* HMAC.swift in Sources */, + AF55FD642987DCEAAE9795808F6267BD /* Int+Extension.swift in Sources */, + 41642560CA055E8EE8FCA2DCA5313C23 /* MD5.swift in Sources */, + B6F9DC89BB62F23C6384F6E26ECBD4A9 /* NoPadding.swift in Sources */, + 9EF595A91415241CCB3320594B53F282 /* OFB.swift in Sources */, + C3232F5FF289636B5085FBD43D5AE6FD /* Operators.swift in Sources */, + CC59CFB29942D3024B21409F183A41F1 /* Padding.swift in Sources */, + 4B3B8AEAD3654C79DD2984A29DACE5B9 /* PBKDF1.swift in Sources */, + CE4A24B14EE10DF8E29E27D17F5FA5DD /* PBKDF2.swift in Sources */, + D4D811091053D1871366EC650281DC15 /* PCBC.swift in Sources */, + F01FB4F122B343BE13963EB262255675 /* PKCS5.swift in Sources */, + 6BA9D56D4651F39C19833F1F409D4178 /* PKCS7.swift in Sources */, + 63A2B87CCC493F65ACEE0001E5CB2B19 /* PKCS7Padding.swift in Sources */, + 96704219B31375941271FF02AAC8193C /* Poly1305.swift in Sources */, + 21CE5B0F01F8E58E9EABCA1B6ED154BA /* Rabbit+Foundation.swift in Sources */, + C992CCAE597216BDCDFE491223C06BE1 /* Rabbit.swift in Sources */, + 0CB63DF68E61516B91FDCDCBE4519EFC /* RandomAccessBlockModeWorker.swift in Sources */, + 645C52C486190C3F39E6D434FACECECD /* RandomAccessCryptor.swift in Sources */, + C1BEDEA59E2E6D70D341E609CAC35E71 /* RandomBytesSequence.swift in Sources */, + 18C1AA22F5B3651F114294733FDF5B2A /* SecureBytes.swift in Sources */, + E5E39AA990B1E34C79CFE8F90E6AFA97 /* SHA1.swift in Sources */, + 0956811701EC202F2F69628EDCBB9EFD /* SHA2.swift in Sources */, + A73F91DACC3AB17F91D968B03A6FFF33 /* SHA3.swift in Sources */, + 2BF51761B945E33FA10C59EA934B8088 /* String+Extension.swift in Sources */, + 29EF96F51B6027797F0760320DCA6BD5 /* String+FoundationExtension.swift in Sources */, + 7CBB1492A9E2DD4F5DFC1BA7A95D3344 /* UInt16+Extension.swift in Sources */, + B0300AF42EB5F8D38F9EA98E95C696E1 /* UInt32+Extension.swift in Sources */, + 95C37DDA83D94B3B59A40A3426A65684 /* UInt64+Extension.swift in Sources */, + 09873F77E269091531A2000295876ED3 /* UInt8+Extension.swift in Sources */, + 9EE4737714DE0CDBCC66384EA4982AD8 /* Updatable.swift in Sources */, + 8723CA06E8722D3594EAA1A139A6D803 /* Utils+Foundation.swift in Sources */, + C0313257B3F8482EAFE428726FD845D9 /* Utils.swift in Sources */, + BEE403F4842EC4C88A514E7374E8B417 /* ZeroPadding.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6CF23713FC2035F5BD9D246E95236685 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A8FC628BC39A85B021B33CD0EDF94E06 /* Keychain.swift in Sources */, + 7FD1C9171DE80CDCBE2C974D9EE0991A /* KeychainAccess-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 72C9D05C29DF4E7FF7661D46D83CA6F1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4881DAE730C3678FEA94F8A2622252C1 /* Pods-Friendvatars-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 3DAFE240C6ED1B623256A9D4FFC83BBE /* PBXTargetDependency */ = { + 5FD94ABB484E82B54643238DEEFF037E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = KeychainAccess; + target = 1630C0AC0CCE2704C3F517D1DFD56586 /* KeychainAccess */; + targetProxy = 12182EA804E368C696A82EA3D0847BB0 /* PBXContainerItemProxy */; + }; + 73E88593784AE5C82210F2FFCD7D11C3 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = CryptoSwift; - target = DE16D66575B4E29D54F3F5DB5CD606FB /* CryptoSwift */; - targetProxy = FC21C348DB5F26AD02A6B216B82EFEF5 /* PBXContainerItemProxy */; + target = 16F79934C9B37C10283012C65CA992AB /* CryptoSwift */; + targetProxy = 4E4D75D7D535AA2262C115253513E932 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 017E033AE3B882C8F1B1B33FDC2041BA /* Release */ = { + 33085B251B90A9185BB0694E05E90DC0 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 07F9C623D91918F13560D807485D5154 /* Pods-Friendvatars.release.xcconfig */; + baseConfigurationReference = F99AC4A7C33349E8C128532FB74A2911 /* CryptoSwift.xcconfig */; buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CryptoSwift/CryptoSwift-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CryptoSwift/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/CryptoSwift/CryptoSwift.modulemap"; + PRODUCT_MODULE_NAME = CryptoSwift; + PRODUCT_NAME = CryptoSwift; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 478A30F15DB5B2AAE0B1427A0EC08EC8 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 35FBA3370551A17B5EC53FF4B5482159 /* Pods-Friendvatars.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -553,115 +708,16 @@ OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = Pods_Friendvatars; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - 1EC6E80B3F946C3B0B2629BBD4A56103 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 958C3E35DD866E890E4BA5EB00450218 /* CryptoSwift.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/CryptoSwift/CryptoSwift-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/CryptoSwift/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/CryptoSwift/CryptoSwift.modulemap"; - PRODUCT_NAME = CryptoSwift; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; - 2C2593E9D2A040F577AC26A8D58D678F /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 097F053EAB3A78D608DA971D6D318270 /* Pods-Friendvatars.debug.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-Friendvatars/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-Friendvatars/Pods-Friendvatars.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = Pods_Friendvatars; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 34AAD49A66933A8C44FFF8FF0FD3E041 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 958C3E35DD866E890E4BA5EB00450218 /* CryptoSwift.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/CryptoSwift/CryptoSwift-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/CryptoSwift/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/CryptoSwift/CryptoSwift.modulemap"; - PRODUCT_NAME = CryptoSwift; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - B254DAA6CF0CE39F4A3D11B90A7E059A /* Release */ = { + 85B95B1234E227C814CCC2C7902D0916 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -671,10 +727,12 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = 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_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -682,6 +740,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -690,6 +749,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGNING_ALLOWED = NO; CODE_SIGNING_REQUIRED = NO; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -709,14 +769,17 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; STRIP_INSTALLED_PRODUCT = NO; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 4.2; SYMROOT = "${SRCROOT}/../build"; }; name = Release; }; - E4B68EE12B21C47CB798D9B1ECA6D7A7 /* Debug */ = { + A73625DEBD810B78234FA1958C191C8C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -726,10 +789,12 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = 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_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -737,6 +802,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -745,6 +811,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGNING_ALLOWED = NO; CODE_SIGNING_REQUIRED = NO; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; @@ -766,42 +833,181 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; STRIP_INSTALLED_PRODUCT = NO; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; SYMROOT = "${SRCROOT}/../build"; }; name = Debug; }; + AA98FBE85C02FF3E1D4C48A3800D69B6 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C2078CB2A2671FC94EDB53C270D2E455 /* KeychainAccess.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/KeychainAccess/KeychainAccess-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/KeychainAccess/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/KeychainAccess/KeychainAccess.modulemap"; + PRODUCT_MODULE_NAME = KeychainAccess; + PRODUCT_NAME = KeychainAccess; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + BACDEA29CF12AB67C1BCC44F9DC639EF /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5692E05105400962A0A6EAC9958B6493 /* Pods-Friendvatars.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-Friendvatars/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-Friendvatars/Pods-Friendvatars.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + BE86D9D7117C944B124740F8E60E620F /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F99AC4A7C33349E8C128532FB74A2911 /* CryptoSwift.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/CryptoSwift/CryptoSwift-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/CryptoSwift/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/CryptoSwift/CryptoSwift.modulemap"; + PRODUCT_MODULE_NAME = CryptoSwift; + PRODUCT_NAME = CryptoSwift; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + FE7F9698AABDE060F38D8CE93838F298 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C2078CB2A2671FC94EDB53C270D2E455 /* KeychainAccess.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/KeychainAccess/KeychainAccess-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/KeychainAccess/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/KeychainAccess/KeychainAccess.modulemap"; + PRODUCT_MODULE_NAME = KeychainAccess; + PRODUCT_NAME = KeychainAccess; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { isa = XCConfigurationList; buildConfigurations = ( - E4B68EE12B21C47CB798D9B1ECA6D7A7 /* Debug */, - B254DAA6CF0CE39F4A3D11B90A7E059A /* Release */, + A73625DEBD810B78234FA1958C191C8C /* Debug */, + 85B95B1234E227C814CCC2C7902D0916 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - A2A1FC75CCCDCE10818AD7D9284ED293 /* Build configuration list for PBXNativeTarget "CryptoSwift" */ = { + 4BC26EB508840B6B2446C27E690E60BC /* Build configuration list for PBXNativeTarget "KeychainAccess" */ = { isa = XCConfigurationList; buildConfigurations = ( - 1EC6E80B3F946C3B0B2629BBD4A56103 /* Debug */, - 34AAD49A66933A8C44FFF8FF0FD3E041 /* Release */, + FE7F9698AABDE060F38D8CE93838F298 /* Debug */, + AA98FBE85C02FF3E1D4C48A3800D69B6 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C7F52FD6C19C202D3233FF9CF94E0737 /* Build configuration list for PBXNativeTarget "Pods-Friendvatars" */ = { + 55768D7603E0ABAF7186C5391B70871A /* Build configuration list for PBXNativeTarget "Pods-Friendvatars" */ = { isa = XCConfigurationList; buildConfigurations = ( - 2C2593E9D2A040F577AC26A8D58D678F /* Debug */, - 017E033AE3B882C8F1B1B33FDC2041BA /* Release */, + 478A30F15DB5B2AAE0B1427A0EC08EC8 /* Debug */, + BACDEA29CF12AB67C1BCC44F9DC639EF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C5F1ED38B025B97D267FF462BB6FE9E4 /* Build configuration list for PBXNativeTarget "CryptoSwift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BE86D9D7117C944B124740F8E60E620F /* Debug */, + 33085B251B90A9185BB0694E05E90DC0 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Pods/Pods.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/CryptoSwift.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/CryptoSwift.xcscheme new file mode 100644 index 0000000..86dd710 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/CryptoSwift.xcscheme @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/KeychainAccess.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/KeychainAccess.xcscheme new file mode 100644 index 0000000..3ea002b --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/KeychainAccess.xcscheme @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/Pods-Friendvatars.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/Pods-Friendvatars.xcscheme new file mode 100644 index 0000000..1db4055 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/Pods-Friendvatars.xcscheme @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/xcschememanagement.plist b/Pods/Pods.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/xcschememanagement.plist index 9c3e97b..046160e 100644 --- a/Pods/Pods.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Pods/Pods.xcodeproj/xcuserdata/dawidkubicki.xcuserdatad/xcschemes/xcschememanagement.plist @@ -4,16 +4,33 @@ SchemeUserState + CryptoSwift.xcscheme + + isShown + + CryptoSwift.xcscheme_^#shared#^_ orderHint - 1 + 0 + + KeychainAccess.xcscheme + + isShown + + + Pods-Friendvatars.xcscheme + + isShown + Pods-Friendvatars.xcscheme_^#shared#^_ orderHint - 2 + 1 + SuppressBuildableAutocreation + diff --git a/Pods/Target Support Files/CryptoSwift/CryptoSwift.xcconfig b/Pods/Target Support Files/CryptoSwift/CryptoSwift.xcconfig index 834a282..d6712ca 100644 --- a/Pods/Target Support Files/CryptoSwift/CryptoSwift.xcconfig +++ b/Pods/Target Support Files/CryptoSwift/CryptoSwift.xcconfig @@ -1,10 +1,9 @@ -CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/CryptoSwift +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 GCC_UNROLL_LOOPS = YES -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" -PODS_BUILD_DIR = $BUILD_DIR -PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/CryptoSwift PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} diff --git a/Pods/Target Support Files/KeychainAccess/Info.plist b/Pods/Target Support Files/KeychainAccess/Info.plist new file mode 100644 index 0000000..c11c2ee --- /dev/null +++ b/Pods/Target Support Files/KeychainAccess/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 3.1.2 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/KeychainAccess/KeychainAccess-dummy.m b/Pods/Target Support Files/KeychainAccess/KeychainAccess-dummy.m new file mode 100644 index 0000000..b1cd3bf --- /dev/null +++ b/Pods/Target Support Files/KeychainAccess/KeychainAccess-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_KeychainAccess : NSObject +@end +@implementation PodsDummy_KeychainAccess +@end diff --git a/Pods/Target Support Files/KeychainAccess/KeychainAccess-prefix.pch b/Pods/Target Support Files/KeychainAccess/KeychainAccess-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/Pods/Target Support Files/KeychainAccess/KeychainAccess-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/KeychainAccess/KeychainAccess-umbrella.h b/Pods/Target Support Files/KeychainAccess/KeychainAccess-umbrella.h new file mode 100644 index 0000000..62ce5de --- /dev/null +++ b/Pods/Target Support Files/KeychainAccess/KeychainAccess-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double KeychainAccessVersionNumber; +FOUNDATION_EXPORT const unsigned char KeychainAccessVersionString[]; + diff --git a/Pods/Target Support Files/KeychainAccess/KeychainAccess.modulemap b/Pods/Target Support Files/KeychainAccess/KeychainAccess.modulemap new file mode 100644 index 0000000..f26e6b1 --- /dev/null +++ b/Pods/Target Support Files/KeychainAccess/KeychainAccess.modulemap @@ -0,0 +1,6 @@ +framework module KeychainAccess { + umbrella header "KeychainAccess-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/KeychainAccess/KeychainAccess.xcconfig b/Pods/Target Support Files/KeychainAccess/KeychainAccess.xcconfig new file mode 100644 index 0000000..89b05e1 --- /dev/null +++ b/Pods/Target Support Files/KeychainAccess/KeychainAccess.xcconfig @@ -0,0 +1,9 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/KeychainAccess +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/KeychainAccess +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES diff --git a/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars-acknowledgements.markdown b/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars-acknowledgements.markdown index 01dfca5..25216f9 100644 --- a/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars-acknowledgements.markdown +++ b/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars-acknowledgements.markdown @@ -14,4 +14,30 @@ Permission is granted to anyone to use this software for any purpose,including c - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. - This notice may not be removed or altered from any source or binary distribution. + +## KeychainAccess + +The MIT License (MIT) + +Copyright (c) 2014 kishikawa katsumi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars-acknowledgements.plist b/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars-acknowledgements.plist index dfba6dc..30bcb6e 100644 --- a/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars-acknowledgements.plist +++ b/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars-acknowledgements.plist @@ -32,6 +32,38 @@ Permission is granted to anyone to use this software for any purpose,including c Type PSGroupSpecifier + + FooterText + The MIT License (MIT) + +Copyright (c) 2014 kishikawa katsumi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + + License + MIT + Title + KeychainAccess + Type + PSGroupSpecifier + FooterText Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars-frameworks.sh b/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars-frameworks.sh index 63e9b9c..b95484d 100755 --- a/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars-frameworks.sh +++ b/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars-frameworks.sh @@ -1,15 +1,28 @@ #!/bin/sh set -e +set -u +set -o pipefail + +if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then + # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy + # frameworks to, so exit 0 (signalling the script phase was successful). + exit 0 +fi echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 + # This protects against multiple targets copying the same framework dependency at the same time. The solution # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") +# Copies and strips a vendored framework install_framework() { if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then @@ -58,21 +71,40 @@ install_framework() fi } -# Copies the dSYM of a vendored framework +# Copies and strips a vendored dSYM install_dsym() { local source="$1" if [ -r "$source" ]; then - echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DWARF_DSYM_FOLDER_PATH}\"" - rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DWARF_DSYM_FOLDER_PATH}" + # Copy the dSYM into a the targets temp dir. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" + + local basename + basename="$(basename -s .framework.dSYM "$source")" + binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then + strip_invalid_archs "$binary" + fi + + if [[ $STRIP_BINARY_RETVAL == 1 ]]; then + # Move the stripped file into its final destination. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + else + # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" + fi fi } # Signs a framework with the provided identity code_sign_if_enabled() { - if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then # Use the current code_sign_identitiy echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" - local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then code_sign_cmd="$code_sign_cmd &" @@ -85,10 +117,18 @@ code_sign_if_enabled() { # Strip invalid architectures strip_invalid_archs() { binary="$1" - # Get architectures for current file - archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" + # Get architectures for current target binary + binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" + # Intersect them with the architectures we are building for + intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" + # If there are no archs supported by this binary then warn the user + if [[ -z "$intersected_archs" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + STRIP_BINARY_RETVAL=0 + return + fi stripped="" - for arch in $archs; do + for arch in $binary_archs; do if ! [[ "${ARCHS}" == *"$arch"* ]]; then # Strip non-valid architectures in-place lipo -remove "$arch" -output "$binary" "$binary" || exit 1 @@ -98,14 +138,17 @@ strip_invalid_archs() { if [[ "$stripped" ]]; then echo "Stripped $binary of architectures:$stripped" fi + STRIP_BINARY_RETVAL=1 } if [[ "$CONFIGURATION" == "Debug" ]]; then install_framework "${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework" + install_framework "${BUILT_PRODUCTS_DIR}/KeychainAccess/KeychainAccess.framework" fi if [[ "$CONFIGURATION" == "Release" ]]; then install_framework "${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework" + install_framework "${BUILT_PRODUCTS_DIR}/KeychainAccess/KeychainAccess.framework" fi if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then wait diff --git a/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars-resources.sh b/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars-resources.sh index a7df440..345301f 100755 --- a/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars-resources.sh +++ b/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars-resources.sh @@ -1,5 +1,13 @@ #!/bin/sh set -e +set -u +set -o pipefail + +if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then + # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy + # resources to, so exit 0 (signalling the script phase was successful). + exit 0 +fi mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" @@ -12,7 +20,7 @@ XCASSET_FILES=() # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") -case "${TARGETED_DEVICE_FAMILY}" in +case "${TARGETED_DEVICE_FAMILY:-}" in 1,2) TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" ;; @@ -92,7 +100,7 @@ if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then fi rm -f "$RESOURCES_TO_COPY" -if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] then # Find all other xcassets (this unfortunately includes those of path pods and other targets). OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) @@ -102,5 +110,9 @@ then fi done <<<"$OTHER_XCASSETS" - printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then + printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + else + printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" + fi fi diff --git a/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars.debug.xcconfig b/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars.debug.xcconfig index e3fff9c..43d4a07 100644 --- a/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars.debug.xcconfig +++ b/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars.debug.xcconfig @@ -1,11 +1,11 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES -FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/CryptoSwift" +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/KeychainAccess" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' -OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/CryptoSwift/CryptoSwift.framework/Headers" -OTHER_LDFLAGS = $(inherited) -framework "CryptoSwift" +OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/KeychainAccess/KeychainAccess.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "CryptoSwift" -framework "KeychainAccess" OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" -PODS_BUILD_DIR = $BUILD_DIR -PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods diff --git a/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars.release.xcconfig b/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars.release.xcconfig index e3fff9c..43d4a07 100644 --- a/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars.release.xcconfig +++ b/Pods/Target Support Files/Pods-Friendvatars/Pods-Friendvatars.release.xcconfig @@ -1,11 +1,11 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES -FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/CryptoSwift" +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift" "${PODS_CONFIGURATION_BUILD_DIR}/KeychainAccess" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' -OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/CryptoSwift/CryptoSwift.framework/Headers" -OTHER_LDFLAGS = $(inherited) -framework "CryptoSwift" +OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/KeychainAccess/KeychainAccess.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "CryptoSwift" -framework "KeychainAccess" OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" -PODS_BUILD_DIR = $BUILD_DIR -PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods