Keychain.swift 121 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074
  1. //
  2. // Keychain.swift
  3. // KeychainAccess
  4. //
  5. // Created by kishikawa katsumi on 2014/12/24.
  6. // Copyright (c) 2014 kishikawa katsumi. All rights reserved.
  7. //
  8. // Permission is hereby granted, free of charge, to any person obtaining a copy
  9. // of this software and associated documentation files (the "Software"), to deal
  10. // in the Software without restriction, including without limitation the rights
  11. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. // copies of the Software, and to permit persons to whom the Software is
  13. // furnished to do so, subject to the following conditions:
  14. //
  15. // The above copyright notice and this permission notice shall be included in
  16. // all copies or substantial portions of the Software.
  17. //
  18. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. // THE SOFTWARE.
  25. import Foundation
  26. import Security
  27. #if os(iOS) || os(OSX)
  28. import LocalAuthentication
  29. #endif
  30. public let KeychainAccessErrorDomain = "com.kishikawakatsumi.KeychainAccess.error"
  31. public enum ItemClass {
  32. case genericPassword
  33. case internetPassword
  34. }
  35. public enum ProtocolType {
  36. case ftp
  37. case ftpAccount
  38. case http
  39. case irc
  40. case nntp
  41. case pop3
  42. case smtp
  43. case socks
  44. case imap
  45. case ldap
  46. case appleTalk
  47. case afp
  48. case telnet
  49. case ssh
  50. case ftps
  51. case https
  52. case httpProxy
  53. case httpsProxy
  54. case ftpProxy
  55. case smb
  56. case rtsp
  57. case rtspProxy
  58. case daap
  59. case eppc
  60. case ipp
  61. case nntps
  62. case ldaps
  63. case telnetS
  64. case imaps
  65. case ircs
  66. case pop3S
  67. }
  68. public enum AuthenticationType {
  69. case ntlm
  70. case msn
  71. case dpa
  72. case rpa
  73. case httpBasic
  74. case httpDigest
  75. case htmlForm
  76. case `default`
  77. }
  78. public enum Accessibility {
  79. /**
  80. Item data can only be accessed
  81. while the device is unlocked. This is recommended for items that only
  82. need be accesible while the application is in the foreground. Items
  83. with this attribute will migrate to a new device when using encrypted
  84. backups.
  85. */
  86. case whenUnlocked
  87. /**
  88. Item data can only be
  89. accessed once the device has been unlocked after a restart. This is
  90. recommended for items that need to be accesible by background
  91. applications. Items with this attribute will migrate to a new device
  92. when using encrypted backups.
  93. */
  94. case afterFirstUnlock
  95. /**
  96. Item data can always be accessed
  97. regardless of the lock state of the device. This is not recommended
  98. for anything except system use. Items with this attribute will migrate
  99. to a new device when using encrypted backups.
  100. */
  101. @available(macCatalyst, unavailable)
  102. case always
  103. /**
  104. Item data can
  105. only be accessed while the device is unlocked. This class is only
  106. available if a passcode is set on the device. This is recommended for
  107. items that only need to be accessible while the application is in the
  108. foreground. Items with this attribute will never migrate to a new
  109. device, so after a backup is restored to a new device, these items
  110. will be missing. No items can be stored in this class on devices
  111. without a passcode. Disabling the device passcode will cause all
  112. items in this class to be deleted.
  113. */
  114. @available(iOS 8.0, OSX 10.10, *)
  115. case whenPasscodeSetThisDeviceOnly
  116. /**
  117. Item data can only
  118. be accessed while the device is unlocked. This is recommended for items
  119. that only need be accesible while the application is in the foreground.
  120. Items with this attribute will never migrate to a new device, so after
  121. a backup is restored to a new device, these items will be missing.
  122. */
  123. case whenUnlockedThisDeviceOnly
  124. /**
  125. Item data can
  126. only be accessed once the device has been unlocked after a restart.
  127. This is recommended for items that need to be accessible by background
  128. applications. Items with this attribute will never migrate to a new
  129. device, so after a backup is restored to a new device these items will
  130. be missing.
  131. */
  132. case afterFirstUnlockThisDeviceOnly
  133. /**
  134. Item data can always
  135. be accessed regardless of the lock state of the device. This option
  136. is not recommended for anything except system use. Items with this
  137. attribute will never migrate to a new device, so after a backup is
  138. restored to a new device, these items will be missing.
  139. */
  140. @available(macCatalyst, unavailable)
  141. case alwaysThisDeviceOnly
  142. }
  143. /**
  144. Predefined item attribute constants used to get or set values
  145. in a dictionary. The kSecUseAuthenticationUI constant is the key and its
  146. value is one of the constants defined here.
  147. If the key kSecUseAuthenticationUI not provided then kSecUseAuthenticationUIAllow
  148. is used as default.
  149. */
  150. public enum AuthenticationUI {
  151. /**
  152. Specifies that authenticate UI can appear.
  153. */
  154. case allow
  155. /**
  156. Specifies that the error
  157. errSecInteractionNotAllowed will be returned if an item needs
  158. to authenticate with UI
  159. */
  160. case fail
  161. /**
  162. Specifies that all items which need
  163. to authenticate with UI will be silently skipped. This value can be used
  164. only with SecItemCopyMatching.
  165. */
  166. case skip
  167. }
  168. @available(iOS 9.0, OSX 10.11, *)
  169. extension AuthenticationUI {
  170. public var rawValue: String {
  171. switch self {
  172. case .allow:
  173. return UseAuthenticationUIAllow
  174. case .fail:
  175. return UseAuthenticationUIFail
  176. case .skip:
  177. return UseAuthenticationUISkip
  178. }
  179. }
  180. public var description: String {
  181. switch self {
  182. case .allow:
  183. return "allow"
  184. case .fail:
  185. return "fail"
  186. case .skip:
  187. return "skip"
  188. }
  189. }
  190. }
  191. public struct AuthenticationPolicy: OptionSet {
  192. /**
  193. User presence policy using Touch ID or Passcode. Touch ID does not
  194. have to be available or enrolled. Item is still accessible by Touch ID
  195. even if fingers are added or removed.
  196. */
  197. @available(iOS 8.0, OSX 10.10, watchOS 2.0, tvOS 8.0, *)
  198. public static let userPresence = AuthenticationPolicy(rawValue: 1 << 0)
  199. /**
  200. Constraint: Touch ID (any finger) or Face ID. Touch ID or Face ID must be available. With Touch ID
  201. at least one finger must be enrolled. With Face ID user has to be enrolled. Item is still accessible by Touch ID even
  202. if fingers are added or removed. Item is still accessible by Face ID if user is re-enrolled.
  203. */
  204. @available(iOS 11.3, OSX 10.13.4, watchOS 4.3, tvOS 11.3, *)
  205. public static let biometryAny = AuthenticationPolicy(rawValue: 1 << 1)
  206. /**
  207. Deprecated, please use biometryAny instead.
  208. */
  209. @available(iOS, introduced: 9.0, deprecated: 11.3, renamed: "biometryAny")
  210. @available(OSX, introduced: 10.12.1, deprecated: 10.13.4, renamed: "biometryAny")
  211. @available(watchOS, introduced: 2.0, deprecated: 4.3, renamed: "biometryAny")
  212. @available(tvOS, introduced: 9.0, deprecated: 11.3, renamed: "biometryAny")
  213. public static let touchIDAny = AuthenticationPolicy(rawValue: 1 << 1)
  214. /**
  215. Constraint: Touch ID from the set of currently enrolled fingers. Touch ID must be available and at least one finger must
  216. be enrolled. When fingers are added or removed, the item is invalidated. When Face ID is re-enrolled this item is invalidated.
  217. */
  218. @available(iOS 11.3, OSX 10.13, watchOS 4.3, tvOS 11.3, *)
  219. public static let biometryCurrentSet = AuthenticationPolicy(rawValue: 1 << 3)
  220. /**
  221. Deprecated, please use biometryCurrentSet instead.
  222. */
  223. @available(iOS, introduced: 9.0, deprecated: 11.3, renamed: "biometryCurrentSet")
  224. @available(OSX, introduced: 10.12.1, deprecated: 10.13.4, renamed: "biometryCurrentSet")
  225. @available(watchOS, introduced: 2.0, deprecated: 4.3, renamed: "biometryCurrentSet")
  226. @available(tvOS, introduced: 9.0, deprecated: 11.3, renamed: "biometryCurrentSet")
  227. public static let touchIDCurrentSet = AuthenticationPolicy(rawValue: 1 << 3)
  228. /**
  229. Constraint: Device passcode
  230. */
  231. @available(iOS 9.0, OSX 10.11, watchOS 2.0, tvOS 9.0, *)
  232. public static let devicePasscode = AuthenticationPolicy(rawValue: 1 << 4)
  233. /**
  234. Constraint: Watch
  235. */
  236. @available(iOS, unavailable)
  237. @available(OSX 10.15, *)
  238. @available(watchOS, unavailable)
  239. @available(tvOS, unavailable)
  240. public static let watch = AuthenticationPolicy(rawValue: 1 << 5)
  241. /**
  242. Constraint logic operation: when using more than one constraint,
  243. at least one of them must be satisfied.
  244. */
  245. @available(iOS 9.0, OSX 10.12.1, watchOS 2.0, tvOS 9.0, *)
  246. public static let or = AuthenticationPolicy(rawValue: 1 << 14)
  247. /**
  248. Constraint logic operation: when using more than one constraint,
  249. all must be satisfied.
  250. */
  251. @available(iOS 9.0, OSX 10.12.1, watchOS 2.0, tvOS 9.0, *)
  252. public static let and = AuthenticationPolicy(rawValue: 1 << 15)
  253. /**
  254. Create access control for private key operations (i.e. sign operation)
  255. */
  256. @available(iOS 9.0, OSX 10.12.1, watchOS 2.0, tvOS 9.0, *)
  257. public static let privateKeyUsage = AuthenticationPolicy(rawValue: 1 << 30)
  258. /**
  259. Security: Application provided password for data encryption key generation.
  260. This is not a constraint but additional item encryption mechanism.
  261. */
  262. @available(iOS 9.0, OSX 10.12.1, watchOS 2.0, tvOS 9.0, *)
  263. public static let applicationPassword = AuthenticationPolicy(rawValue: 1 << 31)
  264. #if swift(>=2.3)
  265. public let rawValue: UInt
  266. public init(rawValue: UInt) {
  267. self.rawValue = rawValue
  268. }
  269. #else
  270. public let rawValue: Int
  271. public init(rawValue: Int) {
  272. self.rawValue = rawValue
  273. }
  274. #endif
  275. }
  276. public struct Attributes {
  277. public var `class`: String? {
  278. return attributes[Class] as? String
  279. }
  280. public var data: Data? {
  281. return attributes[ValueData] as? Data
  282. }
  283. public var ref: Data? {
  284. return attributes[ValueRef] as? Data
  285. }
  286. public var persistentRef: Data? {
  287. return attributes[ValuePersistentRef] as? Data
  288. }
  289. public var accessible: String? {
  290. return attributes[AttributeAccessible] as? String
  291. }
  292. public var accessControl: SecAccessControl? {
  293. if #available(OSX 10.10, *) {
  294. if let accessControl = attributes[AttributeAccessControl] {
  295. return (accessControl as! SecAccessControl)
  296. }
  297. return nil
  298. } else {
  299. return nil
  300. }
  301. }
  302. public var accessGroup: String? {
  303. return attributes[AttributeAccessGroup] as? String
  304. }
  305. public var synchronizable: Bool? {
  306. return attributes[AttributeSynchronizable] as? Bool
  307. }
  308. public var creationDate: Date? {
  309. return attributes[AttributeCreationDate] as? Date
  310. }
  311. public var modificationDate: Date? {
  312. return attributes[AttributeModificationDate] as? Date
  313. }
  314. public var attributeDescription: String? {
  315. return attributes[AttributeDescription] as? String
  316. }
  317. public var comment: String? {
  318. return attributes[AttributeComment] as? String
  319. }
  320. public var creator: String? {
  321. return attributes[AttributeCreator] as? String
  322. }
  323. public var type: String? {
  324. return attributes[AttributeType] as? String
  325. }
  326. public var label: String? {
  327. return attributes[AttributeLabel] as? String
  328. }
  329. public var isInvisible: Bool? {
  330. return attributes[AttributeIsInvisible] as? Bool
  331. }
  332. public var isNegative: Bool? {
  333. return attributes[AttributeIsNegative] as? Bool
  334. }
  335. public var account: String? {
  336. return attributes[AttributeAccount] as? String
  337. }
  338. public var service: String? {
  339. return attributes[AttributeService] as? String
  340. }
  341. public var generic: Data? {
  342. return attributes[AttributeGeneric] as? Data
  343. }
  344. public var securityDomain: String? {
  345. return attributes[AttributeSecurityDomain] as? String
  346. }
  347. public var server: String? {
  348. return attributes[AttributeServer] as? String
  349. }
  350. public var `protocol`: String? {
  351. return attributes[AttributeProtocol] as? String
  352. }
  353. public var authenticationType: String? {
  354. return attributes[AttributeAuthenticationType] as? String
  355. }
  356. public var port: Int? {
  357. return attributes[AttributePort] as? Int
  358. }
  359. public var path: String? {
  360. return attributes[AttributePath] as? String
  361. }
  362. fileprivate let attributes: [String: Any]
  363. init(attributes: [String: Any]) {
  364. self.attributes = attributes
  365. }
  366. public subscript(key: String) -> Any? {
  367. get {
  368. return attributes[key]
  369. }
  370. }
  371. }
  372. public final class Keychain {
  373. public var itemClass: ItemClass {
  374. return options.itemClass
  375. }
  376. public var service: String {
  377. return options.service
  378. }
  379. // This attribute (kSecAttrAccessGroup) applies to macOS keychain items only if you also set a value of true for the
  380. // kSecUseDataProtectionKeychain key, the kSecAttrSynchronizable key, or both.
  381. public var accessGroup: String? {
  382. return options.accessGroup
  383. }
  384. public var server: URL {
  385. return options.server
  386. }
  387. public var protocolType: ProtocolType {
  388. return options.protocolType
  389. }
  390. public var authenticationType: AuthenticationType {
  391. return options.authenticationType
  392. }
  393. public var accessibility: Accessibility {
  394. return options.accessibility
  395. }
  396. @available(iOS 8.0, OSX 10.10, *)
  397. @available(watchOS, unavailable)
  398. public var authenticationPolicy: AuthenticationPolicy? {
  399. return options.authenticationPolicy
  400. }
  401. public var synchronizable: Bool {
  402. return options.synchronizable
  403. }
  404. public var label: String? {
  405. return options.label
  406. }
  407. public var comment: String? {
  408. return options.comment
  409. }
  410. @available(iOS 8.0, OSX 10.10, *)
  411. @available(watchOS, unavailable)
  412. public var authenticationPrompt: String? {
  413. return options.authenticationPrompt
  414. }
  415. @available(iOS 9.0, OSX 10.11, *)
  416. public var authenticationUI: AuthenticationUI {
  417. return options.authenticationUI ?? .allow
  418. }
  419. #if os(iOS) || os(OSX)
  420. @available(iOS 9.0, OSX 10.11, *)
  421. public var authenticationContext: LAContext? {
  422. return options.authenticationContext as? LAContext
  423. }
  424. #endif
  425. fileprivate let options: Options
  426. // MARK:
  427. public convenience init() {
  428. var options = Options()
  429. if let bundleIdentifier = Bundle.main.bundleIdentifier {
  430. options.service = bundleIdentifier
  431. }
  432. self.init(options)
  433. }
  434. public convenience init(service: String) {
  435. var options = Options()
  436. options.service = service
  437. self.init(options)
  438. }
  439. public convenience init(accessGroup: String) {
  440. var options = Options()
  441. if let bundleIdentifier = Bundle.main.bundleIdentifier {
  442. options.service = bundleIdentifier
  443. }
  444. options.accessGroup = accessGroup
  445. self.init(options)
  446. }
  447. public convenience init(service: String, accessGroup: String) {
  448. var options = Options()
  449. options.service = service
  450. options.accessGroup = accessGroup
  451. self.init(options)
  452. }
  453. public convenience init(server: String, protocolType: ProtocolType, accessGroup: String? = nil, authenticationType: AuthenticationType = .default) {
  454. self.init(server: URL(string: server)!, protocolType: protocolType, accessGroup: accessGroup, authenticationType: authenticationType)
  455. }
  456. public convenience init(server: URL, protocolType: ProtocolType, accessGroup: String? = nil, authenticationType: AuthenticationType = .default) {
  457. var options = Options()
  458. options.itemClass = .internetPassword
  459. options.server = server
  460. options.protocolType = protocolType
  461. options.accessGroup = accessGroup
  462. options.authenticationType = authenticationType
  463. self.init(options)
  464. }
  465. fileprivate init(_ opts: Options) {
  466. options = opts
  467. }
  468. // MARK:
  469. public func accessibility(_ accessibility: Accessibility) -> Keychain {
  470. var options = self.options
  471. options.accessibility = accessibility
  472. return Keychain(options)
  473. }
  474. @available(iOS 8.0, OSX 10.10, *)
  475. @available(watchOS, unavailable)
  476. public func accessibility(_ accessibility: Accessibility, authenticationPolicy: AuthenticationPolicy) -> Keychain {
  477. var options = self.options
  478. options.accessibility = accessibility
  479. options.authenticationPolicy = authenticationPolicy
  480. return Keychain(options)
  481. }
  482. public func synchronizable(_ synchronizable: Bool) -> Keychain {
  483. var options = self.options
  484. options.synchronizable = synchronizable
  485. return Keychain(options)
  486. }
  487. public func label(_ label: String) -> Keychain {
  488. var options = self.options
  489. options.label = label
  490. return Keychain(options)
  491. }
  492. public func comment(_ comment: String) -> Keychain {
  493. var options = self.options
  494. options.comment = comment
  495. return Keychain(options)
  496. }
  497. public func attributes(_ attributes: [String: Any]) -> Keychain {
  498. var options = self.options
  499. attributes.forEach { options.attributes.updateValue($1, forKey: $0) }
  500. return Keychain(options)
  501. }
  502. @available(iOS 8.0, OSX 10.10, *)
  503. @available(watchOS, unavailable)
  504. public func authenticationPrompt(_ authenticationPrompt: String) -> Keychain {
  505. var options = self.options
  506. options.authenticationPrompt = authenticationPrompt
  507. return Keychain(options)
  508. }
  509. @available(iOS 9.0, OSX 10.11, *)
  510. public func authenticationUI(_ authenticationUI: AuthenticationUI) -> Keychain {
  511. var options = self.options
  512. options.authenticationUI = authenticationUI
  513. return Keychain(options)
  514. }
  515. #if os(iOS) || os(OSX)
  516. @available(iOS 9.0, OSX 10.11, *)
  517. public func authenticationContext(_ authenticationContext: LAContext) -> Keychain {
  518. var options = self.options
  519. options.authenticationContext = authenticationContext
  520. return Keychain(options)
  521. }
  522. #endif
  523. // MARK:
  524. public func get(_ key: String, ignoringAttributeSynchronizable: Bool = true) throws -> String? {
  525. return try getString(key, ignoringAttributeSynchronizable: ignoringAttributeSynchronizable)
  526. }
  527. public func getString(_ key: String, ignoringAttributeSynchronizable: Bool = true) throws -> String? {
  528. guard let data = try getData(key, ignoringAttributeSynchronizable: ignoringAttributeSynchronizable) else {
  529. return nil
  530. }
  531. guard let string = String(data: data, encoding: .utf8) else {
  532. print("failed to convert data to string")
  533. throw Status.conversionError
  534. }
  535. return string
  536. }
  537. public func getData(_ key: String, ignoringAttributeSynchronizable: Bool = true) throws -> Data? {
  538. var query = options.query(ignoringAttributeSynchronizable: ignoringAttributeSynchronizable)
  539. query[MatchLimit] = MatchLimitOne
  540. query[ReturnData] = kCFBooleanTrue
  541. query[AttributeAccount] = key
  542. var result: AnyObject?
  543. let status = SecItemCopyMatching(query as CFDictionary, &result)
  544. switch status {
  545. case errSecSuccess:
  546. guard let data = result as? Data else {
  547. throw Status.unexpectedError
  548. }
  549. return data
  550. case errSecItemNotFound:
  551. return nil
  552. default:
  553. throw securityError(status: status)
  554. }
  555. }
  556. public func get<T>(_ key: String, ignoringAttributeSynchronizable: Bool = true, handler: (Attributes?) -> T) throws -> T {
  557. var query = options.query(ignoringAttributeSynchronizable: ignoringAttributeSynchronizable)
  558. query[MatchLimit] = MatchLimitOne
  559. query[ReturnData] = kCFBooleanTrue
  560. query[ReturnAttributes] = kCFBooleanTrue
  561. query[ReturnRef] = kCFBooleanTrue
  562. query[ReturnPersistentRef] = kCFBooleanTrue
  563. query[AttributeAccount] = key
  564. var result: AnyObject?
  565. let status = SecItemCopyMatching(query as CFDictionary, &result)
  566. switch status {
  567. case errSecSuccess:
  568. guard let attributes = result as? [String: Any] else {
  569. throw Status.unexpectedError
  570. }
  571. return handler(Attributes(attributes: attributes))
  572. case errSecItemNotFound:
  573. return handler(nil)
  574. default:
  575. throw securityError(status: status)
  576. }
  577. }
  578. // MARK:
  579. public func set(_ value: String, key: String, ignoringAttributeSynchronizable: Bool = true) throws {
  580. guard let data = value.data(using: .utf8, allowLossyConversion: false) else {
  581. print("failed to convert string to data")
  582. throw Status.conversionError
  583. }
  584. try set(data, key: key, ignoringAttributeSynchronizable: ignoringAttributeSynchronizable)
  585. }
  586. public func set(_ value: Data, key: String, ignoringAttributeSynchronizable: Bool = true) throws {
  587. var query = options.query(ignoringAttributeSynchronizable: ignoringAttributeSynchronizable)
  588. query[AttributeAccount] = key
  589. #if os(iOS)
  590. if #available(iOS 9.0, *) {
  591. if let authenticationUI = options.authenticationUI {
  592. query[UseAuthenticationUI] = authenticationUI.rawValue
  593. } else {
  594. query[UseAuthenticationUI] = UseAuthenticationUIFail
  595. }
  596. } else {
  597. query[UseNoAuthenticationUI] = kCFBooleanTrue
  598. }
  599. #elseif os(OSX)
  600. query[ReturnData] = kCFBooleanTrue
  601. if #available(OSX 10.11, *) {
  602. if let authenticationUI = options.authenticationUI {
  603. query[UseAuthenticationUI] = authenticationUI.rawValue
  604. } else {
  605. query[UseAuthenticationUI] = UseAuthenticationUIFail
  606. }
  607. }
  608. #else
  609. if let authenticationUI = options.authenticationUI {
  610. query[UseAuthenticationUI] = authenticationUI.rawValue
  611. }
  612. #endif
  613. var status = SecItemCopyMatching(query as CFDictionary, nil)
  614. switch status {
  615. case errSecSuccess, errSecInteractionNotAllowed:
  616. var query = options.query()
  617. query[AttributeAccount] = key
  618. var (attributes, error) = options.attributes(key: nil, value: value)
  619. if let error = error {
  620. print(error.localizedDescription)
  621. throw error
  622. }
  623. options.attributes.forEach { attributes.updateValue($1, forKey: $0) }
  624. #if os(iOS)
  625. if status == errSecInteractionNotAllowed && floor(NSFoundationVersionNumber) <= floor(NSFoundationVersionNumber_iOS_8_0) {
  626. try remove(key)
  627. try set(value, key: key)
  628. } else {
  629. status = SecItemUpdate(query as CFDictionary, attributes as CFDictionary)
  630. if status != errSecSuccess {
  631. throw securityError(status: status)
  632. }
  633. }
  634. #else
  635. status = SecItemUpdate(query as CFDictionary, attributes as CFDictionary)
  636. if status != errSecSuccess {
  637. throw securityError(status: status)
  638. }
  639. #endif
  640. case errSecItemNotFound:
  641. var (attributes, error) = options.attributes(key: key, value: value)
  642. if let error = error {
  643. print(error.localizedDescription)
  644. throw error
  645. }
  646. options.attributes.forEach { attributes.updateValue($1, forKey: $0) }
  647. status = SecItemAdd(attributes as CFDictionary, nil)
  648. if status != errSecSuccess {
  649. throw securityError(status: status)
  650. }
  651. default:
  652. throw securityError(status: status)
  653. }
  654. }
  655. public subscript(key: String) -> String? {
  656. get {
  657. #if swift(>=5.0)
  658. return try? get(key)
  659. #else
  660. return (try? get(key)).flatMap { $0 }
  661. #endif
  662. }
  663. set {
  664. if let value = newValue {
  665. do {
  666. try set(value, key: key)
  667. } catch {}
  668. } else {
  669. do {
  670. try remove(key)
  671. } catch {}
  672. }
  673. }
  674. }
  675. public subscript(string key: String) -> String? {
  676. get {
  677. return self[key]
  678. }
  679. set {
  680. self[key] = newValue
  681. }
  682. }
  683. public subscript(data key: String) -> Data? {
  684. get {
  685. #if swift(>=5.0)
  686. return try? getData(key)
  687. #else
  688. return (try? getData(key)).flatMap { $0 }
  689. #endif
  690. }
  691. set {
  692. if let value = newValue {
  693. do {
  694. try set(value, key: key)
  695. } catch {}
  696. } else {
  697. do {
  698. try remove(key)
  699. } catch {}
  700. }
  701. }
  702. }
  703. public subscript(attributes key: String) -> Attributes? {
  704. get {
  705. #if swift(>=5.0)
  706. return try? get(key) { $0 }
  707. #else
  708. return (try? get(key) { $0 }).flatMap { $0 }
  709. #endif
  710. }
  711. }
  712. // MARK:
  713. public func remove(_ key: String, ignoringAttributeSynchronizable: Bool = true) throws {
  714. var query = options.query(ignoringAttributeSynchronizable: ignoringAttributeSynchronizable)
  715. query[AttributeAccount] = key
  716. let status = SecItemDelete(query as CFDictionary)
  717. if status != errSecSuccess && status != errSecItemNotFound {
  718. throw securityError(status: status)
  719. }
  720. }
  721. public func removeAll() throws {
  722. var query = options.query()
  723. #if !os(iOS) && !os(watchOS) && !os(tvOS)
  724. query[MatchLimit] = MatchLimitAll
  725. #endif
  726. let status = SecItemDelete(query as CFDictionary)
  727. if status != errSecSuccess && status != errSecItemNotFound {
  728. throw securityError(status: status)
  729. }
  730. }
  731. // MARK:
  732. public func contains(_ key: String, withoutAuthenticationUI: Bool = false) throws -> Bool {
  733. var query = options.query()
  734. query[AttributeAccount] = key
  735. if withoutAuthenticationUI {
  736. #if os(iOS) || os(watchOS) || os(tvOS)
  737. if #available(iOS 9.0, *) {
  738. if let authenticationUI = options.authenticationUI {
  739. query[UseAuthenticationUI] = authenticationUI.rawValue
  740. } else {
  741. query[UseAuthenticationUI] = UseAuthenticationUIFail
  742. }
  743. } else {
  744. query[UseNoAuthenticationUI] = kCFBooleanTrue
  745. }
  746. #else
  747. if #available(OSX 10.11, *) {
  748. if let authenticationUI = options.authenticationUI {
  749. query[UseAuthenticationUI] = authenticationUI.rawValue
  750. } else {
  751. query[UseAuthenticationUI] = UseAuthenticationUIFail
  752. }
  753. } else if #available(OSX 10.10, *) {
  754. query[UseNoAuthenticationUI] = kCFBooleanTrue
  755. }
  756. #endif
  757. } else {
  758. if #available(iOS 9.0, OSX 10.11, *) {
  759. if let authenticationUI = options.authenticationUI {
  760. query[UseAuthenticationUI] = authenticationUI.rawValue
  761. }
  762. }
  763. }
  764. let status = SecItemCopyMatching(query as CFDictionary, nil)
  765. switch status {
  766. case errSecSuccess:
  767. return true
  768. case errSecInteractionNotAllowed:
  769. if withoutAuthenticationUI {
  770. return true
  771. }
  772. return false
  773. case errSecItemNotFound:
  774. return false
  775. default:
  776. throw securityError(status: status)
  777. }
  778. }
  779. // MARK:
  780. public class func allKeys(_ itemClass: ItemClass) -> [(String, String)] {
  781. var query = [String: Any]()
  782. query[Class] = itemClass.rawValue
  783. query[AttributeSynchronizable] = SynchronizableAny
  784. query[MatchLimit] = MatchLimitAll
  785. query[ReturnAttributes] = kCFBooleanTrue
  786. var result: AnyObject?
  787. let status = SecItemCopyMatching(query as CFDictionary, &result)
  788. switch status {
  789. case errSecSuccess:
  790. if let items = result as? [[String: Any]] {
  791. return prettify(itemClass: itemClass, items: items).map {
  792. switch itemClass {
  793. case .genericPassword:
  794. return (($0["service"] ?? "") as! String, ($0["key"] ?? "") as! String)
  795. case .internetPassword:
  796. return (($0["server"] ?? "") as! String, ($0["key"] ?? "") as! String)
  797. }
  798. }
  799. }
  800. case errSecItemNotFound:
  801. return []
  802. default: ()
  803. }
  804. securityError(status: status)
  805. return []
  806. }
  807. public func allKeys() -> [String] {
  808. let allItems = type(of: self).prettify(itemClass: itemClass, items: items())
  809. let filter: ([String: Any]) -> String? = { $0["key"] as? String }
  810. #if swift(>=4.1)
  811. return allItems.compactMap(filter)
  812. #else
  813. return allItems.flatMap(filter)
  814. #endif
  815. }
  816. public class func allItems(_ itemClass: ItemClass) -> [[String: Any]] {
  817. var query = [String: Any]()
  818. query[Class] = itemClass.rawValue
  819. query[MatchLimit] = MatchLimitAll
  820. query[ReturnAttributes] = kCFBooleanTrue
  821. #if os(iOS) || os(watchOS) || os(tvOS)
  822. query[ReturnData] = kCFBooleanTrue
  823. #endif
  824. var result: AnyObject?
  825. let status = SecItemCopyMatching(query as CFDictionary, &result)
  826. switch status {
  827. case errSecSuccess:
  828. if let items = result as? [[String: Any]] {
  829. return prettify(itemClass: itemClass, items: items)
  830. }
  831. case errSecItemNotFound:
  832. return []
  833. default: ()
  834. }
  835. securityError(status: status)
  836. return []
  837. }
  838. public func allItems() -> [[String: Any]] {
  839. return type(of: self).prettify(itemClass: itemClass, items: items())
  840. }
  841. #if os(iOS) && !targetEnvironment(macCatalyst)
  842. @available(iOS 8.0, *)
  843. public func getSharedPassword(_ completion: @escaping (_ account: String?, _ password: String?, _ error: Error?) -> () = { account, password, error -> () in }) {
  844. if let domain = server.host {
  845. type(of: self).requestSharedWebCredential(domain: domain, account: nil) { (credentials, error) -> () in
  846. if let credential = credentials.first {
  847. let account = credential["account"]
  848. let password = credential["password"]
  849. completion(account, password, error)
  850. } else {
  851. completion(nil, nil, error)
  852. }
  853. }
  854. } else {
  855. let error = securityError(status: Status.param.rawValue)
  856. completion(nil, nil, error)
  857. }
  858. }
  859. #endif
  860. #if os(iOS) && !targetEnvironment(macCatalyst)
  861. @available(iOS 8.0, *)
  862. public func getSharedPassword(_ account: String, completion: @escaping (_ password: String?, _ error: Error?) -> () = { password, error -> () in }) {
  863. if let domain = server.host {
  864. type(of: self).requestSharedWebCredential(domain: domain, account: account) { (credentials, error) -> () in
  865. if let credential = credentials.first {
  866. if let password = credential["password"] {
  867. completion(password, error)
  868. } else {
  869. completion(nil, error)
  870. }
  871. } else {
  872. completion(nil, error)
  873. }
  874. }
  875. } else {
  876. let error = securityError(status: Status.param.rawValue)
  877. completion(nil, error)
  878. }
  879. }
  880. #endif
  881. #if os(iOS) && !targetEnvironment(macCatalyst)
  882. @available(iOS 8.0, *)
  883. public func setSharedPassword(_ password: String, account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in }) {
  884. setSharedPassword(password as String?, account: account, completion: completion)
  885. }
  886. #endif
  887. #if os(iOS) && !targetEnvironment(macCatalyst)
  888. @available(iOS 8.0, *)
  889. fileprivate func setSharedPassword(_ password: String?, account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in }) {
  890. if let domain = server.host {
  891. SecAddSharedWebCredential(domain as CFString, account as CFString, password as CFString?) { error -> () in
  892. if let error = error {
  893. completion(error.error)
  894. } else {
  895. completion(nil)
  896. }
  897. }
  898. } else {
  899. let error = securityError(status: Status.param.rawValue)
  900. completion(error)
  901. }
  902. }
  903. #endif
  904. #if os(iOS) && !targetEnvironment(macCatalyst)
  905. @available(iOS 8.0, *)
  906. public func removeSharedPassword(_ account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in }) {
  907. setSharedPassword(nil, account: account, completion: completion)
  908. }
  909. #endif
  910. #if os(iOS) && !targetEnvironment(macCatalyst)
  911. @available(iOS 8.0, *)
  912. public class func requestSharedWebCredential(_ completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in }) {
  913. requestSharedWebCredential(domain: nil, account: nil, completion: completion)
  914. }
  915. #endif
  916. #if os(iOS) && !targetEnvironment(macCatalyst)
  917. @available(iOS 8.0, *)
  918. public class func requestSharedWebCredential(domain: String, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in }) {
  919. requestSharedWebCredential(domain: domain, account: nil, completion: completion)
  920. }
  921. #endif
  922. #if os(iOS) && !targetEnvironment(macCatalyst)
  923. @available(iOS 8.0, *)
  924. public class func requestSharedWebCredential(domain: String, account: String, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in }) {
  925. requestSharedWebCredential(domain: Optional(domain), account: Optional(account)!, completion: completion)
  926. }
  927. #endif
  928. #if os(iOS) && !targetEnvironment(macCatalyst)
  929. @available(iOS 8.0, *)
  930. fileprivate class func requestSharedWebCredential(domain: String?, account: String?, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> ()) {
  931. SecRequestSharedWebCredential(domain as CFString?, account as CFString?) { (credentials, error) -> () in
  932. var remoteError: NSError?
  933. if let error = error {
  934. remoteError = error.error
  935. if remoteError?.code != Int(errSecItemNotFound) {
  936. print("error:[\(remoteError!.code)] \(remoteError!.localizedDescription)")
  937. }
  938. }
  939. if let credentials = credentials {
  940. let credentials = (credentials as NSArray).map { credentials -> [String: String] in
  941. var credential = [String: String]()
  942. if let credentials = credentials as? [String: String] {
  943. if let server = credentials[AttributeServer] {
  944. credential["server"] = server
  945. }
  946. if let account = credentials[AttributeAccount] {
  947. credential["account"] = account
  948. }
  949. if let password = credentials[SharedPassword] {
  950. credential["password"] = password
  951. }
  952. }
  953. return credential
  954. }
  955. completion(credentials, remoteError)
  956. } else {
  957. completion([], remoteError)
  958. }
  959. }
  960. }
  961. #endif
  962. #if os(iOS) && !targetEnvironment(macCatalyst)
  963. /**
  964. @abstract Returns a randomly generated password.
  965. @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.
  966. */
  967. @available(iOS 8.0, *)
  968. public class func generatePassword() -> String {
  969. return SecCreateSharedWebCredentialPassword()! as String
  970. }
  971. #endif
  972. // MARK:
  973. fileprivate func items() -> [[String: Any]] {
  974. var query = options.query()
  975. query[MatchLimit] = MatchLimitAll
  976. query[ReturnAttributes] = kCFBooleanTrue
  977. #if os(iOS) || os(watchOS) || os(tvOS)
  978. query[ReturnData] = kCFBooleanTrue
  979. #endif
  980. var result: AnyObject?
  981. let status = SecItemCopyMatching(query as CFDictionary, &result)
  982. switch status {
  983. case errSecSuccess:
  984. if let items = result as? [[String: Any]] {
  985. return items
  986. }
  987. case errSecItemNotFound:
  988. return []
  989. default: ()
  990. }
  991. securityError(status: status)
  992. return []
  993. }
  994. fileprivate class func prettify(itemClass: ItemClass, items: [[String: Any]]) -> [[String: Any]] {
  995. let items = items.map { attributes -> [String: Any] in
  996. var item = [String: Any]()
  997. item["class"] = itemClass.description
  998. if let accessGroup = attributes[AttributeAccessGroup] as? String {
  999. item["accessGroup"] = accessGroup
  1000. }
  1001. switch itemClass {
  1002. case .genericPassword:
  1003. if let service = attributes[AttributeService] as? String {
  1004. item["service"] = service
  1005. }
  1006. case .internetPassword:
  1007. if let server = attributes[AttributeServer] as? String {
  1008. item["server"] = server
  1009. }
  1010. if let proto = attributes[AttributeProtocol] as? String {
  1011. if let protocolType = ProtocolType(rawValue: proto) {
  1012. item["protocol"] = protocolType.description
  1013. }
  1014. }
  1015. if let auth = attributes[AttributeAuthenticationType] as? String {
  1016. if let authenticationType = AuthenticationType(rawValue: auth) {
  1017. item["authenticationType"] = authenticationType.description
  1018. }
  1019. }
  1020. }
  1021. if let key = attributes[AttributeAccount] as? String {
  1022. item["key"] = key
  1023. }
  1024. if let data = attributes[ValueData] as? Data {
  1025. if let text = String(data: data, encoding: .utf8) {
  1026. item["value"] = text
  1027. } else {
  1028. item["value"] = data
  1029. }
  1030. }
  1031. if let accessible = attributes[AttributeAccessible] as? String {
  1032. if let accessibility = Accessibility(rawValue: accessible) {
  1033. item["accessibility"] = accessibility.description
  1034. }
  1035. }
  1036. if let synchronizable = attributes[AttributeSynchronizable] as? Bool {
  1037. item["synchronizable"] = synchronizable ? "true" : "false"
  1038. }
  1039. return item
  1040. }
  1041. return items
  1042. }
  1043. // MARK:
  1044. @discardableResult
  1045. fileprivate class func securityError(status: OSStatus) -> Error {
  1046. let error = Status(status: status)
  1047. if error != .userCanceled {
  1048. print("OSStatus error:[\(error.errorCode)] \(error.description)")
  1049. }
  1050. return error
  1051. }
  1052. @discardableResult
  1053. fileprivate func securityError(status: OSStatus) -> Error {
  1054. return type(of: self).securityError(status: status)
  1055. }
  1056. }
  1057. struct Options {
  1058. var itemClass: ItemClass = .genericPassword
  1059. var service: String = ""
  1060. var accessGroup: String? = nil
  1061. var server: URL!
  1062. var protocolType: ProtocolType!
  1063. var authenticationType: AuthenticationType = .default
  1064. var accessibility: Accessibility = .afterFirstUnlock
  1065. var authenticationPolicy: AuthenticationPolicy?
  1066. var synchronizable: Bool = false
  1067. var label: String?
  1068. var comment: String?
  1069. var authenticationPrompt: String?
  1070. var authenticationUI: AuthenticationUI?
  1071. var authenticationContext: AnyObject?
  1072. var attributes = [String: Any]()
  1073. }
  1074. /** Class Key Constant */
  1075. private let Class = String(kSecClass)
  1076. /** Attribute Key Constants */
  1077. private let AttributeAccessible = String(kSecAttrAccessible)
  1078. @available(iOS 8.0, OSX 10.10, *)
  1079. private let AttributeAccessControl = String(kSecAttrAccessControl)
  1080. private let AttributeAccessGroup = String(kSecAttrAccessGroup)
  1081. private let AttributeSynchronizable = String(kSecAttrSynchronizable)
  1082. private let AttributeCreationDate = String(kSecAttrCreationDate)
  1083. private let AttributeModificationDate = String(kSecAttrModificationDate)
  1084. private let AttributeDescription = String(kSecAttrDescription)
  1085. private let AttributeComment = String(kSecAttrComment)
  1086. private let AttributeCreator = String(kSecAttrCreator)
  1087. private let AttributeType = String(kSecAttrType)
  1088. private let AttributeLabel = String(kSecAttrLabel)
  1089. private let AttributeIsInvisible = String(kSecAttrIsInvisible)
  1090. private let AttributeIsNegative = String(kSecAttrIsNegative)
  1091. private let AttributeAccount = String(kSecAttrAccount)
  1092. private let AttributeService = String(kSecAttrService)
  1093. private let AttributeGeneric = String(kSecAttrGeneric)
  1094. private let AttributeSecurityDomain = String(kSecAttrSecurityDomain)
  1095. private let AttributeServer = String(kSecAttrServer)
  1096. private let AttributeProtocol = String(kSecAttrProtocol)
  1097. private let AttributeAuthenticationType = String(kSecAttrAuthenticationType)
  1098. private let AttributePort = String(kSecAttrPort)
  1099. private let AttributePath = String(kSecAttrPath)
  1100. private let SynchronizableAny = kSecAttrSynchronizableAny
  1101. /** Search Constants */
  1102. private let MatchLimit = String(kSecMatchLimit)
  1103. private let MatchLimitOne = kSecMatchLimitOne
  1104. private let MatchLimitAll = kSecMatchLimitAll
  1105. /** Return Type Key Constants */
  1106. private let ReturnData = String(kSecReturnData)
  1107. private let ReturnAttributes = String(kSecReturnAttributes)
  1108. private let ReturnRef = String(kSecReturnRef)
  1109. private let ReturnPersistentRef = String(kSecReturnPersistentRef)
  1110. /** Value Type Key Constants */
  1111. private let ValueData = String(kSecValueData)
  1112. private let ValueRef = String(kSecValueRef)
  1113. private let ValuePersistentRef = String(kSecValuePersistentRef)
  1114. /** Other Constants */
  1115. @available(iOS 8.0, OSX 10.10, tvOS 8.0, *)
  1116. private let UseOperationPrompt = String(kSecUseOperationPrompt)
  1117. @available(iOS, introduced: 8.0, deprecated: 9.0, message: "Use a UseAuthenticationUI instead.")
  1118. @available(OSX, introduced: 10.10, deprecated: 10.11, message: "Use UseAuthenticationUI instead.")
  1119. @available(watchOS, introduced: 2.0, deprecated: 2.0, message: "Use UseAuthenticationUI instead.")
  1120. @available(tvOS, introduced: 8.0, deprecated: 9.0, message: "Use UseAuthenticationUI instead.")
  1121. private let UseNoAuthenticationUI = String(kSecUseNoAuthenticationUI)
  1122. @available(iOS 9.0, OSX 10.11, watchOS 2.0, tvOS 9.0, *)
  1123. private let UseAuthenticationUI = String(kSecUseAuthenticationUI)
  1124. @available(iOS 9.0, OSX 10.11, watchOS 2.0, tvOS 9.0, *)
  1125. private let UseAuthenticationContext = String(kSecUseAuthenticationContext)
  1126. @available(iOS 9.0, OSX 10.11, watchOS 2.0, tvOS 9.0, *)
  1127. private let UseAuthenticationUIAllow = String(kSecUseAuthenticationUIAllow)
  1128. @available(iOS 9.0, OSX 10.11, watchOS 2.0, tvOS 9.0, *)
  1129. private let UseAuthenticationUIFail = String(kSecUseAuthenticationUIFail)
  1130. @available(iOS 9.0, OSX 10.11, watchOS 2.0, tvOS 9.0, *)
  1131. private let UseAuthenticationUISkip = String(kSecUseAuthenticationUISkip)
  1132. #if os(iOS) && !targetEnvironment(macCatalyst)
  1133. /** Credential Key Constants */
  1134. private let SharedPassword = String(kSecSharedPassword)
  1135. #endif
  1136. extension Keychain: CustomStringConvertible, CustomDebugStringConvertible {
  1137. public var description: String {
  1138. let items = allItems()
  1139. if items.isEmpty {
  1140. return "[]"
  1141. }
  1142. var description = "[\n"
  1143. for item in items {
  1144. description += " "
  1145. description += "\(item)\n"
  1146. }
  1147. description += "]"
  1148. return description
  1149. }
  1150. public var debugDescription: String {
  1151. return "\(items())"
  1152. }
  1153. }
  1154. extension Options {
  1155. func query(ignoringAttributeSynchronizable: Bool = true) -> [String: Any] {
  1156. var query = [String: Any]()
  1157. query[Class] = itemClass.rawValue
  1158. if let accessGroup = self.accessGroup {
  1159. query[AttributeAccessGroup] = accessGroup
  1160. }
  1161. if ignoringAttributeSynchronizable {
  1162. query[AttributeSynchronizable] = SynchronizableAny
  1163. } else {
  1164. query[AttributeSynchronizable] = synchronizable ? kCFBooleanTrue : kCFBooleanFalse
  1165. }
  1166. switch itemClass {
  1167. case .genericPassword:
  1168. query[AttributeService] = service
  1169. case .internetPassword:
  1170. query[AttributeServer] = server.host
  1171. query[AttributePort] = server.port
  1172. query[AttributeProtocol] = protocolType.rawValue
  1173. query[AttributeAuthenticationType] = authenticationType.rawValue
  1174. }
  1175. if #available(OSX 10.10, *) {
  1176. if authenticationPrompt != nil {
  1177. query[UseOperationPrompt] = authenticationPrompt
  1178. }
  1179. }
  1180. #if !os(watchOS)
  1181. if #available(iOS 9.0, OSX 10.11, *) {
  1182. if authenticationContext != nil {
  1183. query[UseAuthenticationContext] = authenticationContext
  1184. }
  1185. }
  1186. #endif
  1187. return query
  1188. }
  1189. func attributes(key: String?, value: Data) -> ([String: Any], Error?) {
  1190. var attributes: [String: Any]
  1191. if key != nil {
  1192. attributes = query()
  1193. attributes[AttributeAccount] = key
  1194. } else {
  1195. attributes = [String: Any]()
  1196. }
  1197. attributes[ValueData] = value
  1198. if label != nil {
  1199. attributes[AttributeLabel] = label
  1200. }
  1201. if comment != nil {
  1202. attributes[AttributeComment] = comment
  1203. }
  1204. if let policy = authenticationPolicy {
  1205. if #available(OSX 10.10, *) {
  1206. var error: Unmanaged<CFError>?
  1207. guard let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, SecAccessControlCreateFlags(rawValue: CFOptionFlags(policy.rawValue)), &error) else {
  1208. if let error = error?.takeUnretainedValue() {
  1209. return (attributes, error.error)
  1210. }
  1211. return (attributes, Status.unexpectedError)
  1212. }
  1213. attributes[AttributeAccessControl] = accessControl
  1214. } else {
  1215. print("Unavailable 'Touch ID integration' on OS X versions prior to 10.10.")
  1216. }
  1217. } else {
  1218. attributes[AttributeAccessible] = accessibility.rawValue
  1219. }
  1220. attributes[AttributeSynchronizable] = synchronizable ? kCFBooleanTrue : kCFBooleanFalse
  1221. return (attributes, nil)
  1222. }
  1223. }
  1224. // MARK:
  1225. extension Attributes: CustomStringConvertible, CustomDebugStringConvertible {
  1226. public var description: String {
  1227. return "\(attributes)"
  1228. }
  1229. public var debugDescription: String {
  1230. return description
  1231. }
  1232. }
  1233. extension ItemClass: RawRepresentable, CustomStringConvertible {
  1234. public init?(rawValue: String) {
  1235. switch rawValue {
  1236. case String(kSecClassGenericPassword):
  1237. self = .genericPassword
  1238. case String(kSecClassInternetPassword):
  1239. self = .internetPassword
  1240. default:
  1241. return nil
  1242. }
  1243. }
  1244. public var rawValue: String {
  1245. switch self {
  1246. case .genericPassword:
  1247. return String(kSecClassGenericPassword)
  1248. case .internetPassword:
  1249. return String(kSecClassInternetPassword)
  1250. }
  1251. }
  1252. public var description: String {
  1253. switch self {
  1254. case .genericPassword:
  1255. return "GenericPassword"
  1256. case .internetPassword:
  1257. return "InternetPassword"
  1258. }
  1259. }
  1260. }
  1261. extension ProtocolType: RawRepresentable, CustomStringConvertible {
  1262. public init?(rawValue: String) {
  1263. switch rawValue {
  1264. case String(kSecAttrProtocolFTP):
  1265. self = .ftp
  1266. case String(kSecAttrProtocolFTPAccount):
  1267. self = .ftpAccount
  1268. case String(kSecAttrProtocolHTTP):
  1269. self = .http
  1270. case String(kSecAttrProtocolIRC):
  1271. self = .irc
  1272. case String(kSecAttrProtocolNNTP):
  1273. self = .nntp
  1274. case String(kSecAttrProtocolPOP3):
  1275. self = .pop3
  1276. case String(kSecAttrProtocolSMTP):
  1277. self = .smtp
  1278. case String(kSecAttrProtocolSOCKS):
  1279. self = .socks
  1280. case String(kSecAttrProtocolIMAP):
  1281. self = .imap
  1282. case String(kSecAttrProtocolLDAP):
  1283. self = .ldap
  1284. case String(kSecAttrProtocolAppleTalk):
  1285. self = .appleTalk
  1286. case String(kSecAttrProtocolAFP):
  1287. self = .afp
  1288. case String(kSecAttrProtocolTelnet):
  1289. self = .telnet
  1290. case String(kSecAttrProtocolSSH):
  1291. self = .ssh
  1292. case String(kSecAttrProtocolFTPS):
  1293. self = .ftps
  1294. case String(kSecAttrProtocolHTTPS):
  1295. self = .https
  1296. case String(kSecAttrProtocolHTTPProxy):
  1297. self = .httpProxy
  1298. case String(kSecAttrProtocolHTTPSProxy):
  1299. self = .httpsProxy
  1300. case String(kSecAttrProtocolFTPProxy):
  1301. self = .ftpProxy
  1302. case String(kSecAttrProtocolSMB):
  1303. self = .smb
  1304. case String(kSecAttrProtocolRTSP):
  1305. self = .rtsp
  1306. case String(kSecAttrProtocolRTSPProxy):
  1307. self = .rtspProxy
  1308. case String(kSecAttrProtocolDAAP):
  1309. self = .daap
  1310. case String(kSecAttrProtocolEPPC):
  1311. self = .eppc
  1312. case String(kSecAttrProtocolIPP):
  1313. self = .ipp
  1314. case String(kSecAttrProtocolNNTPS):
  1315. self = .nntps
  1316. case String(kSecAttrProtocolLDAPS):
  1317. self = .ldaps
  1318. case String(kSecAttrProtocolTelnetS):
  1319. self = .telnetS
  1320. case String(kSecAttrProtocolIMAPS):
  1321. self = .imaps
  1322. case String(kSecAttrProtocolIRCS):
  1323. self = .ircs
  1324. case String(kSecAttrProtocolPOP3S):
  1325. self = .pop3S
  1326. default:
  1327. return nil
  1328. }
  1329. }
  1330. public var rawValue: String {
  1331. switch self {
  1332. case .ftp:
  1333. return String(kSecAttrProtocolFTP)
  1334. case .ftpAccount:
  1335. return String(kSecAttrProtocolFTPAccount)
  1336. case .http:
  1337. return String(kSecAttrProtocolHTTP)
  1338. case .irc:
  1339. return String(kSecAttrProtocolIRC)
  1340. case .nntp:
  1341. return String(kSecAttrProtocolNNTP)
  1342. case .pop3:
  1343. return String(kSecAttrProtocolPOP3)
  1344. case .smtp:
  1345. return String(kSecAttrProtocolSMTP)
  1346. case .socks:
  1347. return String(kSecAttrProtocolSOCKS)
  1348. case .imap:
  1349. return String(kSecAttrProtocolIMAP)
  1350. case .ldap:
  1351. return String(kSecAttrProtocolLDAP)
  1352. case .appleTalk:
  1353. return String(kSecAttrProtocolAppleTalk)
  1354. case .afp:
  1355. return String(kSecAttrProtocolAFP)
  1356. case .telnet:
  1357. return String(kSecAttrProtocolTelnet)
  1358. case .ssh:
  1359. return String(kSecAttrProtocolSSH)
  1360. case .ftps:
  1361. return String(kSecAttrProtocolFTPS)
  1362. case .https:
  1363. return String(kSecAttrProtocolHTTPS)
  1364. case .httpProxy:
  1365. return String(kSecAttrProtocolHTTPProxy)
  1366. case .httpsProxy:
  1367. return String(kSecAttrProtocolHTTPSProxy)
  1368. case .ftpProxy:
  1369. return String(kSecAttrProtocolFTPProxy)
  1370. case .smb:
  1371. return String(kSecAttrProtocolSMB)
  1372. case .rtsp:
  1373. return String(kSecAttrProtocolRTSP)
  1374. case .rtspProxy:
  1375. return String(kSecAttrProtocolRTSPProxy)
  1376. case .daap:
  1377. return String(kSecAttrProtocolDAAP)
  1378. case .eppc:
  1379. return String(kSecAttrProtocolEPPC)
  1380. case .ipp:
  1381. return String(kSecAttrProtocolIPP)
  1382. case .nntps:
  1383. return String(kSecAttrProtocolNNTPS)
  1384. case .ldaps:
  1385. return String(kSecAttrProtocolLDAPS)
  1386. case .telnetS:
  1387. return String(kSecAttrProtocolTelnetS)
  1388. case .imaps:
  1389. return String(kSecAttrProtocolIMAPS)
  1390. case .ircs:
  1391. return String(kSecAttrProtocolIRCS)
  1392. case .pop3S:
  1393. return String(kSecAttrProtocolPOP3S)
  1394. }
  1395. }
  1396. public var description: String {
  1397. switch self {
  1398. case .ftp:
  1399. return "FTP"
  1400. case .ftpAccount:
  1401. return "FTPAccount"
  1402. case .http:
  1403. return "HTTP"
  1404. case .irc:
  1405. return "IRC"
  1406. case .nntp:
  1407. return "NNTP"
  1408. case .pop3:
  1409. return "POP3"
  1410. case .smtp:
  1411. return "SMTP"
  1412. case .socks:
  1413. return "SOCKS"
  1414. case .imap:
  1415. return "IMAP"
  1416. case .ldap:
  1417. return "LDAP"
  1418. case .appleTalk:
  1419. return "AppleTalk"
  1420. case .afp:
  1421. return "AFP"
  1422. case .telnet:
  1423. return "Telnet"
  1424. case .ssh:
  1425. return "SSH"
  1426. case .ftps:
  1427. return "FTPS"
  1428. case .https:
  1429. return "HTTPS"
  1430. case .httpProxy:
  1431. return "HTTPProxy"
  1432. case .httpsProxy:
  1433. return "HTTPSProxy"
  1434. case .ftpProxy:
  1435. return "FTPProxy"
  1436. case .smb:
  1437. return "SMB"
  1438. case .rtsp:
  1439. return "RTSP"
  1440. case .rtspProxy:
  1441. return "RTSPProxy"
  1442. case .daap:
  1443. return "DAAP"
  1444. case .eppc:
  1445. return "EPPC"
  1446. case .ipp:
  1447. return "IPP"
  1448. case .nntps:
  1449. return "NNTPS"
  1450. case .ldaps:
  1451. return "LDAPS"
  1452. case .telnetS:
  1453. return "TelnetS"
  1454. case .imaps:
  1455. return "IMAPS"
  1456. case .ircs:
  1457. return "IRCS"
  1458. case .pop3S:
  1459. return "POP3S"
  1460. }
  1461. }
  1462. }
  1463. extension AuthenticationType: RawRepresentable, CustomStringConvertible {
  1464. public init?(rawValue: String) {
  1465. switch rawValue {
  1466. case String(kSecAttrAuthenticationTypeNTLM):
  1467. self = .ntlm
  1468. case String(kSecAttrAuthenticationTypeMSN):
  1469. self = .msn
  1470. case String(kSecAttrAuthenticationTypeDPA):
  1471. self = .dpa
  1472. case String(kSecAttrAuthenticationTypeRPA):
  1473. self = .rpa
  1474. case String(kSecAttrAuthenticationTypeHTTPBasic):
  1475. self = .httpBasic
  1476. case String(kSecAttrAuthenticationTypeHTTPDigest):
  1477. self = .httpDigest
  1478. case String(kSecAttrAuthenticationTypeHTMLForm):
  1479. self = .htmlForm
  1480. case String(kSecAttrAuthenticationTypeDefault):
  1481. self = .`default`
  1482. default:
  1483. return nil
  1484. }
  1485. }
  1486. public var rawValue: String {
  1487. switch self {
  1488. case .ntlm:
  1489. return String(kSecAttrAuthenticationTypeNTLM)
  1490. case .msn:
  1491. return String(kSecAttrAuthenticationTypeMSN)
  1492. case .dpa:
  1493. return String(kSecAttrAuthenticationTypeDPA)
  1494. case .rpa:
  1495. return String(kSecAttrAuthenticationTypeRPA)
  1496. case .httpBasic:
  1497. return String(kSecAttrAuthenticationTypeHTTPBasic)
  1498. case .httpDigest:
  1499. return String(kSecAttrAuthenticationTypeHTTPDigest)
  1500. case .htmlForm:
  1501. return String(kSecAttrAuthenticationTypeHTMLForm)
  1502. case .`default`:
  1503. return String(kSecAttrAuthenticationTypeDefault)
  1504. }
  1505. }
  1506. public var description: String {
  1507. switch self {
  1508. case .ntlm:
  1509. return "NTLM"
  1510. case .msn:
  1511. return "MSN"
  1512. case .dpa:
  1513. return "DPA"
  1514. case .rpa:
  1515. return "RPA"
  1516. case .httpBasic:
  1517. return "HTTPBasic"
  1518. case .httpDigest:
  1519. return "HTTPDigest"
  1520. case .htmlForm:
  1521. return "HTMLForm"
  1522. case .`default`:
  1523. return "Default"
  1524. }
  1525. }
  1526. }
  1527. extension Accessibility: RawRepresentable, CustomStringConvertible {
  1528. public init?(rawValue: String) {
  1529. if #available(OSX 10.10, *) {
  1530. switch rawValue {
  1531. case String(kSecAttrAccessibleWhenUnlocked):
  1532. self = .whenUnlocked
  1533. case String(kSecAttrAccessibleAfterFirstUnlock):
  1534. self = .afterFirstUnlock
  1535. #if !targetEnvironment(macCatalyst)
  1536. case String(kSecAttrAccessibleAlways):
  1537. self = .always
  1538. #endif
  1539. case String(kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly):
  1540. self = .whenPasscodeSetThisDeviceOnly
  1541. case String(kSecAttrAccessibleWhenUnlockedThisDeviceOnly):
  1542. self = .whenUnlockedThisDeviceOnly
  1543. case String(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly):
  1544. self = .afterFirstUnlockThisDeviceOnly
  1545. #if !targetEnvironment(macCatalyst)
  1546. case String(kSecAttrAccessibleAlwaysThisDeviceOnly):
  1547. self = .alwaysThisDeviceOnly
  1548. #endif
  1549. default:
  1550. return nil
  1551. }
  1552. } else {
  1553. switch rawValue {
  1554. case String(kSecAttrAccessibleWhenUnlocked):
  1555. self = .whenUnlocked
  1556. case String(kSecAttrAccessibleAfterFirstUnlock):
  1557. self = .afterFirstUnlock
  1558. #if !targetEnvironment(macCatalyst)
  1559. case String(kSecAttrAccessibleAlways):
  1560. self = .always
  1561. #endif
  1562. case String(kSecAttrAccessibleWhenUnlockedThisDeviceOnly):
  1563. self = .whenUnlockedThisDeviceOnly
  1564. case String(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly):
  1565. self = .afterFirstUnlockThisDeviceOnly
  1566. #if !targetEnvironment(macCatalyst)
  1567. case String(kSecAttrAccessibleAlwaysThisDeviceOnly):
  1568. self = .alwaysThisDeviceOnly
  1569. #endif
  1570. default:
  1571. return nil
  1572. }
  1573. }
  1574. }
  1575. public var rawValue: String {
  1576. switch self {
  1577. case .whenUnlocked:
  1578. return String(kSecAttrAccessibleWhenUnlocked)
  1579. case .afterFirstUnlock:
  1580. return String(kSecAttrAccessibleAfterFirstUnlock)
  1581. #if !targetEnvironment(macCatalyst)
  1582. case .always:
  1583. return String(kSecAttrAccessibleAlways)
  1584. #endif
  1585. case .whenPasscodeSetThisDeviceOnly:
  1586. if #available(OSX 10.10, *) {
  1587. return String(kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly)
  1588. } else {
  1589. fatalError("'Accessibility.WhenPasscodeSetThisDeviceOnly' is not available on this version of OS.")
  1590. }
  1591. case .whenUnlockedThisDeviceOnly:
  1592. return String(kSecAttrAccessibleWhenUnlockedThisDeviceOnly)
  1593. case .afterFirstUnlockThisDeviceOnly:
  1594. return String(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly)
  1595. #if !targetEnvironment(macCatalyst)
  1596. case .alwaysThisDeviceOnly:
  1597. return String(kSecAttrAccessibleAlwaysThisDeviceOnly)
  1598. #endif
  1599. }
  1600. }
  1601. public var description: String {
  1602. switch self {
  1603. case .whenUnlocked:
  1604. return "WhenUnlocked"
  1605. case .afterFirstUnlock:
  1606. return "AfterFirstUnlock"
  1607. #if !targetEnvironment(macCatalyst)
  1608. case .always:
  1609. return "Always"
  1610. #endif
  1611. case .whenPasscodeSetThisDeviceOnly:
  1612. return "WhenPasscodeSetThisDeviceOnly"
  1613. case .whenUnlockedThisDeviceOnly:
  1614. return "WhenUnlockedThisDeviceOnly"
  1615. case .afterFirstUnlockThisDeviceOnly:
  1616. return "AfterFirstUnlockThisDeviceOnly"
  1617. #if !targetEnvironment(macCatalyst)
  1618. case .alwaysThisDeviceOnly:
  1619. return "AlwaysThisDeviceOnly"
  1620. #endif
  1621. }
  1622. }
  1623. }
  1624. extension CFError {
  1625. var error: NSError {
  1626. let domain = CFErrorGetDomain(self) as String
  1627. let code = CFErrorGetCode(self)
  1628. let userInfo = CFErrorCopyUserInfo(self) as! [String: Any]
  1629. return NSError(domain: domain, code: code, userInfo: userInfo)
  1630. }
  1631. }
  1632. public enum Status: OSStatus, Error {
  1633. case success = 0
  1634. case unimplemented = -4
  1635. case diskFull = -34
  1636. case io = -36
  1637. case opWr = -49
  1638. case param = -50
  1639. case wrPerm = -61
  1640. case allocate = -108
  1641. case userCanceled = -128
  1642. case badReq = -909
  1643. case internalComponent = -2070
  1644. case notAvailable = -25291
  1645. case readOnly = -25292
  1646. case authFailed = -25293
  1647. case noSuchKeychain = -25294
  1648. case invalidKeychain = -25295
  1649. case duplicateKeychain = -25296
  1650. case duplicateCallback = -25297
  1651. case invalidCallback = -25298
  1652. case duplicateItem = -25299
  1653. case itemNotFound = -25300
  1654. case bufferTooSmall = -25301
  1655. case dataTooLarge = -25302
  1656. case noSuchAttr = -25303
  1657. case invalidItemRef = -25304
  1658. case invalidSearchRef = -25305
  1659. case noSuchClass = -25306
  1660. case noDefaultKeychain = -25307
  1661. case interactionNotAllowed = -25308
  1662. case readOnlyAttr = -25309
  1663. case wrongSecVersion = -25310
  1664. case keySizeNotAllowed = -25311
  1665. case noStorageModule = -25312
  1666. case noCertificateModule = -25313
  1667. case noPolicyModule = -25314
  1668. case interactionRequired = -25315
  1669. case dataNotAvailable = -25316
  1670. case dataNotModifiable = -25317
  1671. case createChainFailed = -25318
  1672. case invalidPrefsDomain = -25319
  1673. case inDarkWake = -25320
  1674. case aclNotSimple = -25240
  1675. case policyNotFound = -25241
  1676. case invalidTrustSetting = -25242
  1677. case noAccessForItem = -25243
  1678. case invalidOwnerEdit = -25244
  1679. case trustNotAvailable = -25245
  1680. case unsupportedFormat = -25256
  1681. case unknownFormat = -25257
  1682. case keyIsSensitive = -25258
  1683. case multiplePrivKeys = -25259
  1684. case passphraseRequired = -25260
  1685. case invalidPasswordRef = -25261
  1686. case invalidTrustSettings = -25262
  1687. case noTrustSettings = -25263
  1688. case pkcs12VerifyFailure = -25264
  1689. case invalidCertificate = -26265
  1690. case notSigner = -26267
  1691. case policyDenied = -26270
  1692. case invalidKey = -26274
  1693. case decode = -26275
  1694. case `internal` = -26276
  1695. case unsupportedAlgorithm = -26268
  1696. case unsupportedOperation = -26271
  1697. case unsupportedPadding = -26273
  1698. case itemInvalidKey = -34000
  1699. case itemInvalidKeyType = -34001
  1700. case itemInvalidValue = -34002
  1701. case itemClassMissing = -34003
  1702. case itemMatchUnsupported = -34004
  1703. case useItemListUnsupported = -34005
  1704. case useKeychainUnsupported = -34006
  1705. case useKeychainListUnsupported = -34007
  1706. case returnDataUnsupported = -34008
  1707. case returnAttributesUnsupported = -34009
  1708. case returnRefUnsupported = -34010
  1709. case returnPersitentRefUnsupported = -34011
  1710. case valueRefUnsupported = -34012
  1711. case valuePersistentRefUnsupported = -34013
  1712. case returnMissingPointer = -34014
  1713. case matchLimitUnsupported = -34015
  1714. case itemIllegalQuery = -34016
  1715. case waitForCallback = -34017
  1716. case missingEntitlement = -34018
  1717. case upgradePending = -34019
  1718. case mpSignatureInvalid = -25327
  1719. case otrTooOld = -25328
  1720. case otrIDTooNew = -25329
  1721. case serviceNotAvailable = -67585
  1722. case insufficientClientID = -67586
  1723. case deviceReset = -67587
  1724. case deviceFailed = -67588
  1725. case appleAddAppACLSubject = -67589
  1726. case applePublicKeyIncomplete = -67590
  1727. case appleSignatureMismatch = -67591
  1728. case appleInvalidKeyStartDate = -67592
  1729. case appleInvalidKeyEndDate = -67593
  1730. case conversionError = -67594
  1731. case appleSSLv2Rollback = -67595
  1732. case quotaExceeded = -67596
  1733. case fileTooBig = -67597
  1734. case invalidDatabaseBlob = -67598
  1735. case invalidKeyBlob = -67599
  1736. case incompatibleDatabaseBlob = -67600
  1737. case incompatibleKeyBlob = -67601
  1738. case hostNameMismatch = -67602
  1739. case unknownCriticalExtensionFlag = -67603
  1740. case noBasicConstraints = -67604
  1741. case noBasicConstraintsCA = -67605
  1742. case invalidAuthorityKeyID = -67606
  1743. case invalidSubjectKeyID = -67607
  1744. case invalidKeyUsageForPolicy = -67608
  1745. case invalidExtendedKeyUsage = -67609
  1746. case invalidIDLinkage = -67610
  1747. case pathLengthConstraintExceeded = -67611
  1748. case invalidRoot = -67612
  1749. case crlExpired = -67613
  1750. case crlNotValidYet = -67614
  1751. case crlNotFound = -67615
  1752. case crlServerDown = -67616
  1753. case crlBadURI = -67617
  1754. case unknownCertExtension = -67618
  1755. case unknownCRLExtension = -67619
  1756. case crlNotTrusted = -67620
  1757. case crlPolicyFailed = -67621
  1758. case idpFailure = -67622
  1759. case smimeEmailAddressesNotFound = -67623
  1760. case smimeBadExtendedKeyUsage = -67624
  1761. case smimeBadKeyUsage = -67625
  1762. case smimeKeyUsageNotCritical = -67626
  1763. case smimeNoEmailAddress = -67627
  1764. case smimeSubjAltNameNotCritical = -67628
  1765. case sslBadExtendedKeyUsage = -67629
  1766. case ocspBadResponse = -67630
  1767. case ocspBadRequest = -67631
  1768. case ocspUnavailable = -67632
  1769. case ocspStatusUnrecognized = -67633
  1770. case endOfData = -67634
  1771. case incompleteCertRevocationCheck = -67635
  1772. case networkFailure = -67636
  1773. case ocspNotTrustedToAnchor = -67637
  1774. case recordModified = -67638
  1775. case ocspSignatureError = -67639
  1776. case ocspNoSigner = -67640
  1777. case ocspResponderMalformedReq = -67641
  1778. case ocspResponderInternalError = -67642
  1779. case ocspResponderTryLater = -67643
  1780. case ocspResponderSignatureRequired = -67644
  1781. case ocspResponderUnauthorized = -67645
  1782. case ocspResponseNonceMismatch = -67646
  1783. case codeSigningBadCertChainLength = -67647
  1784. case codeSigningNoBasicConstraints = -67648
  1785. case codeSigningBadPathLengthConstraint = -67649
  1786. case codeSigningNoExtendedKeyUsage = -67650
  1787. case codeSigningDevelopment = -67651
  1788. case resourceSignBadCertChainLength = -67652
  1789. case resourceSignBadExtKeyUsage = -67653
  1790. case trustSettingDeny = -67654
  1791. case invalidSubjectName = -67655
  1792. case unknownQualifiedCertStatement = -67656
  1793. case mobileMeRequestQueued = -67657
  1794. case mobileMeRequestRedirected = -67658
  1795. case mobileMeServerError = -67659
  1796. case mobileMeServerNotAvailable = -67660
  1797. case mobileMeServerAlreadyExists = -67661
  1798. case mobileMeServerServiceErr = -67662
  1799. case mobileMeRequestAlreadyPending = -67663
  1800. case mobileMeNoRequestPending = -67664
  1801. case mobileMeCSRVerifyFailure = -67665
  1802. case mobileMeFailedConsistencyCheck = -67666
  1803. case notInitialized = -67667
  1804. case invalidHandleUsage = -67668
  1805. case pvcReferentNotFound = -67669
  1806. case functionIntegrityFail = -67670
  1807. case internalError = -67671
  1808. case memoryError = -67672
  1809. case invalidData = -67673
  1810. case mdsError = -67674
  1811. case invalidPointer = -67675
  1812. case selfCheckFailed = -67676
  1813. case functionFailed = -67677
  1814. case moduleManifestVerifyFailed = -67678
  1815. case invalidGUID = -67679
  1816. case invalidHandle = -67680
  1817. case invalidDBList = -67681
  1818. case invalidPassthroughID = -67682
  1819. case invalidNetworkAddress = -67683
  1820. case crlAlreadySigned = -67684
  1821. case invalidNumberOfFields = -67685
  1822. case verificationFailure = -67686
  1823. case unknownTag = -67687
  1824. case invalidSignature = -67688
  1825. case invalidName = -67689
  1826. case invalidCertificateRef = -67690
  1827. case invalidCertificateGroup = -67691
  1828. case tagNotFound = -67692
  1829. case invalidQuery = -67693
  1830. case invalidValue = -67694
  1831. case callbackFailed = -67695
  1832. case aclDeleteFailed = -67696
  1833. case aclReplaceFailed = -67697
  1834. case aclAddFailed = -67698
  1835. case aclChangeFailed = -67699
  1836. case invalidAccessCredentials = -67700
  1837. case invalidRecord = -67701
  1838. case invalidACL = -67702
  1839. case invalidSampleValue = -67703
  1840. case incompatibleVersion = -67704
  1841. case privilegeNotGranted = -67705
  1842. case invalidScope = -67706
  1843. case pvcAlreadyConfigured = -67707
  1844. case invalidPVC = -67708
  1845. case emmLoadFailed = -67709
  1846. case emmUnloadFailed = -67710
  1847. case addinLoadFailed = -67711
  1848. case invalidKeyRef = -67712
  1849. case invalidKeyHierarchy = -67713
  1850. case addinUnloadFailed = -67714
  1851. case libraryReferenceNotFound = -67715
  1852. case invalidAddinFunctionTable = -67716
  1853. case invalidServiceMask = -67717
  1854. case moduleNotLoaded = -67718
  1855. case invalidSubServiceID = -67719
  1856. case attributeNotInContext = -67720
  1857. case moduleManagerInitializeFailed = -67721
  1858. case moduleManagerNotFound = -67722
  1859. case eventNotificationCallbackNotFound = -67723
  1860. case inputLengthError = -67724
  1861. case outputLengthError = -67725
  1862. case privilegeNotSupported = -67726
  1863. case deviceError = -67727
  1864. case attachHandleBusy = -67728
  1865. case notLoggedIn = -67729
  1866. case algorithmMismatch = -67730
  1867. case keyUsageIncorrect = -67731
  1868. case keyBlobTypeIncorrect = -67732
  1869. case keyHeaderInconsistent = -67733
  1870. case unsupportedKeyFormat = -67734
  1871. case unsupportedKeySize = -67735
  1872. case invalidKeyUsageMask = -67736
  1873. case unsupportedKeyUsageMask = -67737
  1874. case invalidKeyAttributeMask = -67738
  1875. case unsupportedKeyAttributeMask = -67739
  1876. case invalidKeyLabel = -67740
  1877. case unsupportedKeyLabel = -67741
  1878. case invalidKeyFormat = -67742
  1879. case unsupportedVectorOfBuffers = -67743
  1880. case invalidInputVector = -67744
  1881. case invalidOutputVector = -67745
  1882. case invalidContext = -67746
  1883. case invalidAlgorithm = -67747
  1884. case invalidAttributeKey = -67748
  1885. case missingAttributeKey = -67749
  1886. case invalidAttributeInitVector = -67750
  1887. case missingAttributeInitVector = -67751
  1888. case invalidAttributeSalt = -67752
  1889. case missingAttributeSalt = -67753
  1890. case invalidAttributePadding = -67754
  1891. case missingAttributePadding = -67755
  1892. case invalidAttributeRandom = -67756
  1893. case missingAttributeRandom = -67757
  1894. case invalidAttributeSeed = -67758
  1895. case missingAttributeSeed = -67759
  1896. case invalidAttributePassphrase = -67760
  1897. case missingAttributePassphrase = -67761
  1898. case invalidAttributeKeyLength = -67762
  1899. case missingAttributeKeyLength = -67763
  1900. case invalidAttributeBlockSize = -67764
  1901. case missingAttributeBlockSize = -67765
  1902. case invalidAttributeOutputSize = -67766
  1903. case missingAttributeOutputSize = -67767
  1904. case invalidAttributeRounds = -67768
  1905. case missingAttributeRounds = -67769
  1906. case invalidAlgorithmParms = -67770
  1907. case missingAlgorithmParms = -67771
  1908. case invalidAttributeLabel = -67772
  1909. case missingAttributeLabel = -67773
  1910. case invalidAttributeKeyType = -67774
  1911. case missingAttributeKeyType = -67775
  1912. case invalidAttributeMode = -67776
  1913. case missingAttributeMode = -67777
  1914. case invalidAttributeEffectiveBits = -67778
  1915. case missingAttributeEffectiveBits = -67779
  1916. case invalidAttributeStartDate = -67780
  1917. case missingAttributeStartDate = -67781
  1918. case invalidAttributeEndDate = -67782
  1919. case missingAttributeEndDate = -67783
  1920. case invalidAttributeVersion = -67784
  1921. case missingAttributeVersion = -67785
  1922. case invalidAttributePrime = -67786
  1923. case missingAttributePrime = -67787
  1924. case invalidAttributeBase = -67788
  1925. case missingAttributeBase = -67789
  1926. case invalidAttributeSubprime = -67790
  1927. case missingAttributeSubprime = -67791
  1928. case invalidAttributeIterationCount = -67792
  1929. case missingAttributeIterationCount = -67793
  1930. case invalidAttributeDLDBHandle = -67794
  1931. case missingAttributeDLDBHandle = -67795
  1932. case invalidAttributeAccessCredentials = -67796
  1933. case missingAttributeAccessCredentials = -67797
  1934. case invalidAttributePublicKeyFormat = -67798
  1935. case missingAttributePublicKeyFormat = -67799
  1936. case invalidAttributePrivateKeyFormat = -67800
  1937. case missingAttributePrivateKeyFormat = -67801
  1938. case invalidAttributeSymmetricKeyFormat = -67802
  1939. case missingAttributeSymmetricKeyFormat = -67803
  1940. case invalidAttributeWrappedKeyFormat = -67804
  1941. case missingAttributeWrappedKeyFormat = -67805
  1942. case stagedOperationInProgress = -67806
  1943. case stagedOperationNotStarted = -67807
  1944. case verifyFailed = -67808
  1945. case querySizeUnknown = -67809
  1946. case blockSizeMismatch = -67810
  1947. case publicKeyInconsistent = -67811
  1948. case deviceVerifyFailed = -67812
  1949. case invalidLoginName = -67813
  1950. case alreadyLoggedIn = -67814
  1951. case invalidDigestAlgorithm = -67815
  1952. case invalidCRLGroup = -67816
  1953. case certificateCannotOperate = -67817
  1954. case certificateExpired = -67818
  1955. case certificateNotValidYet = -67819
  1956. case certificateRevoked = -67820
  1957. case certificateSuspended = -67821
  1958. case insufficientCredentials = -67822
  1959. case invalidAction = -67823
  1960. case invalidAuthority = -67824
  1961. case verifyActionFailed = -67825
  1962. case invalidCertAuthority = -67826
  1963. case invaldCRLAuthority = -67827
  1964. case invalidCRLEncoding = -67828
  1965. case invalidCRLType = -67829
  1966. case invalidCRL = -67830
  1967. case invalidFormType = -67831
  1968. case invalidID = -67832
  1969. case invalidIdentifier = -67833
  1970. case invalidIndex = -67834
  1971. case invalidPolicyIdentifiers = -67835
  1972. case invalidTimeString = -67836
  1973. case invalidReason = -67837
  1974. case invalidRequestInputs = -67838
  1975. case invalidResponseVector = -67839
  1976. case invalidStopOnPolicy = -67840
  1977. case invalidTuple = -67841
  1978. case multipleValuesUnsupported = -67842
  1979. case notTrusted = -67843
  1980. case noDefaultAuthority = -67844
  1981. case rejectedForm = -67845
  1982. case requestLost = -67846
  1983. case requestRejected = -67847
  1984. case unsupportedAddressType = -67848
  1985. case unsupportedService = -67849
  1986. case invalidTupleGroup = -67850
  1987. case invalidBaseACLs = -67851
  1988. case invalidTupleCredendtials = -67852
  1989. case invalidEncoding = -67853
  1990. case invalidValidityPeriod = -67854
  1991. case invalidRequestor = -67855
  1992. case requestDescriptor = -67856
  1993. case invalidBundleInfo = -67857
  1994. case invalidCRLIndex = -67858
  1995. case noFieldValues = -67859
  1996. case unsupportedFieldFormat = -67860
  1997. case unsupportedIndexInfo = -67861
  1998. case unsupportedLocality = -67862
  1999. case unsupportedNumAttributes = -67863
  2000. case unsupportedNumIndexes = -67864
  2001. case unsupportedNumRecordTypes = -67865
  2002. case fieldSpecifiedMultiple = -67866
  2003. case incompatibleFieldFormat = -67867
  2004. case invalidParsingModule = -67868
  2005. case databaseLocked = -67869
  2006. case datastoreIsOpen = -67870
  2007. case missingValue = -67871
  2008. case unsupportedQueryLimits = -67872
  2009. case unsupportedNumSelectionPreds = -67873
  2010. case unsupportedOperator = -67874
  2011. case invalidDBLocation = -67875
  2012. case invalidAccessRequest = -67876
  2013. case invalidIndexInfo = -67877
  2014. case invalidNewOwner = -67878
  2015. case invalidModifyMode = -67879
  2016. case missingRequiredExtension = -67880
  2017. case extendedKeyUsageNotCritical = -67881
  2018. case timestampMissing = -67882
  2019. case timestampInvalid = -67883
  2020. case timestampNotTrusted = -67884
  2021. case timestampServiceNotAvailable = -67885
  2022. case timestampBadAlg = -67886
  2023. case timestampBadRequest = -67887
  2024. case timestampBadDataFormat = -67888
  2025. case timestampTimeNotAvailable = -67889
  2026. case timestampUnacceptedPolicy = -67890
  2027. case timestampUnacceptedExtension = -67891
  2028. case timestampAddInfoNotAvailable = -67892
  2029. case timestampSystemFailure = -67893
  2030. case signingTimeMissing = -67894
  2031. case timestampRejection = -67895
  2032. case timestampWaiting = -67896
  2033. case timestampRevocationWarning = -67897
  2034. case timestampRevocationNotification = -67898
  2035. case unexpectedError = -99999
  2036. }
  2037. extension Status: RawRepresentable, CustomStringConvertible {
  2038. public init(status: OSStatus) {
  2039. if let mappedStatus = Status(rawValue: status) {
  2040. self = mappedStatus
  2041. } else {
  2042. self = .unexpectedError
  2043. }
  2044. }
  2045. public var description: String {
  2046. switch self {
  2047. case .success:
  2048. return "No error."
  2049. case .unimplemented:
  2050. return "Function or operation not implemented."
  2051. case .diskFull:
  2052. return "The disk is full."
  2053. case .io:
  2054. return "I/O error (bummers)"
  2055. case .opWr:
  2056. return "file already open with with write permission"
  2057. case .param:
  2058. return "One or more parameters passed to a function were not valid."
  2059. case .wrPerm:
  2060. return "write permissions error"
  2061. case .allocate:
  2062. return "Failed to allocate memory."
  2063. case .userCanceled:
  2064. return "User canceled the operation."
  2065. case .badReq:
  2066. return "Bad parameter or invalid state for operation."
  2067. case .internalComponent:
  2068. return ""
  2069. case .notAvailable:
  2070. return "No keychain is available. You may need to restart your computer."
  2071. case .readOnly:
  2072. return "This keychain cannot be modified."
  2073. case .authFailed:
  2074. return "The user name or passphrase you entered is not correct."
  2075. case .noSuchKeychain:
  2076. return "The specified keychain could not be found."
  2077. case .invalidKeychain:
  2078. return "The specified keychain is not a valid keychain file."
  2079. case .duplicateKeychain:
  2080. return "A keychain with the same name already exists."
  2081. case .duplicateCallback:
  2082. return "The specified callback function is already installed."
  2083. case .invalidCallback:
  2084. return "The specified callback function is not valid."
  2085. case .duplicateItem:
  2086. return "The specified item already exists in the keychain."
  2087. case .itemNotFound:
  2088. return "The specified item could not be found in the keychain."
  2089. case .bufferTooSmall:
  2090. return "There is not enough memory available to use the specified item."
  2091. case .dataTooLarge:
  2092. return "This item contains information which is too large or in a format that cannot be displayed."
  2093. case .noSuchAttr:
  2094. return "The specified attribute does not exist."
  2095. case .invalidItemRef:
  2096. return "The specified item is no longer valid. It may have been deleted from the keychain."
  2097. case .invalidSearchRef:
  2098. return "Unable to search the current keychain."
  2099. case .noSuchClass:
  2100. return "The specified item does not appear to be a valid keychain item."
  2101. case .noDefaultKeychain:
  2102. return "A default keychain could not be found."
  2103. case .interactionNotAllowed:
  2104. return "User interaction is not allowed."
  2105. case .readOnlyAttr:
  2106. return "The specified attribute could not be modified."
  2107. case .wrongSecVersion:
  2108. return "This keychain was created by a different version of the system software and cannot be opened."
  2109. case .keySizeNotAllowed:
  2110. return "This item specifies a key size which is too large."
  2111. case .noStorageModule:
  2112. return "A required component (data storage module) could not be loaded. You may need to restart your computer."
  2113. case .noCertificateModule:
  2114. return "A required component (certificate module) could not be loaded. You may need to restart your computer."
  2115. case .noPolicyModule:
  2116. return "A required component (policy module) could not be loaded. You may need to restart your computer."
  2117. case .interactionRequired:
  2118. return "User interaction is required, but is currently not allowed."
  2119. case .dataNotAvailable:
  2120. return "The contents of this item cannot be retrieved."
  2121. case .dataNotModifiable:
  2122. return "The contents of this item cannot be modified."
  2123. case .createChainFailed:
  2124. return "One or more certificates required to validate this certificate cannot be found."
  2125. case .invalidPrefsDomain:
  2126. return "The specified preferences domain is not valid."
  2127. case .inDarkWake:
  2128. return "In dark wake, no UI possible"
  2129. case .aclNotSimple:
  2130. return "The specified access control list is not in standard (simple) form."
  2131. case .policyNotFound:
  2132. return "The specified policy cannot be found."
  2133. case .invalidTrustSetting:
  2134. return "The specified trust setting is invalid."
  2135. case .noAccessForItem:
  2136. return "The specified item has no access control."
  2137. case .invalidOwnerEdit:
  2138. return "Invalid attempt to change the owner of this item."
  2139. case .trustNotAvailable:
  2140. return "No trust results are available."
  2141. case .unsupportedFormat:
  2142. return "Import/Export format unsupported."
  2143. case .unknownFormat:
  2144. return "Unknown format in import."
  2145. case .keyIsSensitive:
  2146. return "Key material must be wrapped for export."
  2147. case .multiplePrivKeys:
  2148. return "An attempt was made to import multiple private keys."
  2149. case .passphraseRequired:
  2150. return "Passphrase is required for import/export."
  2151. case .invalidPasswordRef:
  2152. return "The password reference was invalid."
  2153. case .invalidTrustSettings:
  2154. return "The Trust Settings Record was corrupted."
  2155. case .noTrustSettings:
  2156. return "No Trust Settings were found."
  2157. case .pkcs12VerifyFailure:
  2158. return "MAC verification failed during PKCS12 import (wrong password?)"
  2159. case .invalidCertificate:
  2160. return "This certificate could not be decoded."
  2161. case .notSigner:
  2162. return "A certificate was not signed by its proposed parent."
  2163. case .policyDenied:
  2164. return "The certificate chain was not trusted due to a policy not accepting it."
  2165. case .invalidKey:
  2166. return "The provided key material was not valid."
  2167. case .decode:
  2168. return "Unable to decode the provided data."
  2169. case .`internal`:
  2170. return "An internal error occurred in the Security framework."
  2171. case .unsupportedAlgorithm:
  2172. return "An unsupported algorithm was encountered."
  2173. case .unsupportedOperation:
  2174. return "The operation you requested is not supported by this key."
  2175. case .unsupportedPadding:
  2176. return "The padding you requested is not supported."
  2177. case .itemInvalidKey:
  2178. return "A string key in dictionary is not one of the supported keys."
  2179. case .itemInvalidKeyType:
  2180. return "A key in a dictionary is neither a CFStringRef nor a CFNumberRef."
  2181. case .itemInvalidValue:
  2182. return "A value in a dictionary is an invalid (or unsupported) CF type."
  2183. case .itemClassMissing:
  2184. return "No kSecItemClass key was specified in a dictionary."
  2185. case .itemMatchUnsupported:
  2186. return "The caller passed one or more kSecMatch keys to a function which does not support matches."
  2187. case .useItemListUnsupported:
  2188. return "The caller passed in a kSecUseItemList key to a function which does not support it."
  2189. case .useKeychainUnsupported:
  2190. return "The caller passed in a kSecUseKeychain key to a function which does not support it."
  2191. case .useKeychainListUnsupported:
  2192. return "The caller passed in a kSecUseKeychainList key to a function which does not support it."
  2193. case .returnDataUnsupported:
  2194. return "The caller passed in a kSecReturnData key to a function which does not support it."
  2195. case .returnAttributesUnsupported:
  2196. return "The caller passed in a kSecReturnAttributes key to a function which does not support it."
  2197. case .returnRefUnsupported:
  2198. return "The caller passed in a kSecReturnRef key to a function which does not support it."
  2199. case .returnPersitentRefUnsupported:
  2200. return "The caller passed in a kSecReturnPersistentRef key to a function which does not support it."
  2201. case .valueRefUnsupported:
  2202. return "The caller passed in a kSecValueRef key to a function which does not support it."
  2203. case .valuePersistentRefUnsupported:
  2204. return "The caller passed in a kSecValuePersistentRef key to a function which does not support it."
  2205. case .returnMissingPointer:
  2206. return "The caller passed asked for something to be returned but did not pass in a result pointer."
  2207. case .matchLimitUnsupported:
  2208. return "The caller passed in a kSecMatchLimit key to a call which does not support limits."
  2209. case .itemIllegalQuery:
  2210. return "The caller passed in a query which contained too many keys."
  2211. case .waitForCallback:
  2212. return "This operation is incomplete, until the callback is invoked (not an error)."
  2213. case .missingEntitlement:
  2214. return "Internal error when a required entitlement isn't present, client has neither application-identifier nor keychain-access-groups entitlements."
  2215. case .upgradePending:
  2216. 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."
  2217. case .mpSignatureInvalid:
  2218. return "Signature invalid on MP message"
  2219. case .otrTooOld:
  2220. return "Message is too old to use"
  2221. case .otrIDTooNew:
  2222. return "Key ID is too new to use! Message from the future?"
  2223. case .serviceNotAvailable:
  2224. return "The required service is not available."
  2225. case .insufficientClientID:
  2226. return "The client ID is not correct."
  2227. case .deviceReset:
  2228. return "A device reset has occurred."
  2229. case .deviceFailed:
  2230. return "A device failure has occurred."
  2231. case .appleAddAppACLSubject:
  2232. return "Adding an application ACL subject failed."
  2233. case .applePublicKeyIncomplete:
  2234. return "The public key is incomplete."
  2235. case .appleSignatureMismatch:
  2236. return "A signature mismatch has occurred."
  2237. case .appleInvalidKeyStartDate:
  2238. return "The specified key has an invalid start date."
  2239. case .appleInvalidKeyEndDate:
  2240. return "The specified key has an invalid end date."
  2241. case .conversionError:
  2242. return "A conversion error has occurred."
  2243. case .appleSSLv2Rollback:
  2244. return "A SSLv2 rollback error has occurred."
  2245. case .quotaExceeded:
  2246. return "The quota was exceeded."
  2247. case .fileTooBig:
  2248. return "The file is too big."
  2249. case .invalidDatabaseBlob:
  2250. return "The specified database has an invalid blob."
  2251. case .invalidKeyBlob:
  2252. return "The specified database has an invalid key blob."
  2253. case .incompatibleDatabaseBlob:
  2254. return "The specified database has an incompatible blob."
  2255. case .incompatibleKeyBlob:
  2256. return "The specified database has an incompatible key blob."
  2257. case .hostNameMismatch:
  2258. return "A host name mismatch has occurred."
  2259. case .unknownCriticalExtensionFlag:
  2260. return "There is an unknown critical extension flag."
  2261. case .noBasicConstraints:
  2262. return "No basic constraints were found."
  2263. case .noBasicConstraintsCA:
  2264. return "No basic CA constraints were found."
  2265. case .invalidAuthorityKeyID:
  2266. return "The authority key ID is not valid."
  2267. case .invalidSubjectKeyID:
  2268. return "The subject key ID is not valid."
  2269. case .invalidKeyUsageForPolicy:
  2270. return "The key usage is not valid for the specified policy."
  2271. case .invalidExtendedKeyUsage:
  2272. return "The extended key usage is not valid."
  2273. case .invalidIDLinkage:
  2274. return "The ID linkage is not valid."
  2275. case .pathLengthConstraintExceeded:
  2276. return "The path length constraint was exceeded."
  2277. case .invalidRoot:
  2278. return "The root or anchor certificate is not valid."
  2279. case .crlExpired:
  2280. return "The CRL has expired."
  2281. case .crlNotValidYet:
  2282. return "The CRL is not yet valid."
  2283. case .crlNotFound:
  2284. return "The CRL was not found."
  2285. case .crlServerDown:
  2286. return "The CRL server is down."
  2287. case .crlBadURI:
  2288. return "The CRL has a bad Uniform Resource Identifier."
  2289. case .unknownCertExtension:
  2290. return "An unknown certificate extension was encountered."
  2291. case .unknownCRLExtension:
  2292. return "An unknown CRL extension was encountered."
  2293. case .crlNotTrusted:
  2294. return "The CRL is not trusted."
  2295. case .crlPolicyFailed:
  2296. return "The CRL policy failed."
  2297. case .idpFailure:
  2298. return "The issuing distribution point was not valid."
  2299. case .smimeEmailAddressesNotFound:
  2300. return "An email address mismatch was encountered."
  2301. case .smimeBadExtendedKeyUsage:
  2302. return "The appropriate extended key usage for SMIME was not found."
  2303. case .smimeBadKeyUsage:
  2304. return "The key usage is not compatible with SMIME."
  2305. case .smimeKeyUsageNotCritical:
  2306. return "The key usage extension is not marked as critical."
  2307. case .smimeNoEmailAddress:
  2308. return "No email address was found in the certificate."
  2309. case .smimeSubjAltNameNotCritical:
  2310. return "The subject alternative name extension is not marked as critical."
  2311. case .sslBadExtendedKeyUsage:
  2312. return "The appropriate extended key usage for SSL was not found."
  2313. case .ocspBadResponse:
  2314. return "The OCSP response was incorrect or could not be parsed."
  2315. case .ocspBadRequest:
  2316. return "The OCSP request was incorrect or could not be parsed."
  2317. case .ocspUnavailable:
  2318. return "OCSP service is unavailable."
  2319. case .ocspStatusUnrecognized:
  2320. return "The OCSP server did not recognize this certificate."
  2321. case .endOfData:
  2322. return "An end-of-data was detected."
  2323. case .incompleteCertRevocationCheck:
  2324. return "An incomplete certificate revocation check occurred."
  2325. case .networkFailure:
  2326. return "A network failure occurred."
  2327. case .ocspNotTrustedToAnchor:
  2328. return "The OCSP response was not trusted to a root or anchor certificate."
  2329. case .recordModified:
  2330. return "The record was modified."
  2331. case .ocspSignatureError:
  2332. return "The OCSP response had an invalid signature."
  2333. case .ocspNoSigner:
  2334. return "The OCSP response had no signer."
  2335. case .ocspResponderMalformedReq:
  2336. return "The OCSP responder was given a malformed request."
  2337. case .ocspResponderInternalError:
  2338. return "The OCSP responder encountered an internal error."
  2339. case .ocspResponderTryLater:
  2340. return "The OCSP responder is busy, try again later."
  2341. case .ocspResponderSignatureRequired:
  2342. return "The OCSP responder requires a signature."
  2343. case .ocspResponderUnauthorized:
  2344. return "The OCSP responder rejected this request as unauthorized."
  2345. case .ocspResponseNonceMismatch:
  2346. return "The OCSP response nonce did not match the request."
  2347. case .codeSigningBadCertChainLength:
  2348. return "Code signing encountered an incorrect certificate chain length."
  2349. case .codeSigningNoBasicConstraints:
  2350. return "Code signing found no basic constraints."
  2351. case .codeSigningBadPathLengthConstraint:
  2352. return "Code signing encountered an incorrect path length constraint."
  2353. case .codeSigningNoExtendedKeyUsage:
  2354. return "Code signing found no extended key usage."
  2355. case .codeSigningDevelopment:
  2356. return "Code signing indicated use of a development-only certificate."
  2357. case .resourceSignBadCertChainLength:
  2358. return "Resource signing has encountered an incorrect certificate chain length."
  2359. case .resourceSignBadExtKeyUsage:
  2360. return "Resource signing has encountered an error in the extended key usage."
  2361. case .trustSettingDeny:
  2362. return "The trust setting for this policy was set to Deny."
  2363. case .invalidSubjectName:
  2364. return "An invalid certificate subject name was encountered."
  2365. case .unknownQualifiedCertStatement:
  2366. return "An unknown qualified certificate statement was encountered."
  2367. case .mobileMeRequestQueued:
  2368. return "The MobileMe request will be sent during the next connection."
  2369. case .mobileMeRequestRedirected:
  2370. return "The MobileMe request was redirected."
  2371. case .mobileMeServerError:
  2372. return "A MobileMe server error occurred."
  2373. case .mobileMeServerNotAvailable:
  2374. return "The MobileMe server is not available."
  2375. case .mobileMeServerAlreadyExists:
  2376. return "The MobileMe server reported that the item already exists."
  2377. case .mobileMeServerServiceErr:
  2378. return "A MobileMe service error has occurred."
  2379. case .mobileMeRequestAlreadyPending:
  2380. return "A MobileMe request is already pending."
  2381. case .mobileMeNoRequestPending:
  2382. return "MobileMe has no request pending."
  2383. case .mobileMeCSRVerifyFailure:
  2384. return "A MobileMe CSR verification failure has occurred."
  2385. case .mobileMeFailedConsistencyCheck:
  2386. return "MobileMe has found a failed consistency check."
  2387. case .notInitialized:
  2388. return "A function was called without initializing CSSM."
  2389. case .invalidHandleUsage:
  2390. return "The CSSM handle does not match with the service type."
  2391. case .pvcReferentNotFound:
  2392. return "A reference to the calling module was not found in the list of authorized callers."
  2393. case .functionIntegrityFail:
  2394. return "A function address was not within the verified module."
  2395. case .internalError:
  2396. return "An internal error has occurred."
  2397. case .memoryError:
  2398. return "A memory error has occurred."
  2399. case .invalidData:
  2400. return "Invalid data was encountered."
  2401. case .mdsError:
  2402. return "A Module Directory Service error has occurred."
  2403. case .invalidPointer:
  2404. return "An invalid pointer was encountered."
  2405. case .selfCheckFailed:
  2406. return "Self-check has failed."
  2407. case .functionFailed:
  2408. return "A function has failed."
  2409. case .moduleManifestVerifyFailed:
  2410. return "A module manifest verification failure has occurred."
  2411. case .invalidGUID:
  2412. return "An invalid GUID was encountered."
  2413. case .invalidHandle:
  2414. return "An invalid handle was encountered."
  2415. case .invalidDBList:
  2416. return "An invalid DB list was encountered."
  2417. case .invalidPassthroughID:
  2418. return "An invalid passthrough ID was encountered."
  2419. case .invalidNetworkAddress:
  2420. return "An invalid network address was encountered."
  2421. case .crlAlreadySigned:
  2422. return "The certificate revocation list is already signed."
  2423. case .invalidNumberOfFields:
  2424. return "An invalid number of fields were encountered."
  2425. case .verificationFailure:
  2426. return "A verification failure occurred."
  2427. case .unknownTag:
  2428. return "An unknown tag was encountered."
  2429. case .invalidSignature:
  2430. return "An invalid signature was encountered."
  2431. case .invalidName:
  2432. return "An invalid name was encountered."
  2433. case .invalidCertificateRef:
  2434. return "An invalid certificate reference was encountered."
  2435. case .invalidCertificateGroup:
  2436. return "An invalid certificate group was encountered."
  2437. case .tagNotFound:
  2438. return "The specified tag was not found."
  2439. case .invalidQuery:
  2440. return "The specified query was not valid."
  2441. case .invalidValue:
  2442. return "An invalid value was detected."
  2443. case .callbackFailed:
  2444. return "A callback has failed."
  2445. case .aclDeleteFailed:
  2446. return "An ACL delete operation has failed."
  2447. case .aclReplaceFailed:
  2448. return "An ACL replace operation has failed."
  2449. case .aclAddFailed:
  2450. return "An ACL add operation has failed."
  2451. case .aclChangeFailed:
  2452. return "An ACL change operation has failed."
  2453. case .invalidAccessCredentials:
  2454. return "Invalid access credentials were encountered."
  2455. case .invalidRecord:
  2456. return "An invalid record was encountered."
  2457. case .invalidACL:
  2458. return "An invalid ACL was encountered."
  2459. case .invalidSampleValue:
  2460. return "An invalid sample value was encountered."
  2461. case .incompatibleVersion:
  2462. return "An incompatible version was encountered."
  2463. case .privilegeNotGranted:
  2464. return "The privilege was not granted."
  2465. case .invalidScope:
  2466. return "An invalid scope was encountered."
  2467. case .pvcAlreadyConfigured:
  2468. return "The PVC is already configured."
  2469. case .invalidPVC:
  2470. return "An invalid PVC was encountered."
  2471. case .emmLoadFailed:
  2472. return "The EMM load has failed."
  2473. case .emmUnloadFailed:
  2474. return "The EMM unload has failed."
  2475. case .addinLoadFailed:
  2476. return "The add-in load operation has failed."
  2477. case .invalidKeyRef:
  2478. return "An invalid key was encountered."
  2479. case .invalidKeyHierarchy:
  2480. return "An invalid key hierarchy was encountered."
  2481. case .addinUnloadFailed:
  2482. return "The add-in unload operation has failed."
  2483. case .libraryReferenceNotFound:
  2484. return "A library reference was not found."
  2485. case .invalidAddinFunctionTable:
  2486. return "An invalid add-in function table was encountered."
  2487. case .invalidServiceMask:
  2488. return "An invalid service mask was encountered."
  2489. case .moduleNotLoaded:
  2490. return "A module was not loaded."
  2491. case .invalidSubServiceID:
  2492. return "An invalid subservice ID was encountered."
  2493. case .attributeNotInContext:
  2494. return "An attribute was not in the context."
  2495. case .moduleManagerInitializeFailed:
  2496. return "A module failed to initialize."
  2497. case .moduleManagerNotFound:
  2498. return "A module was not found."
  2499. case .eventNotificationCallbackNotFound:
  2500. return "An event notification callback was not found."
  2501. case .inputLengthError:
  2502. return "An input length error was encountered."
  2503. case .outputLengthError:
  2504. return "An output length error was encountered."
  2505. case .privilegeNotSupported:
  2506. return "The privilege is not supported."
  2507. case .deviceError:
  2508. return "A device error was encountered."
  2509. case .attachHandleBusy:
  2510. return "The CSP handle was busy."
  2511. case .notLoggedIn:
  2512. return "You are not logged in."
  2513. case .algorithmMismatch:
  2514. return "An algorithm mismatch was encountered."
  2515. case .keyUsageIncorrect:
  2516. return "The key usage is incorrect."
  2517. case .keyBlobTypeIncorrect:
  2518. return "The key blob type is incorrect."
  2519. case .keyHeaderInconsistent:
  2520. return "The key header is inconsistent."
  2521. case .unsupportedKeyFormat:
  2522. return "The key header format is not supported."
  2523. case .unsupportedKeySize:
  2524. return "The key size is not supported."
  2525. case .invalidKeyUsageMask:
  2526. return "The key usage mask is not valid."
  2527. case .unsupportedKeyUsageMask:
  2528. return "The key usage mask is not supported."
  2529. case .invalidKeyAttributeMask:
  2530. return "The key attribute mask is not valid."
  2531. case .unsupportedKeyAttributeMask:
  2532. return "The key attribute mask is not supported."
  2533. case .invalidKeyLabel:
  2534. return "The key label is not valid."
  2535. case .unsupportedKeyLabel:
  2536. return "The key label is not supported."
  2537. case .invalidKeyFormat:
  2538. return "The key format is not valid."
  2539. case .unsupportedVectorOfBuffers:
  2540. return "The vector of buffers is not supported."
  2541. case .invalidInputVector:
  2542. return "The input vector is not valid."
  2543. case .invalidOutputVector:
  2544. return "The output vector is not valid."
  2545. case .invalidContext:
  2546. return "An invalid context was encountered."
  2547. case .invalidAlgorithm:
  2548. return "An invalid algorithm was encountered."
  2549. case .invalidAttributeKey:
  2550. return "A key attribute was not valid."
  2551. case .missingAttributeKey:
  2552. return "A key attribute was missing."
  2553. case .invalidAttributeInitVector:
  2554. return "An init vector attribute was not valid."
  2555. case .missingAttributeInitVector:
  2556. return "An init vector attribute was missing."
  2557. case .invalidAttributeSalt:
  2558. return "A salt attribute was not valid."
  2559. case .missingAttributeSalt:
  2560. return "A salt attribute was missing."
  2561. case .invalidAttributePadding:
  2562. return "A padding attribute was not valid."
  2563. case .missingAttributePadding:
  2564. return "A padding attribute was missing."
  2565. case .invalidAttributeRandom:
  2566. return "A random number attribute was not valid."
  2567. case .missingAttributeRandom:
  2568. return "A random number attribute was missing."
  2569. case .invalidAttributeSeed:
  2570. return "A seed attribute was not valid."
  2571. case .missingAttributeSeed:
  2572. return "A seed attribute was missing."
  2573. case .invalidAttributePassphrase:
  2574. return "A passphrase attribute was not valid."
  2575. case .missingAttributePassphrase:
  2576. return "A passphrase attribute was missing."
  2577. case .invalidAttributeKeyLength:
  2578. return "A key length attribute was not valid."
  2579. case .missingAttributeKeyLength:
  2580. return "A key length attribute was missing."
  2581. case .invalidAttributeBlockSize:
  2582. return "A block size attribute was not valid."
  2583. case .missingAttributeBlockSize:
  2584. return "A block size attribute was missing."
  2585. case .invalidAttributeOutputSize:
  2586. return "An output size attribute was not valid."
  2587. case .missingAttributeOutputSize:
  2588. return "An output size attribute was missing."
  2589. case .invalidAttributeRounds:
  2590. return "The number of rounds attribute was not valid."
  2591. case .missingAttributeRounds:
  2592. return "The number of rounds attribute was missing."
  2593. case .invalidAlgorithmParms:
  2594. return "An algorithm parameters attribute was not valid."
  2595. case .missingAlgorithmParms:
  2596. return "An algorithm parameters attribute was missing."
  2597. case .invalidAttributeLabel:
  2598. return "A label attribute was not valid."
  2599. case .missingAttributeLabel:
  2600. return "A label attribute was missing."
  2601. case .invalidAttributeKeyType:
  2602. return "A key type attribute was not valid."
  2603. case .missingAttributeKeyType:
  2604. return "A key type attribute was missing."
  2605. case .invalidAttributeMode:
  2606. return "A mode attribute was not valid."
  2607. case .missingAttributeMode:
  2608. return "A mode attribute was missing."
  2609. case .invalidAttributeEffectiveBits:
  2610. return "An effective bits attribute was not valid."
  2611. case .missingAttributeEffectiveBits:
  2612. return "An effective bits attribute was missing."
  2613. case .invalidAttributeStartDate:
  2614. return "A start date attribute was not valid."
  2615. case .missingAttributeStartDate:
  2616. return "A start date attribute was missing."
  2617. case .invalidAttributeEndDate:
  2618. return "An end date attribute was not valid."
  2619. case .missingAttributeEndDate:
  2620. return "An end date attribute was missing."
  2621. case .invalidAttributeVersion:
  2622. return "A version attribute was not valid."
  2623. case .missingAttributeVersion:
  2624. return "A version attribute was missing."
  2625. case .invalidAttributePrime:
  2626. return "A prime attribute was not valid."
  2627. case .missingAttributePrime:
  2628. return "A prime attribute was missing."
  2629. case .invalidAttributeBase:
  2630. return "A base attribute was not valid."
  2631. case .missingAttributeBase:
  2632. return "A base attribute was missing."
  2633. case .invalidAttributeSubprime:
  2634. return "A subprime attribute was not valid."
  2635. case .missingAttributeSubprime:
  2636. return "A subprime attribute was missing."
  2637. case .invalidAttributeIterationCount:
  2638. return "An iteration count attribute was not valid."
  2639. case .missingAttributeIterationCount:
  2640. return "An iteration count attribute was missing."
  2641. case .invalidAttributeDLDBHandle:
  2642. return "A database handle attribute was not valid."
  2643. case .missingAttributeDLDBHandle:
  2644. return "A database handle attribute was missing."
  2645. case .invalidAttributeAccessCredentials:
  2646. return "An access credentials attribute was not valid."
  2647. case .missingAttributeAccessCredentials:
  2648. return "An access credentials attribute was missing."
  2649. case .invalidAttributePublicKeyFormat:
  2650. return "A public key format attribute was not valid."
  2651. case .missingAttributePublicKeyFormat:
  2652. return "A public key format attribute was missing."
  2653. case .invalidAttributePrivateKeyFormat:
  2654. return "A private key format attribute was not valid."
  2655. case .missingAttributePrivateKeyFormat:
  2656. return "A private key format attribute was missing."
  2657. case .invalidAttributeSymmetricKeyFormat:
  2658. return "A symmetric key format attribute was not valid."
  2659. case .missingAttributeSymmetricKeyFormat:
  2660. return "A symmetric key format attribute was missing."
  2661. case .invalidAttributeWrappedKeyFormat:
  2662. return "A wrapped key format attribute was not valid."
  2663. case .missingAttributeWrappedKeyFormat:
  2664. return "A wrapped key format attribute was missing."
  2665. case .stagedOperationInProgress:
  2666. return "A staged operation is in progress."
  2667. case .stagedOperationNotStarted:
  2668. return "A staged operation was not started."
  2669. case .verifyFailed:
  2670. return "A cryptographic verification failure has occurred."
  2671. case .querySizeUnknown:
  2672. return "The query size is unknown."
  2673. case .blockSizeMismatch:
  2674. return "A block size mismatch occurred."
  2675. case .publicKeyInconsistent:
  2676. return "The public key was inconsistent."
  2677. case .deviceVerifyFailed:
  2678. return "A device verification failure has occurred."
  2679. case .invalidLoginName:
  2680. return "An invalid login name was detected."
  2681. case .alreadyLoggedIn:
  2682. return "The user is already logged in."
  2683. case .invalidDigestAlgorithm:
  2684. return "An invalid digest algorithm was detected."
  2685. case .invalidCRLGroup:
  2686. return "An invalid CRL group was detected."
  2687. case .certificateCannotOperate:
  2688. return "The certificate cannot operate."
  2689. case .certificateExpired:
  2690. return "An expired certificate was detected."
  2691. case .certificateNotValidYet:
  2692. return "The certificate is not yet valid."
  2693. case .certificateRevoked:
  2694. return "The certificate was revoked."
  2695. case .certificateSuspended:
  2696. return "The certificate was suspended."
  2697. case .insufficientCredentials:
  2698. return "Insufficient credentials were detected."
  2699. case .invalidAction:
  2700. return "The action was not valid."
  2701. case .invalidAuthority:
  2702. return "The authority was not valid."
  2703. case .verifyActionFailed:
  2704. return "A verify action has failed."
  2705. case .invalidCertAuthority:
  2706. return "The certificate authority was not valid."
  2707. case .invaldCRLAuthority:
  2708. return "The CRL authority was not valid."
  2709. case .invalidCRLEncoding:
  2710. return "The CRL encoding was not valid."
  2711. case .invalidCRLType:
  2712. return "The CRL type was not valid."
  2713. case .invalidCRL:
  2714. return "The CRL was not valid."
  2715. case .invalidFormType:
  2716. return "The form type was not valid."
  2717. case .invalidID:
  2718. return "The ID was not valid."
  2719. case .invalidIdentifier:
  2720. return "The identifier was not valid."
  2721. case .invalidIndex:
  2722. return "The index was not valid."
  2723. case .invalidPolicyIdentifiers:
  2724. return "The policy identifiers are not valid."
  2725. case .invalidTimeString:
  2726. return "The time specified was not valid."
  2727. case .invalidReason:
  2728. return "The trust policy reason was not valid."
  2729. case .invalidRequestInputs:
  2730. return "The request inputs are not valid."
  2731. case .invalidResponseVector:
  2732. return "The response vector was not valid."
  2733. case .invalidStopOnPolicy:
  2734. return "The stop-on policy was not valid."
  2735. case .invalidTuple:
  2736. return "The tuple was not valid."
  2737. case .multipleValuesUnsupported:
  2738. return "Multiple values are not supported."
  2739. case .notTrusted:
  2740. return "The trust policy was not trusted."
  2741. case .noDefaultAuthority:
  2742. return "No default authority was detected."
  2743. case .rejectedForm:
  2744. return "The trust policy had a rejected form."
  2745. case .requestLost:
  2746. return "The request was lost."
  2747. case .requestRejected:
  2748. return "The request was rejected."
  2749. case .unsupportedAddressType:
  2750. return "The address type is not supported."
  2751. case .unsupportedService:
  2752. return "The service is not supported."
  2753. case .invalidTupleGroup:
  2754. return "The tuple group was not valid."
  2755. case .invalidBaseACLs:
  2756. return "The base ACLs are not valid."
  2757. case .invalidTupleCredendtials:
  2758. return "The tuple credentials are not valid."
  2759. case .invalidEncoding:
  2760. return "The encoding was not valid."
  2761. case .invalidValidityPeriod:
  2762. return "The validity period was not valid."
  2763. case .invalidRequestor:
  2764. return "The requestor was not valid."
  2765. case .requestDescriptor:
  2766. return "The request descriptor was not valid."
  2767. case .invalidBundleInfo:
  2768. return "The bundle information was not valid."
  2769. case .invalidCRLIndex:
  2770. return "The CRL index was not valid."
  2771. case .noFieldValues:
  2772. return "No field values were detected."
  2773. case .unsupportedFieldFormat:
  2774. return "The field format is not supported."
  2775. case .unsupportedIndexInfo:
  2776. return "The index information is not supported."
  2777. case .unsupportedLocality:
  2778. return "The locality is not supported."
  2779. case .unsupportedNumAttributes:
  2780. return "The number of attributes is not supported."
  2781. case .unsupportedNumIndexes:
  2782. return "The number of indexes is not supported."
  2783. case .unsupportedNumRecordTypes:
  2784. return "The number of record types is not supported."
  2785. case .fieldSpecifiedMultiple:
  2786. return "Too many fields were specified."
  2787. case .incompatibleFieldFormat:
  2788. return "The field format was incompatible."
  2789. case .invalidParsingModule:
  2790. return "The parsing module was not valid."
  2791. case .databaseLocked:
  2792. return "The database is locked."
  2793. case .datastoreIsOpen:
  2794. return "The data store is open."
  2795. case .missingValue:
  2796. return "A missing value was detected."
  2797. case .unsupportedQueryLimits:
  2798. return "The query limits are not supported."
  2799. case .unsupportedNumSelectionPreds:
  2800. return "The number of selection predicates is not supported."
  2801. case .unsupportedOperator:
  2802. return "The operator is not supported."
  2803. case .invalidDBLocation:
  2804. return "The database location is not valid."
  2805. case .invalidAccessRequest:
  2806. return "The access request is not valid."
  2807. case .invalidIndexInfo:
  2808. return "The index information is not valid."
  2809. case .invalidNewOwner:
  2810. return "The new owner is not valid."
  2811. case .invalidModifyMode:
  2812. return "The modify mode is not valid."
  2813. case .missingRequiredExtension:
  2814. return "A required certificate extension is missing."
  2815. case .extendedKeyUsageNotCritical:
  2816. return "The extended key usage extension was not marked critical."
  2817. case .timestampMissing:
  2818. return "A timestamp was expected but was not found."
  2819. case .timestampInvalid:
  2820. return "The timestamp was not valid."
  2821. case .timestampNotTrusted:
  2822. return "The timestamp was not trusted."
  2823. case .timestampServiceNotAvailable:
  2824. return "The timestamp service is not available."
  2825. case .timestampBadAlg:
  2826. return "An unrecognized or unsupported Algorithm Identifier in timestamp."
  2827. case .timestampBadRequest:
  2828. return "The timestamp transaction is not permitted or supported."
  2829. case .timestampBadDataFormat:
  2830. return "The timestamp data submitted has the wrong format."
  2831. case .timestampTimeNotAvailable:
  2832. return "The time source for the Timestamp Authority is not available."
  2833. case .timestampUnacceptedPolicy:
  2834. return "The requested policy is not supported by the Timestamp Authority."
  2835. case .timestampUnacceptedExtension:
  2836. return "The requested extension is not supported by the Timestamp Authority."
  2837. case .timestampAddInfoNotAvailable:
  2838. return "The additional information requested is not available."
  2839. case .timestampSystemFailure:
  2840. return "The timestamp request cannot be handled due to system failure."
  2841. case .signingTimeMissing:
  2842. return "A signing time was expected but was not found."
  2843. case .timestampRejection:
  2844. return "A timestamp transaction was rejected."
  2845. case .timestampWaiting:
  2846. return "A timestamp transaction is waiting."
  2847. case .timestampRevocationWarning:
  2848. return "A timestamp authority revocation warning was issued."
  2849. case .timestampRevocationNotification:
  2850. return "A timestamp authority revocation notification was issued."
  2851. case .unexpectedError:
  2852. return "Unexpected error has occurred."
  2853. }
  2854. }
  2855. }
  2856. extension Status: CustomNSError {
  2857. public static let errorDomain = KeychainAccessErrorDomain
  2858. public var errorCode: Int {
  2859. return Int(rawValue)
  2860. }
  2861. public var errorUserInfo: [String : Any] {
  2862. return [NSLocalizedDescriptionKey: description]
  2863. }
  2864. }