12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074 |
- //
- // Keychain.swift
- // KeychainAccess
- //
- // Created by kishikawa katsumi on 2014/12/24.
- // Copyright (c) 2014 kishikawa katsumi. All rights reserved.
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- // THE SOFTWARE.
- import Foundation
- import Security
- #if os(iOS) || os(OSX)
- import LocalAuthentication
- #endif
- public let KeychainAccessErrorDomain = "com.kishikawakatsumi.KeychainAccess.error"
- public enum ItemClass {
- case genericPassword
- case internetPassword
- }
- public enum ProtocolType {
- case ftp
- case ftpAccount
- case http
- case irc
- case nntp
- case pop3
- case smtp
- case socks
- case imap
- case ldap
- case appleTalk
- case afp
- case telnet
- case ssh
- case ftps
- case https
- case httpProxy
- case httpsProxy
- case ftpProxy
- case smb
- case rtsp
- case rtspProxy
- case daap
- case eppc
- case ipp
- case nntps
- case ldaps
- case telnetS
- case imaps
- case ircs
- case pop3S
- }
- public enum AuthenticationType {
- case ntlm
- case msn
- case dpa
- case rpa
- case httpBasic
- case httpDigest
- case htmlForm
- case `default`
- }
- public enum Accessibility {
- /**
- Item data can only be accessed
- while the device is unlocked. This is recommended for items that only
- need be accesible while the application is in the foreground. Items
- with this attribute will migrate to a new device when using encrypted
- backups.
- */
- case whenUnlocked
- /**
- Item data can only be
- accessed once the device has been unlocked after a restart. This is
- recommended for items that need to be accesible by background
- applications. Items with this attribute will migrate to a new device
- when using encrypted backups.
- */
- case afterFirstUnlock
- /**
- Item data can always be accessed
- regardless of the lock state of the device. This is not recommended
- for anything except system use. Items with this attribute will migrate
- to a new device when using encrypted backups.
- */
- @available(macCatalyst, unavailable)
- case always
- /**
- Item data can
- only be accessed while the device is unlocked. This class is only
- available if a passcode is set on the device. This is recommended for
- items that only need to be accessible while the application is in the
- foreground. Items with this attribute will never migrate to a new
- device, so after a backup is restored to a new device, these items
- will be missing. No items can be stored in this class on devices
- without a passcode. Disabling the device passcode will cause all
- items in this class to be deleted.
- */
- @available(iOS 8.0, OSX 10.10, *)
- case whenPasscodeSetThisDeviceOnly
- /**
- Item data can only
- be accessed while the device is unlocked. This is recommended for items
- that only need be accesible while the application is in the foreground.
- Items with this attribute will never migrate to a new device, so after
- a backup is restored to a new device, these items will be missing.
- */
- case whenUnlockedThisDeviceOnly
- /**
- Item data can
- only be accessed once the device has been unlocked after a restart.
- This is recommended for items that need to be accessible by background
- applications. Items with this attribute will never migrate to a new
- device, so after a backup is restored to a new device these items will
- be missing.
- */
- case afterFirstUnlockThisDeviceOnly
- /**
- Item data can always
- be accessed regardless of the lock state of the device. This option
- is not recommended for anything except system use. Items with this
- attribute will never migrate to a new device, so after a backup is
- restored to a new device, these items will be missing.
- */
- @available(macCatalyst, unavailable)
- case alwaysThisDeviceOnly
- }
- /**
- Predefined item attribute constants used to get or set values
- in a dictionary. The kSecUseAuthenticationUI constant is the key and its
- value is one of the constants defined here.
- If the key kSecUseAuthenticationUI not provided then kSecUseAuthenticationUIAllow
- is used as default.
- */
- public enum AuthenticationUI {
- /**
- Specifies that authenticate UI can appear.
- */
- case allow
- /**
- Specifies that the error
- errSecInteractionNotAllowed will be returned if an item needs
- to authenticate with UI
- */
- case fail
- /**
- Specifies that all items which need
- to authenticate with UI will be silently skipped. This value can be used
- only with SecItemCopyMatching.
- */
- case skip
- }
- @available(iOS 9.0, OSX 10.11, *)
- extension AuthenticationUI {
- public var rawValue: String {
- switch self {
- case .allow:
- return UseAuthenticationUIAllow
- case .fail:
- return UseAuthenticationUIFail
- case .skip:
- return UseAuthenticationUISkip
- }
- }
- public var description: String {
- switch self {
- case .allow:
- return "allow"
- case .fail:
- return "fail"
- case .skip:
- return "skip"
- }
- }
- }
- public struct AuthenticationPolicy: OptionSet {
- /**
- User presence policy using Touch ID or Passcode. Touch ID does not
- have to be available or enrolled. Item is still accessible by Touch ID
- even if fingers are added or removed.
- */
- @available(iOS 8.0, OSX 10.10, watchOS 2.0, tvOS 8.0, *)
- public static let userPresence = AuthenticationPolicy(rawValue: 1 << 0)
- /**
- Constraint: Touch ID (any finger) or Face ID. Touch ID or Face ID must be available. With Touch ID
- at least one finger must be enrolled. With Face ID user has to be enrolled. Item is still accessible by Touch ID even
- if fingers are added or removed. Item is still accessible by Face ID if user is re-enrolled.
- */
- @available(iOS 11.3, OSX 10.13.4, watchOS 4.3, tvOS 11.3, *)
- public static let biometryAny = AuthenticationPolicy(rawValue: 1 << 1)
- /**
- Deprecated, please use biometryAny instead.
- */
- @available(iOS, introduced: 9.0, deprecated: 11.3, renamed: "biometryAny")
- @available(OSX, introduced: 10.12.1, deprecated: 10.13.4, renamed: "biometryAny")
- @available(watchOS, introduced: 2.0, deprecated: 4.3, renamed: "biometryAny")
- @available(tvOS, introduced: 9.0, deprecated: 11.3, renamed: "biometryAny")
- public static let touchIDAny = AuthenticationPolicy(rawValue: 1 << 1)
- /**
- Constraint: Touch ID from the set of currently enrolled fingers. Touch ID must be available and at least one finger must
- be enrolled. When fingers are added or removed, the item is invalidated. When Face ID is re-enrolled this item is invalidated.
- */
- @available(iOS 11.3, OSX 10.13, watchOS 4.3, tvOS 11.3, *)
- public static let biometryCurrentSet = AuthenticationPolicy(rawValue: 1 << 3)
- /**
- Deprecated, please use biometryCurrentSet instead.
- */
- @available(iOS, introduced: 9.0, deprecated: 11.3, renamed: "biometryCurrentSet")
- @available(OSX, introduced: 10.12.1, deprecated: 10.13.4, renamed: "biometryCurrentSet")
- @available(watchOS, introduced: 2.0, deprecated: 4.3, renamed: "biometryCurrentSet")
- @available(tvOS, introduced: 9.0, deprecated: 11.3, renamed: "biometryCurrentSet")
- public static let touchIDCurrentSet = AuthenticationPolicy(rawValue: 1 << 3)
- /**
- Constraint: Device passcode
- */
- @available(iOS 9.0, OSX 10.11, watchOS 2.0, tvOS 9.0, *)
- public static let devicePasscode = AuthenticationPolicy(rawValue: 1 << 4)
- /**
- Constraint: Watch
- */
- @available(iOS, unavailable)
- @available(OSX 10.15, *)
- @available(watchOS, unavailable)
- @available(tvOS, unavailable)
- public static let watch = AuthenticationPolicy(rawValue: 1 << 5)
- /**
- Constraint logic operation: when using more than one constraint,
- at least one of them must be satisfied.
- */
- @available(iOS 9.0, OSX 10.12.1, watchOS 2.0, tvOS 9.0, *)
- public static let or = AuthenticationPolicy(rawValue: 1 << 14)
- /**
- Constraint logic operation: when using more than one constraint,
- all must be satisfied.
- */
- @available(iOS 9.0, OSX 10.12.1, watchOS 2.0, tvOS 9.0, *)
- public static let and = AuthenticationPolicy(rawValue: 1 << 15)
- /**
- Create access control for private key operations (i.e. sign operation)
- */
- @available(iOS 9.0, OSX 10.12.1, watchOS 2.0, tvOS 9.0, *)
- public static let privateKeyUsage = AuthenticationPolicy(rawValue: 1 << 30)
- /**
- Security: Application provided password for data encryption key generation.
- This is not a constraint but additional item encryption mechanism.
- */
- @available(iOS 9.0, OSX 10.12.1, watchOS 2.0, tvOS 9.0, *)
- public static let applicationPassword = AuthenticationPolicy(rawValue: 1 << 31)
- #if swift(>=2.3)
- public let rawValue: UInt
- public init(rawValue: UInt) {
- self.rawValue = rawValue
- }
- #else
- public let rawValue: Int
- public init(rawValue: Int) {
- self.rawValue = rawValue
- }
- #endif
- }
- public struct Attributes {
- public var `class`: String? {
- return attributes[Class] as? String
- }
- public var data: Data? {
- return attributes[ValueData] as? Data
- }
- public var ref: Data? {
- return attributes[ValueRef] as? Data
- }
- public var persistentRef: Data? {
- return attributes[ValuePersistentRef] as? Data
- }
- public var accessible: String? {
- return attributes[AttributeAccessible] as? String
- }
- public var accessControl: SecAccessControl? {
- if #available(OSX 10.10, *) {
- if let accessControl = attributes[AttributeAccessControl] {
- return (accessControl as! SecAccessControl)
- }
- return nil
- } else {
- return nil
- }
- }
- public var accessGroup: String? {
- return attributes[AttributeAccessGroup] as? String
- }
- public var synchronizable: Bool? {
- return attributes[AttributeSynchronizable] as? Bool
- }
- public var creationDate: Date? {
- return attributes[AttributeCreationDate] as? Date
- }
- public var modificationDate: Date? {
- return attributes[AttributeModificationDate] as? Date
- }
- public var attributeDescription: String? {
- return attributes[AttributeDescription] as? String
- }
- public var comment: String? {
- return attributes[AttributeComment] as? String
- }
- public var creator: String? {
- return attributes[AttributeCreator] as? String
- }
- public var type: String? {
- return attributes[AttributeType] as? String
- }
- public var label: String? {
- return attributes[AttributeLabel] as? String
- }
- public var isInvisible: Bool? {
- return attributes[AttributeIsInvisible] as? Bool
- }
- public var isNegative: Bool? {
- return attributes[AttributeIsNegative] as? Bool
- }
- public var account: String? {
- return attributes[AttributeAccount] as? String
- }
- public var service: String? {
- return attributes[AttributeService] as? String
- }
- public var generic: Data? {
- return attributes[AttributeGeneric] as? Data
- }
- public var securityDomain: String? {
- return attributes[AttributeSecurityDomain] as? String
- }
- public var server: String? {
- return attributes[AttributeServer] as? String
- }
- public var `protocol`: String? {
- return attributes[AttributeProtocol] as? String
- }
- public var authenticationType: String? {
- return attributes[AttributeAuthenticationType] as? String
- }
- public var port: Int? {
- return attributes[AttributePort] as? Int
- }
- public var path: String? {
- return attributes[AttributePath] as? String
- }
- fileprivate let attributes: [String: Any]
- init(attributes: [String: Any]) {
- self.attributes = attributes
- }
- public subscript(key: String) -> Any? {
- get {
- return attributes[key]
- }
- }
- }
- public final class Keychain {
- public var itemClass: ItemClass {
- return options.itemClass
- }
- public var service: String {
- return options.service
- }
- // This attribute (kSecAttrAccessGroup) applies to macOS keychain items only if you also set a value of true for the
- // kSecUseDataProtectionKeychain key, the kSecAttrSynchronizable key, or both.
- public var accessGroup: String? {
- return options.accessGroup
- }
- public var server: URL {
- return options.server
- }
- public var protocolType: ProtocolType {
- return options.protocolType
- }
- public var authenticationType: AuthenticationType {
- return options.authenticationType
- }
- public var accessibility: Accessibility {
- return options.accessibility
- }
- @available(iOS 8.0, OSX 10.10, *)
- @available(watchOS, unavailable)
- public var authenticationPolicy: AuthenticationPolicy? {
- return options.authenticationPolicy
- }
- public var synchronizable: Bool {
- return options.synchronizable
- }
- public var label: String? {
- return options.label
- }
- public var comment: String? {
- return options.comment
- }
- @available(iOS 8.0, OSX 10.10, *)
- @available(watchOS, unavailable)
- public var authenticationPrompt: String? {
- return options.authenticationPrompt
- }
- @available(iOS 9.0, OSX 10.11, *)
- public var authenticationUI: AuthenticationUI {
- return options.authenticationUI ?? .allow
- }
- #if os(iOS) || os(OSX)
- @available(iOS 9.0, OSX 10.11, *)
- public var authenticationContext: LAContext? {
- return options.authenticationContext as? LAContext
- }
- #endif
- fileprivate let options: Options
- // MARK:
- public convenience init() {
- var options = Options()
- if let bundleIdentifier = Bundle.main.bundleIdentifier {
- options.service = bundleIdentifier
- }
- self.init(options)
- }
- public convenience init(service: String) {
- var options = Options()
- options.service = service
- self.init(options)
- }
- public convenience init(accessGroup: String) {
- var options = Options()
- if let bundleIdentifier = Bundle.main.bundleIdentifier {
- options.service = bundleIdentifier
- }
- options.accessGroup = accessGroup
- self.init(options)
- }
- public convenience init(service: String, accessGroup: String) {
- var options = Options()
- options.service = service
- options.accessGroup = accessGroup
- self.init(options)
- }
- public convenience init(server: String, protocolType: ProtocolType, accessGroup: String? = nil, authenticationType: AuthenticationType = .default) {
- self.init(server: URL(string: server)!, protocolType: protocolType, accessGroup: accessGroup, authenticationType: authenticationType)
- }
- public convenience init(server: URL, protocolType: ProtocolType, accessGroup: String? = nil, authenticationType: AuthenticationType = .default) {
- var options = Options()
- options.itemClass = .internetPassword
- options.server = server
- options.protocolType = protocolType
- options.accessGroup = accessGroup
- options.authenticationType = authenticationType
- self.init(options)
- }
- fileprivate init(_ opts: Options) {
- options = opts
- }
- // MARK:
- public func accessibility(_ accessibility: Accessibility) -> Keychain {
- var options = self.options
- options.accessibility = accessibility
- return Keychain(options)
- }
- @available(iOS 8.0, OSX 10.10, *)
- @available(watchOS, unavailable)
- public func accessibility(_ accessibility: Accessibility, authenticationPolicy: AuthenticationPolicy) -> Keychain {
- var options = self.options
- options.accessibility = accessibility
- options.authenticationPolicy = authenticationPolicy
- return Keychain(options)
- }
- public func synchronizable(_ synchronizable: Bool) -> Keychain {
- var options = self.options
- options.synchronizable = synchronizable
- return Keychain(options)
- }
- public func label(_ label: String) -> Keychain {
- var options = self.options
- options.label = label
- return Keychain(options)
- }
- public func comment(_ comment: String) -> Keychain {
- var options = self.options
- options.comment = comment
- return Keychain(options)
- }
- public func attributes(_ attributes: [String: Any]) -> Keychain {
- var options = self.options
- attributes.forEach { options.attributes.updateValue($1, forKey: $0) }
- return Keychain(options)
- }
- @available(iOS 8.0, OSX 10.10, *)
- @available(watchOS, unavailable)
- public func authenticationPrompt(_ authenticationPrompt: String) -> Keychain {
- var options = self.options
- options.authenticationPrompt = authenticationPrompt
- return Keychain(options)
- }
- @available(iOS 9.0, OSX 10.11, *)
- public func authenticationUI(_ authenticationUI: AuthenticationUI) -> Keychain {
- var options = self.options
- options.authenticationUI = authenticationUI
- return Keychain(options)
- }
- #if os(iOS) || os(OSX)
- @available(iOS 9.0, OSX 10.11, *)
- public func authenticationContext(_ authenticationContext: LAContext) -> Keychain {
- var options = self.options
- options.authenticationContext = authenticationContext
- return Keychain(options)
- }
- #endif
- // MARK:
- public func get(_ key: String, ignoringAttributeSynchronizable: Bool = true) throws -> String? {
- return try getString(key, ignoringAttributeSynchronizable: ignoringAttributeSynchronizable)
- }
- public func getString(_ key: String, ignoringAttributeSynchronizable: Bool = true) throws -> String? {
- guard let data = try getData(key, ignoringAttributeSynchronizable: ignoringAttributeSynchronizable) else {
- return nil
- }
- guard let string = String(data: data, encoding: .utf8) else {
- print("failed to convert data to string")
- throw Status.conversionError
- }
- return string
- }
- public func getData(_ key: String, ignoringAttributeSynchronizable: Bool = true) throws -> Data? {
- var query = options.query(ignoringAttributeSynchronizable: ignoringAttributeSynchronizable)
- query[MatchLimit] = MatchLimitOne
- query[ReturnData] = kCFBooleanTrue
- query[AttributeAccount] = key
- var result: AnyObject?
- let status = SecItemCopyMatching(query as CFDictionary, &result)
- switch status {
- case errSecSuccess:
- guard let data = result as? Data else {
- throw Status.unexpectedError
- }
- return data
- case errSecItemNotFound:
- return nil
- default:
- throw securityError(status: status)
- }
- }
- public func get<T>(_ key: String, ignoringAttributeSynchronizable: Bool = true, handler: (Attributes?) -> T) throws -> T {
- var query = options.query(ignoringAttributeSynchronizable: ignoringAttributeSynchronizable)
- query[MatchLimit] = MatchLimitOne
- query[ReturnData] = kCFBooleanTrue
- query[ReturnAttributes] = kCFBooleanTrue
- query[ReturnRef] = kCFBooleanTrue
- query[ReturnPersistentRef] = kCFBooleanTrue
- query[AttributeAccount] = key
- var result: AnyObject?
- let status = SecItemCopyMatching(query as CFDictionary, &result)
- switch status {
- case errSecSuccess:
- guard let attributes = result as? [String: Any] else {
- throw Status.unexpectedError
- }
- return handler(Attributes(attributes: attributes))
- case errSecItemNotFound:
- return handler(nil)
- default:
- throw securityError(status: status)
- }
- }
- // MARK:
- public func set(_ value: String, key: String, ignoringAttributeSynchronizable: Bool = true) throws {
- guard let data = value.data(using: .utf8, allowLossyConversion: false) else {
- print("failed to convert string to data")
- throw Status.conversionError
- }
- try set(data, key: key, ignoringAttributeSynchronizable: ignoringAttributeSynchronizable)
- }
- public func set(_ value: Data, key: String, ignoringAttributeSynchronizable: Bool = true) throws {
- var query = options.query(ignoringAttributeSynchronizable: ignoringAttributeSynchronizable)
- query[AttributeAccount] = key
- #if os(iOS)
- if #available(iOS 9.0, *) {
- if let authenticationUI = options.authenticationUI {
- query[UseAuthenticationUI] = authenticationUI.rawValue
- } else {
- query[UseAuthenticationUI] = UseAuthenticationUIFail
- }
- } else {
- query[UseNoAuthenticationUI] = kCFBooleanTrue
- }
- #elseif os(OSX)
- query[ReturnData] = kCFBooleanTrue
- if #available(OSX 10.11, *) {
- if let authenticationUI = options.authenticationUI {
- query[UseAuthenticationUI] = authenticationUI.rawValue
- } else {
- query[UseAuthenticationUI] = UseAuthenticationUIFail
- }
- }
- #else
- if let authenticationUI = options.authenticationUI {
- query[UseAuthenticationUI] = authenticationUI.rawValue
- }
- #endif
- var status = SecItemCopyMatching(query as CFDictionary, nil)
- switch status {
- case errSecSuccess, errSecInteractionNotAllowed:
- var query = options.query()
- query[AttributeAccount] = key
- var (attributes, error) = options.attributes(key: nil, value: value)
- if let error = error {
- print(error.localizedDescription)
- throw error
- }
- options.attributes.forEach { attributes.updateValue($1, forKey: $0) }
- #if os(iOS)
- if status == errSecInteractionNotAllowed && floor(NSFoundationVersionNumber) <= floor(NSFoundationVersionNumber_iOS_8_0) {
- try remove(key)
- try set(value, key: key)
- } else {
- status = SecItemUpdate(query as CFDictionary, attributes as CFDictionary)
- if status != errSecSuccess {
- throw securityError(status: status)
- }
- }
- #else
- status = SecItemUpdate(query as CFDictionary, attributes as CFDictionary)
- if status != errSecSuccess {
- throw securityError(status: status)
- }
- #endif
- case errSecItemNotFound:
- var (attributes, error) = options.attributes(key: key, value: value)
- if let error = error {
- print(error.localizedDescription)
- throw error
- }
- options.attributes.forEach { attributes.updateValue($1, forKey: $0) }
- status = SecItemAdd(attributes as CFDictionary, nil)
- if status != errSecSuccess {
- throw securityError(status: status)
- }
- default:
- throw securityError(status: status)
- }
- }
- public subscript(key: String) -> String? {
- get {
- #if swift(>=5.0)
- return try? get(key)
- #else
- return (try? get(key)).flatMap { $0 }
- #endif
- }
- set {
- if let value = newValue {
- do {
- try set(value, key: key)
- } catch {}
- } else {
- do {
- try remove(key)
- } catch {}
- }
- }
- }
- public subscript(string key: String) -> String? {
- get {
- return self[key]
- }
- set {
- self[key] = newValue
- }
- }
- public subscript(data key: String) -> Data? {
- get {
- #if swift(>=5.0)
- return try? getData(key)
- #else
- return (try? getData(key)).flatMap { $0 }
- #endif
- }
- set {
- if let value = newValue {
- do {
- try set(value, key: key)
- } catch {}
- } else {
- do {
- try remove(key)
- } catch {}
- }
- }
- }
- public subscript(attributes key: String) -> Attributes? {
- get {
- #if swift(>=5.0)
- return try? get(key) { $0 }
- #else
- return (try? get(key) { $0 }).flatMap { $0 }
- #endif
- }
- }
- // MARK:
- public func remove(_ key: String, ignoringAttributeSynchronizable: Bool = true) throws {
- var query = options.query(ignoringAttributeSynchronizable: ignoringAttributeSynchronizable)
- query[AttributeAccount] = key
- let status = SecItemDelete(query as CFDictionary)
- if status != errSecSuccess && status != errSecItemNotFound {
- throw securityError(status: status)
- }
- }
- public func removeAll() throws {
- var query = options.query()
- #if !os(iOS) && !os(watchOS) && !os(tvOS)
- query[MatchLimit] = MatchLimitAll
- #endif
- let status = SecItemDelete(query as CFDictionary)
- if status != errSecSuccess && status != errSecItemNotFound {
- throw securityError(status: status)
- }
- }
- // MARK:
- public func contains(_ key: String, withoutAuthenticationUI: Bool = false) throws -> Bool {
- var query = options.query()
- query[AttributeAccount] = key
- if withoutAuthenticationUI {
- #if os(iOS) || os(watchOS) || os(tvOS)
- if #available(iOS 9.0, *) {
- if let authenticationUI = options.authenticationUI {
- query[UseAuthenticationUI] = authenticationUI.rawValue
- } else {
- query[UseAuthenticationUI] = UseAuthenticationUIFail
- }
- } else {
- query[UseNoAuthenticationUI] = kCFBooleanTrue
- }
- #else
- if #available(OSX 10.11, *) {
- if let authenticationUI = options.authenticationUI {
- query[UseAuthenticationUI] = authenticationUI.rawValue
- } else {
- query[UseAuthenticationUI] = UseAuthenticationUIFail
- }
- } else if #available(OSX 10.10, *) {
- query[UseNoAuthenticationUI] = kCFBooleanTrue
- }
- #endif
- } else {
- if #available(iOS 9.0, OSX 10.11, *) {
- if let authenticationUI = options.authenticationUI {
- query[UseAuthenticationUI] = authenticationUI.rawValue
- }
- }
- }
-
- let status = SecItemCopyMatching(query as CFDictionary, nil)
- switch status {
- case errSecSuccess:
- return true
- case errSecInteractionNotAllowed:
- if withoutAuthenticationUI {
- return true
- }
- return false
- case errSecItemNotFound:
- return false
- default:
- throw securityError(status: status)
- }
- }
- // MARK:
- public class func allKeys(_ itemClass: ItemClass) -> [(String, String)] {
- var query = [String: Any]()
- query[Class] = itemClass.rawValue
- query[AttributeSynchronizable] = SynchronizableAny
- query[MatchLimit] = MatchLimitAll
- query[ReturnAttributes] = kCFBooleanTrue
- var result: AnyObject?
- let status = SecItemCopyMatching(query as CFDictionary, &result)
- switch status {
- case errSecSuccess:
- if let items = result as? [[String: Any]] {
- return prettify(itemClass: itemClass, items: items).map {
- switch itemClass {
- case .genericPassword:
- return (($0["service"] ?? "") as! String, ($0["key"] ?? "") as! String)
- case .internetPassword:
- return (($0["server"] ?? "") as! String, ($0["key"] ?? "") as! String)
- }
- }
- }
- case errSecItemNotFound:
- return []
- default: ()
- }
- securityError(status: status)
- return []
- }
- public func allKeys() -> [String] {
- let allItems = type(of: self).prettify(itemClass: itemClass, items: items())
- let filter: ([String: Any]) -> String? = { $0["key"] as? String }
- #if swift(>=4.1)
- return allItems.compactMap(filter)
- #else
- return allItems.flatMap(filter)
- #endif
- }
- public class func allItems(_ itemClass: ItemClass) -> [[String: Any]] {
- var query = [String: Any]()
- query[Class] = itemClass.rawValue
- query[MatchLimit] = MatchLimitAll
- query[ReturnAttributes] = kCFBooleanTrue
- #if os(iOS) || os(watchOS) || os(tvOS)
- query[ReturnData] = kCFBooleanTrue
- #endif
- var result: AnyObject?
- let status = SecItemCopyMatching(query as CFDictionary, &result)
- switch status {
- case errSecSuccess:
- if let items = result as? [[String: Any]] {
- return prettify(itemClass: itemClass, items: items)
- }
- case errSecItemNotFound:
- return []
- default: ()
- }
- securityError(status: status)
- return []
- }
- public func allItems() -> [[String: Any]] {
- return type(of: self).prettify(itemClass: itemClass, items: items())
- }
- #if os(iOS) && !targetEnvironment(macCatalyst)
- @available(iOS 8.0, *)
- public func getSharedPassword(_ completion: @escaping (_ account: String?, _ password: String?, _ error: Error?) -> () = { account, password, error -> () in }) {
- if let domain = server.host {
- type(of: self).requestSharedWebCredential(domain: domain, account: nil) { (credentials, error) -> () in
- if let credential = credentials.first {
- let account = credential["account"]
- let password = credential["password"]
- completion(account, password, error)
- } else {
- completion(nil, nil, error)
- }
- }
- } else {
- let error = securityError(status: Status.param.rawValue)
- completion(nil, nil, error)
- }
- }
- #endif
- #if os(iOS) && !targetEnvironment(macCatalyst)
- @available(iOS 8.0, *)
- public func getSharedPassword(_ account: String, completion: @escaping (_ password: String?, _ error: Error?) -> () = { password, error -> () in }) {
- if let domain = server.host {
- type(of: self).requestSharedWebCredential(domain: domain, account: account) { (credentials, error) -> () in
- if let credential = credentials.first {
- if let password = credential["password"] {
- completion(password, error)
- } else {
- completion(nil, error)
- }
- } else {
- completion(nil, error)
- }
- }
- } else {
- let error = securityError(status: Status.param.rawValue)
- completion(nil, error)
- }
- }
- #endif
- #if os(iOS) && !targetEnvironment(macCatalyst)
- @available(iOS 8.0, *)
- public func setSharedPassword(_ password: String, account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in }) {
- setSharedPassword(password as String?, account: account, completion: completion)
- }
- #endif
- #if os(iOS) && !targetEnvironment(macCatalyst)
- @available(iOS 8.0, *)
- fileprivate func setSharedPassword(_ password: String?, account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in }) {
- if let domain = server.host {
- SecAddSharedWebCredential(domain as CFString, account as CFString, password as CFString?) { error -> () in
- if let error = error {
- completion(error.error)
- } else {
- completion(nil)
- }
- }
- } else {
- let error = securityError(status: Status.param.rawValue)
- completion(error)
- }
- }
- #endif
- #if os(iOS) && !targetEnvironment(macCatalyst)
- @available(iOS 8.0, *)
- public func removeSharedPassword(_ account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in }) {
- setSharedPassword(nil, account: account, completion: completion)
- }
- #endif
- #if os(iOS) && !targetEnvironment(macCatalyst)
- @available(iOS 8.0, *)
- public class func requestSharedWebCredential(_ completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in }) {
- requestSharedWebCredential(domain: nil, account: nil, completion: completion)
- }
- #endif
- #if os(iOS) && !targetEnvironment(macCatalyst)
- @available(iOS 8.0, *)
- public class func requestSharedWebCredential(domain: String, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in }) {
- requestSharedWebCredential(domain: domain, account: nil, completion: completion)
- }
- #endif
- #if os(iOS) && !targetEnvironment(macCatalyst)
- @available(iOS 8.0, *)
- public class func requestSharedWebCredential(domain: String, account: String, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in }) {
- requestSharedWebCredential(domain: Optional(domain), account: Optional(account)!, completion: completion)
- }
- #endif
- #if os(iOS) && !targetEnvironment(macCatalyst)
- @available(iOS 8.0, *)
- fileprivate class func requestSharedWebCredential(domain: String?, account: String?, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> ()) {
- SecRequestSharedWebCredential(domain as CFString?, account as CFString?) { (credentials, error) -> () in
- var remoteError: NSError?
- if let error = error {
- remoteError = error.error
- if remoteError?.code != Int(errSecItemNotFound) {
- print("error:[\(remoteError!.code)] \(remoteError!.localizedDescription)")
- }
- }
- if let credentials = credentials {
- let credentials = (credentials as NSArray).map { credentials -> [String: String] in
- var credential = [String: String]()
- if let credentials = credentials as? [String: String] {
- if let server = credentials[AttributeServer] {
- credential["server"] = server
- }
- if let account = credentials[AttributeAccount] {
- credential["account"] = account
- }
- if let password = credentials[SharedPassword] {
- credential["password"] = password
- }
- }
- return credential
- }
- completion(credentials, remoteError)
- } else {
- completion([], remoteError)
- }
- }
- }
- #endif
- #if os(iOS) && !targetEnvironment(macCatalyst)
- /**
- @abstract Returns a randomly generated password.
- @return String password in the form xxx-xxx-xxx-xxx where x is taken from the sets "abcdefghkmnopqrstuvwxy", "ABCDEFGHJKLMNPQRSTUVWXYZ", "3456789" with at least one character from each set being present.
- */
- @available(iOS 8.0, *)
- public class func generatePassword() -> String {
- return SecCreateSharedWebCredentialPassword()! as String
- }
- #endif
- // MARK:
- fileprivate func items() -> [[String: Any]] {
- var query = options.query()
- query[MatchLimit] = MatchLimitAll
- query[ReturnAttributes] = kCFBooleanTrue
- #if os(iOS) || os(watchOS) || os(tvOS)
- query[ReturnData] = kCFBooleanTrue
- #endif
- var result: AnyObject?
- let status = SecItemCopyMatching(query as CFDictionary, &result)
- switch status {
- case errSecSuccess:
- if let items = result as? [[String: Any]] {
- return items
- }
- case errSecItemNotFound:
- return []
- default: ()
- }
- securityError(status: status)
- return []
- }
- fileprivate class func prettify(itemClass: ItemClass, items: [[String: Any]]) -> [[String: Any]] {
- let items = items.map { attributes -> [String: Any] in
- var item = [String: Any]()
- item["class"] = itemClass.description
-
- if let accessGroup = attributes[AttributeAccessGroup] as? String {
- item["accessGroup"] = accessGroup
- }
- switch itemClass {
- case .genericPassword:
- if let service = attributes[AttributeService] as? String {
- item["service"] = service
- }
- case .internetPassword:
- if let server = attributes[AttributeServer] as? String {
- item["server"] = server
- }
- if let proto = attributes[AttributeProtocol] as? String {
- if let protocolType = ProtocolType(rawValue: proto) {
- item["protocol"] = protocolType.description
- }
- }
- if let auth = attributes[AttributeAuthenticationType] as? String {
- if let authenticationType = AuthenticationType(rawValue: auth) {
- item["authenticationType"] = authenticationType.description
- }
- }
- }
- if let key = attributes[AttributeAccount] as? String {
- item["key"] = key
- }
- if let data = attributes[ValueData] as? Data {
- if let text = String(data: data, encoding: .utf8) {
- item["value"] = text
- } else {
- item["value"] = data
- }
- }
- if let accessible = attributes[AttributeAccessible] as? String {
- if let accessibility = Accessibility(rawValue: accessible) {
- item["accessibility"] = accessibility.description
- }
- }
- if let synchronizable = attributes[AttributeSynchronizable] as? Bool {
- item["synchronizable"] = synchronizable ? "true" : "false"
- }
- return item
- }
- return items
- }
- // MARK:
- @discardableResult
- fileprivate class func securityError(status: OSStatus) -> Error {
- let error = Status(status: status)
- if error != .userCanceled {
- print("OSStatus error:[\(error.errorCode)] \(error.description)")
- }
- return error
- }
- @discardableResult
- fileprivate func securityError(status: OSStatus) -> Error {
- return type(of: self).securityError(status: status)
- }
- }
- struct Options {
- var itemClass: ItemClass = .genericPassword
- var service: String = ""
- var accessGroup: String? = nil
- var server: URL!
- var protocolType: ProtocolType!
- var authenticationType: AuthenticationType = .default
- var accessibility: Accessibility = .afterFirstUnlock
- var authenticationPolicy: AuthenticationPolicy?
- var synchronizable: Bool = false
- var label: String?
- var comment: String?
- var authenticationPrompt: String?
- var authenticationUI: AuthenticationUI?
- var authenticationContext: AnyObject?
- var attributes = [String: Any]()
- }
- /** Class Key Constant */
- private let Class = String(kSecClass)
- /** Attribute Key Constants */
- private let AttributeAccessible = String(kSecAttrAccessible)
- @available(iOS 8.0, OSX 10.10, *)
- private let AttributeAccessControl = String(kSecAttrAccessControl)
- private let AttributeAccessGroup = String(kSecAttrAccessGroup)
- private let AttributeSynchronizable = String(kSecAttrSynchronizable)
- private let AttributeCreationDate = String(kSecAttrCreationDate)
- private let AttributeModificationDate = String(kSecAttrModificationDate)
- private let AttributeDescription = String(kSecAttrDescription)
- private let AttributeComment = String(kSecAttrComment)
- private let AttributeCreator = String(kSecAttrCreator)
- private let AttributeType = String(kSecAttrType)
- private let AttributeLabel = String(kSecAttrLabel)
- private let AttributeIsInvisible = String(kSecAttrIsInvisible)
- private let AttributeIsNegative = String(kSecAttrIsNegative)
- private let AttributeAccount = String(kSecAttrAccount)
- private let AttributeService = String(kSecAttrService)
- private let AttributeGeneric = String(kSecAttrGeneric)
- private let AttributeSecurityDomain = String(kSecAttrSecurityDomain)
- private let AttributeServer = String(kSecAttrServer)
- private let AttributeProtocol = String(kSecAttrProtocol)
- private let AttributeAuthenticationType = String(kSecAttrAuthenticationType)
- private let AttributePort = String(kSecAttrPort)
- private let AttributePath = String(kSecAttrPath)
- private let SynchronizableAny = kSecAttrSynchronizableAny
- /** Search Constants */
- private let MatchLimit = String(kSecMatchLimit)
- private let MatchLimitOne = kSecMatchLimitOne
- private let MatchLimitAll = kSecMatchLimitAll
- /** Return Type Key Constants */
- private let ReturnData = String(kSecReturnData)
- private let ReturnAttributes = String(kSecReturnAttributes)
- private let ReturnRef = String(kSecReturnRef)
- private let ReturnPersistentRef = String(kSecReturnPersistentRef)
- /** Value Type Key Constants */
- private let ValueData = String(kSecValueData)
- private let ValueRef = String(kSecValueRef)
- private let ValuePersistentRef = String(kSecValuePersistentRef)
- /** Other Constants */
- @available(iOS 8.0, OSX 10.10, tvOS 8.0, *)
- private let UseOperationPrompt = String(kSecUseOperationPrompt)
- @available(iOS, introduced: 8.0, deprecated: 9.0, message: "Use a UseAuthenticationUI instead.")
- @available(OSX, introduced: 10.10, deprecated: 10.11, message: "Use UseAuthenticationUI instead.")
- @available(watchOS, introduced: 2.0, deprecated: 2.0, message: "Use UseAuthenticationUI instead.")
- @available(tvOS, introduced: 8.0, deprecated: 9.0, message: "Use UseAuthenticationUI instead.")
- private let UseNoAuthenticationUI = String(kSecUseNoAuthenticationUI)
- @available(iOS 9.0, OSX 10.11, watchOS 2.0, tvOS 9.0, *)
- private let UseAuthenticationUI = String(kSecUseAuthenticationUI)
- @available(iOS 9.0, OSX 10.11, watchOS 2.0, tvOS 9.0, *)
- private let UseAuthenticationContext = String(kSecUseAuthenticationContext)
- @available(iOS 9.0, OSX 10.11, watchOS 2.0, tvOS 9.0, *)
- private let UseAuthenticationUIAllow = String(kSecUseAuthenticationUIAllow)
- @available(iOS 9.0, OSX 10.11, watchOS 2.0, tvOS 9.0, *)
- private let UseAuthenticationUIFail = String(kSecUseAuthenticationUIFail)
- @available(iOS 9.0, OSX 10.11, watchOS 2.0, tvOS 9.0, *)
- private let UseAuthenticationUISkip = String(kSecUseAuthenticationUISkip)
- #if os(iOS) && !targetEnvironment(macCatalyst)
- /** Credential Key Constants */
- private let SharedPassword = String(kSecSharedPassword)
- #endif
- extension Keychain: CustomStringConvertible, CustomDebugStringConvertible {
- public var description: String {
- let items = allItems()
- if items.isEmpty {
- return "[]"
- }
- var description = "[\n"
- for item in items {
- description += " "
- description += "\(item)\n"
- }
- description += "]"
- return description
- }
- public var debugDescription: String {
- return "\(items())"
- }
- }
- extension Options {
- func query(ignoringAttributeSynchronizable: Bool = true) -> [String: Any] {
- var query = [String: Any]()
- query[Class] = itemClass.rawValue
- if let accessGroup = self.accessGroup {
- query[AttributeAccessGroup] = accessGroup
- }
- if ignoringAttributeSynchronizable {
- query[AttributeSynchronizable] = SynchronizableAny
- } else {
- query[AttributeSynchronizable] = synchronizable ? kCFBooleanTrue : kCFBooleanFalse
- }
- switch itemClass {
- case .genericPassword:
- query[AttributeService] = service
- case .internetPassword:
- query[AttributeServer] = server.host
- query[AttributePort] = server.port
- query[AttributeProtocol] = protocolType.rawValue
- query[AttributeAuthenticationType] = authenticationType.rawValue
- }
- if #available(OSX 10.10, *) {
- if authenticationPrompt != nil {
- query[UseOperationPrompt] = authenticationPrompt
- }
- }
- #if !os(watchOS)
- if #available(iOS 9.0, OSX 10.11, *) {
- if authenticationContext != nil {
- query[UseAuthenticationContext] = authenticationContext
- }
- }
- #endif
- return query
- }
- func attributes(key: String?, value: Data) -> ([String: Any], Error?) {
- var attributes: [String: Any]
- if key != nil {
- attributes = query()
- attributes[AttributeAccount] = key
- } else {
- attributes = [String: Any]()
- }
- attributes[ValueData] = value
- if label != nil {
- attributes[AttributeLabel] = label
- }
- if comment != nil {
- attributes[AttributeComment] = comment
- }
- if let policy = authenticationPolicy {
- if #available(OSX 10.10, *) {
- var error: Unmanaged<CFError>?
- guard let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, SecAccessControlCreateFlags(rawValue: CFOptionFlags(policy.rawValue)), &error) else {
- if let error = error?.takeUnretainedValue() {
- return (attributes, error.error)
- }
- return (attributes, Status.unexpectedError)
- }
- attributes[AttributeAccessControl] = accessControl
- } else {
- print("Unavailable 'Touch ID integration' on OS X versions prior to 10.10.")
- }
- } else {
- attributes[AttributeAccessible] = accessibility.rawValue
- }
- attributes[AttributeSynchronizable] = synchronizable ? kCFBooleanTrue : kCFBooleanFalse
- return (attributes, nil)
- }
- }
- // MARK:
- extension Attributes: CustomStringConvertible, CustomDebugStringConvertible {
- public var description: String {
- return "\(attributes)"
- }
- public var debugDescription: String {
- return description
- }
- }
- extension ItemClass: RawRepresentable, CustomStringConvertible {
- public init?(rawValue: String) {
- switch rawValue {
- case String(kSecClassGenericPassword):
- self = .genericPassword
- case String(kSecClassInternetPassword):
- self = .internetPassword
- default:
- return nil
- }
- }
- public var rawValue: String {
- switch self {
- case .genericPassword:
- return String(kSecClassGenericPassword)
- case .internetPassword:
- return String(kSecClassInternetPassword)
- }
- }
- public var description: String {
- switch self {
- case .genericPassword:
- return "GenericPassword"
- case .internetPassword:
- return "InternetPassword"
- }
- }
- }
- extension ProtocolType: RawRepresentable, CustomStringConvertible {
- public init?(rawValue: String) {
- switch rawValue {
- case String(kSecAttrProtocolFTP):
- self = .ftp
- case String(kSecAttrProtocolFTPAccount):
- self = .ftpAccount
- case String(kSecAttrProtocolHTTP):
- self = .http
- case String(kSecAttrProtocolIRC):
- self = .irc
- case String(kSecAttrProtocolNNTP):
- self = .nntp
- case String(kSecAttrProtocolPOP3):
- self = .pop3
- case String(kSecAttrProtocolSMTP):
- self = .smtp
- case String(kSecAttrProtocolSOCKS):
- self = .socks
- case String(kSecAttrProtocolIMAP):
- self = .imap
- case String(kSecAttrProtocolLDAP):
- self = .ldap
- case String(kSecAttrProtocolAppleTalk):
- self = .appleTalk
- case String(kSecAttrProtocolAFP):
- self = .afp
- case String(kSecAttrProtocolTelnet):
- self = .telnet
- case String(kSecAttrProtocolSSH):
- self = .ssh
- case String(kSecAttrProtocolFTPS):
- self = .ftps
- case String(kSecAttrProtocolHTTPS):
- self = .https
- case String(kSecAttrProtocolHTTPProxy):
- self = .httpProxy
- case String(kSecAttrProtocolHTTPSProxy):
- self = .httpsProxy
- case String(kSecAttrProtocolFTPProxy):
- self = .ftpProxy
- case String(kSecAttrProtocolSMB):
- self = .smb
- case String(kSecAttrProtocolRTSP):
- self = .rtsp
- case String(kSecAttrProtocolRTSPProxy):
- self = .rtspProxy
- case String(kSecAttrProtocolDAAP):
- self = .daap
- case String(kSecAttrProtocolEPPC):
- self = .eppc
- case String(kSecAttrProtocolIPP):
- self = .ipp
- case String(kSecAttrProtocolNNTPS):
- self = .nntps
- case String(kSecAttrProtocolLDAPS):
- self = .ldaps
- case String(kSecAttrProtocolTelnetS):
- self = .telnetS
- case String(kSecAttrProtocolIMAPS):
- self = .imaps
- case String(kSecAttrProtocolIRCS):
- self = .ircs
- case String(kSecAttrProtocolPOP3S):
- self = .pop3S
- default:
- return nil
- }
- }
- public var rawValue: String {
- switch self {
- case .ftp:
- return String(kSecAttrProtocolFTP)
- case .ftpAccount:
- return String(kSecAttrProtocolFTPAccount)
- case .http:
- return String(kSecAttrProtocolHTTP)
- case .irc:
- return String(kSecAttrProtocolIRC)
- case .nntp:
- return String(kSecAttrProtocolNNTP)
- case .pop3:
- return String(kSecAttrProtocolPOP3)
- case .smtp:
- return String(kSecAttrProtocolSMTP)
- case .socks:
- return String(kSecAttrProtocolSOCKS)
- case .imap:
- return String(kSecAttrProtocolIMAP)
- case .ldap:
- return String(kSecAttrProtocolLDAP)
- case .appleTalk:
- return String(kSecAttrProtocolAppleTalk)
- case .afp:
- return String(kSecAttrProtocolAFP)
- case .telnet:
- return String(kSecAttrProtocolTelnet)
- case .ssh:
- return String(kSecAttrProtocolSSH)
- case .ftps:
- return String(kSecAttrProtocolFTPS)
- case .https:
- return String(kSecAttrProtocolHTTPS)
- case .httpProxy:
- return String(kSecAttrProtocolHTTPProxy)
- case .httpsProxy:
- return String(kSecAttrProtocolHTTPSProxy)
- case .ftpProxy:
- return String(kSecAttrProtocolFTPProxy)
- case .smb:
- return String(kSecAttrProtocolSMB)
- case .rtsp:
- return String(kSecAttrProtocolRTSP)
- case .rtspProxy:
- return String(kSecAttrProtocolRTSPProxy)
- case .daap:
- return String(kSecAttrProtocolDAAP)
- case .eppc:
- return String(kSecAttrProtocolEPPC)
- case .ipp:
- return String(kSecAttrProtocolIPP)
- case .nntps:
- return String(kSecAttrProtocolNNTPS)
- case .ldaps:
- return String(kSecAttrProtocolLDAPS)
- case .telnetS:
- return String(kSecAttrProtocolTelnetS)
- case .imaps:
- return String(kSecAttrProtocolIMAPS)
- case .ircs:
- return String(kSecAttrProtocolIRCS)
- case .pop3S:
- return String(kSecAttrProtocolPOP3S)
- }
- }
- public var description: String {
- switch self {
- case .ftp:
- return "FTP"
- case .ftpAccount:
- return "FTPAccount"
- case .http:
- return "HTTP"
- case .irc:
- return "IRC"
- case .nntp:
- return "NNTP"
- case .pop3:
- return "POP3"
- case .smtp:
- return "SMTP"
- case .socks:
- return "SOCKS"
- case .imap:
- return "IMAP"
- case .ldap:
- return "LDAP"
- case .appleTalk:
- return "AppleTalk"
- case .afp:
- return "AFP"
- case .telnet:
- return "Telnet"
- case .ssh:
- return "SSH"
- case .ftps:
- return "FTPS"
- case .https:
- return "HTTPS"
- case .httpProxy:
- return "HTTPProxy"
- case .httpsProxy:
- return "HTTPSProxy"
- case .ftpProxy:
- return "FTPProxy"
- case .smb:
- return "SMB"
- case .rtsp:
- return "RTSP"
- case .rtspProxy:
- return "RTSPProxy"
- case .daap:
- return "DAAP"
- case .eppc:
- return "EPPC"
- case .ipp:
- return "IPP"
- case .nntps:
- return "NNTPS"
- case .ldaps:
- return "LDAPS"
- case .telnetS:
- return "TelnetS"
- case .imaps:
- return "IMAPS"
- case .ircs:
- return "IRCS"
- case .pop3S:
- return "POP3S"
- }
- }
- }
- extension AuthenticationType: RawRepresentable, CustomStringConvertible {
- public init?(rawValue: String) {
- switch rawValue {
- case String(kSecAttrAuthenticationTypeNTLM):
- self = .ntlm
- case String(kSecAttrAuthenticationTypeMSN):
- self = .msn
- case String(kSecAttrAuthenticationTypeDPA):
- self = .dpa
- case String(kSecAttrAuthenticationTypeRPA):
- self = .rpa
- case String(kSecAttrAuthenticationTypeHTTPBasic):
- self = .httpBasic
- case String(kSecAttrAuthenticationTypeHTTPDigest):
- self = .httpDigest
- case String(kSecAttrAuthenticationTypeHTMLForm):
- self = .htmlForm
- case String(kSecAttrAuthenticationTypeDefault):
- self = .`default`
- default:
- return nil
- }
- }
- public var rawValue: String {
- switch self {
- case .ntlm:
- return String(kSecAttrAuthenticationTypeNTLM)
- case .msn:
- return String(kSecAttrAuthenticationTypeMSN)
- case .dpa:
- return String(kSecAttrAuthenticationTypeDPA)
- case .rpa:
- return String(kSecAttrAuthenticationTypeRPA)
- case .httpBasic:
- return String(kSecAttrAuthenticationTypeHTTPBasic)
- case .httpDigest:
- return String(kSecAttrAuthenticationTypeHTTPDigest)
- case .htmlForm:
- return String(kSecAttrAuthenticationTypeHTMLForm)
- case .`default`:
- return String(kSecAttrAuthenticationTypeDefault)
- }
- }
- public var description: String {
- switch self {
- case .ntlm:
- return "NTLM"
- case .msn:
- return "MSN"
- case .dpa:
- return "DPA"
- case .rpa:
- return "RPA"
- case .httpBasic:
- return "HTTPBasic"
- case .httpDigest:
- return "HTTPDigest"
- case .htmlForm:
- return "HTMLForm"
- case .`default`:
- return "Default"
- }
- }
- }
- extension Accessibility: RawRepresentable, CustomStringConvertible {
- public init?(rawValue: String) {
- if #available(OSX 10.10, *) {
- switch rawValue {
- case String(kSecAttrAccessibleWhenUnlocked):
- self = .whenUnlocked
- case String(kSecAttrAccessibleAfterFirstUnlock):
- self = .afterFirstUnlock
- #if !targetEnvironment(macCatalyst)
- case String(kSecAttrAccessibleAlways):
- self = .always
- #endif
- case String(kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly):
- self = .whenPasscodeSetThisDeviceOnly
- case String(kSecAttrAccessibleWhenUnlockedThisDeviceOnly):
- self = .whenUnlockedThisDeviceOnly
- case String(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly):
- self = .afterFirstUnlockThisDeviceOnly
- #if !targetEnvironment(macCatalyst)
- case String(kSecAttrAccessibleAlwaysThisDeviceOnly):
- self = .alwaysThisDeviceOnly
- #endif
- default:
- return nil
- }
- } else {
- switch rawValue {
- case String(kSecAttrAccessibleWhenUnlocked):
- self = .whenUnlocked
- case String(kSecAttrAccessibleAfterFirstUnlock):
- self = .afterFirstUnlock
- #if !targetEnvironment(macCatalyst)
- case String(kSecAttrAccessibleAlways):
- self = .always
- #endif
- case String(kSecAttrAccessibleWhenUnlockedThisDeviceOnly):
- self = .whenUnlockedThisDeviceOnly
- case String(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly):
- self = .afterFirstUnlockThisDeviceOnly
- #if !targetEnvironment(macCatalyst)
- case String(kSecAttrAccessibleAlwaysThisDeviceOnly):
- self = .alwaysThisDeviceOnly
- #endif
- default:
- return nil
- }
- }
- }
- public var rawValue: String {
- switch self {
- case .whenUnlocked:
- return String(kSecAttrAccessibleWhenUnlocked)
- case .afterFirstUnlock:
- return String(kSecAttrAccessibleAfterFirstUnlock)
- #if !targetEnvironment(macCatalyst)
- case .always:
- return String(kSecAttrAccessibleAlways)
- #endif
- case .whenPasscodeSetThisDeviceOnly:
- if #available(OSX 10.10, *) {
- return String(kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly)
- } else {
- fatalError("'Accessibility.WhenPasscodeSetThisDeviceOnly' is not available on this version of OS.")
- }
- case .whenUnlockedThisDeviceOnly:
- return String(kSecAttrAccessibleWhenUnlockedThisDeviceOnly)
- case .afterFirstUnlockThisDeviceOnly:
- return String(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly)
- #if !targetEnvironment(macCatalyst)
- case .alwaysThisDeviceOnly:
- return String(kSecAttrAccessibleAlwaysThisDeviceOnly)
- #endif
- }
- }
- public var description: String {
- switch self {
- case .whenUnlocked:
- return "WhenUnlocked"
- case .afterFirstUnlock:
- return "AfterFirstUnlock"
- #if !targetEnvironment(macCatalyst)
- case .always:
- return "Always"
- #endif
- case .whenPasscodeSetThisDeviceOnly:
- return "WhenPasscodeSetThisDeviceOnly"
- case .whenUnlockedThisDeviceOnly:
- return "WhenUnlockedThisDeviceOnly"
- case .afterFirstUnlockThisDeviceOnly:
- return "AfterFirstUnlockThisDeviceOnly"
- #if !targetEnvironment(macCatalyst)
- case .alwaysThisDeviceOnly:
- return "AlwaysThisDeviceOnly"
- #endif
- }
- }
- }
- extension CFError {
- var error: NSError {
- let domain = CFErrorGetDomain(self) as String
- let code = CFErrorGetCode(self)
- let userInfo = CFErrorCopyUserInfo(self) as! [String: Any]
- return NSError(domain: domain, code: code, userInfo: userInfo)
- }
- }
- public enum Status: OSStatus, Error {
- case success = 0
- case unimplemented = -4
- case diskFull = -34
- case io = -36
- case opWr = -49
- case param = -50
- case wrPerm = -61
- case allocate = -108
- case userCanceled = -128
- case badReq = -909
- case internalComponent = -2070
- case notAvailable = -25291
- case readOnly = -25292
- case authFailed = -25293
- case noSuchKeychain = -25294
- case invalidKeychain = -25295
- case duplicateKeychain = -25296
- case duplicateCallback = -25297
- case invalidCallback = -25298
- case duplicateItem = -25299
- case itemNotFound = -25300
- case bufferTooSmall = -25301
- case dataTooLarge = -25302
- case noSuchAttr = -25303
- case invalidItemRef = -25304
- case invalidSearchRef = -25305
- case noSuchClass = -25306
- case noDefaultKeychain = -25307
- case interactionNotAllowed = -25308
- case readOnlyAttr = -25309
- case wrongSecVersion = -25310
- case keySizeNotAllowed = -25311
- case noStorageModule = -25312
- case noCertificateModule = -25313
- case noPolicyModule = -25314
- case interactionRequired = -25315
- case dataNotAvailable = -25316
- case dataNotModifiable = -25317
- case createChainFailed = -25318
- case invalidPrefsDomain = -25319
- case inDarkWake = -25320
- case aclNotSimple = -25240
- case policyNotFound = -25241
- case invalidTrustSetting = -25242
- case noAccessForItem = -25243
- case invalidOwnerEdit = -25244
- case trustNotAvailable = -25245
- case unsupportedFormat = -25256
- case unknownFormat = -25257
- case keyIsSensitive = -25258
- case multiplePrivKeys = -25259
- case passphraseRequired = -25260
- case invalidPasswordRef = -25261
- case invalidTrustSettings = -25262
- case noTrustSettings = -25263
- case pkcs12VerifyFailure = -25264
- case invalidCertificate = -26265
- case notSigner = -26267
- case policyDenied = -26270
- case invalidKey = -26274
- case decode = -26275
- case `internal` = -26276
- case unsupportedAlgorithm = -26268
- case unsupportedOperation = -26271
- case unsupportedPadding = -26273
- case itemInvalidKey = -34000
- case itemInvalidKeyType = -34001
- case itemInvalidValue = -34002
- case itemClassMissing = -34003
- case itemMatchUnsupported = -34004
- case useItemListUnsupported = -34005
- case useKeychainUnsupported = -34006
- case useKeychainListUnsupported = -34007
- case returnDataUnsupported = -34008
- case returnAttributesUnsupported = -34009
- case returnRefUnsupported = -34010
- case returnPersitentRefUnsupported = -34011
- case valueRefUnsupported = -34012
- case valuePersistentRefUnsupported = -34013
- case returnMissingPointer = -34014
- case matchLimitUnsupported = -34015
- case itemIllegalQuery = -34016
- case waitForCallback = -34017
- case missingEntitlement = -34018
- case upgradePending = -34019
- case mpSignatureInvalid = -25327
- case otrTooOld = -25328
- case otrIDTooNew = -25329
- case serviceNotAvailable = -67585
- case insufficientClientID = -67586
- case deviceReset = -67587
- case deviceFailed = -67588
- case appleAddAppACLSubject = -67589
- case applePublicKeyIncomplete = -67590
- case appleSignatureMismatch = -67591
- case appleInvalidKeyStartDate = -67592
- case appleInvalidKeyEndDate = -67593
- case conversionError = -67594
- case appleSSLv2Rollback = -67595
- case quotaExceeded = -67596
- case fileTooBig = -67597
- case invalidDatabaseBlob = -67598
- case invalidKeyBlob = -67599
- case incompatibleDatabaseBlob = -67600
- case incompatibleKeyBlob = -67601
- case hostNameMismatch = -67602
- case unknownCriticalExtensionFlag = -67603
- case noBasicConstraints = -67604
- case noBasicConstraintsCA = -67605
- case invalidAuthorityKeyID = -67606
- case invalidSubjectKeyID = -67607
- case invalidKeyUsageForPolicy = -67608
- case invalidExtendedKeyUsage = -67609
- case invalidIDLinkage = -67610
- case pathLengthConstraintExceeded = -67611
- case invalidRoot = -67612
- case crlExpired = -67613
- case crlNotValidYet = -67614
- case crlNotFound = -67615
- case crlServerDown = -67616
- case crlBadURI = -67617
- case unknownCertExtension = -67618
- case unknownCRLExtension = -67619
- case crlNotTrusted = -67620
- case crlPolicyFailed = -67621
- case idpFailure = -67622
- case smimeEmailAddressesNotFound = -67623
- case smimeBadExtendedKeyUsage = -67624
- case smimeBadKeyUsage = -67625
- case smimeKeyUsageNotCritical = -67626
- case smimeNoEmailAddress = -67627
- case smimeSubjAltNameNotCritical = -67628
- case sslBadExtendedKeyUsage = -67629
- case ocspBadResponse = -67630
- case ocspBadRequest = -67631
- case ocspUnavailable = -67632
- case ocspStatusUnrecognized = -67633
- case endOfData = -67634
- case incompleteCertRevocationCheck = -67635
- case networkFailure = -67636
- case ocspNotTrustedToAnchor = -67637
- case recordModified = -67638
- case ocspSignatureError = -67639
- case ocspNoSigner = -67640
- case ocspResponderMalformedReq = -67641
- case ocspResponderInternalError = -67642
- case ocspResponderTryLater = -67643
- case ocspResponderSignatureRequired = -67644
- case ocspResponderUnauthorized = -67645
- case ocspResponseNonceMismatch = -67646
- case codeSigningBadCertChainLength = -67647
- case codeSigningNoBasicConstraints = -67648
- case codeSigningBadPathLengthConstraint = -67649
- case codeSigningNoExtendedKeyUsage = -67650
- case codeSigningDevelopment = -67651
- case resourceSignBadCertChainLength = -67652
- case resourceSignBadExtKeyUsage = -67653
- case trustSettingDeny = -67654
- case invalidSubjectName = -67655
- case unknownQualifiedCertStatement = -67656
- case mobileMeRequestQueued = -67657
- case mobileMeRequestRedirected = -67658
- case mobileMeServerError = -67659
- case mobileMeServerNotAvailable = -67660
- case mobileMeServerAlreadyExists = -67661
- case mobileMeServerServiceErr = -67662
- case mobileMeRequestAlreadyPending = -67663
- case mobileMeNoRequestPending = -67664
- case mobileMeCSRVerifyFailure = -67665
- case mobileMeFailedConsistencyCheck = -67666
- case notInitialized = -67667
- case invalidHandleUsage = -67668
- case pvcReferentNotFound = -67669
- case functionIntegrityFail = -67670
- case internalError = -67671
- case memoryError = -67672
- case invalidData = -67673
- case mdsError = -67674
- case invalidPointer = -67675
- case selfCheckFailed = -67676
- case functionFailed = -67677
- case moduleManifestVerifyFailed = -67678
- case invalidGUID = -67679
- case invalidHandle = -67680
- case invalidDBList = -67681
- case invalidPassthroughID = -67682
- case invalidNetworkAddress = -67683
- case crlAlreadySigned = -67684
- case invalidNumberOfFields = -67685
- case verificationFailure = -67686
- case unknownTag = -67687
- case invalidSignature = -67688
- case invalidName = -67689
- case invalidCertificateRef = -67690
- case invalidCertificateGroup = -67691
- case tagNotFound = -67692
- case invalidQuery = -67693
- case invalidValue = -67694
- case callbackFailed = -67695
- case aclDeleteFailed = -67696
- case aclReplaceFailed = -67697
- case aclAddFailed = -67698
- case aclChangeFailed = -67699
- case invalidAccessCredentials = -67700
- case invalidRecord = -67701
- case invalidACL = -67702
- case invalidSampleValue = -67703
- case incompatibleVersion = -67704
- case privilegeNotGranted = -67705
- case invalidScope = -67706
- case pvcAlreadyConfigured = -67707
- case invalidPVC = -67708
- case emmLoadFailed = -67709
- case emmUnloadFailed = -67710
- case addinLoadFailed = -67711
- case invalidKeyRef = -67712
- case invalidKeyHierarchy = -67713
- case addinUnloadFailed = -67714
- case libraryReferenceNotFound = -67715
- case invalidAddinFunctionTable = -67716
- case invalidServiceMask = -67717
- case moduleNotLoaded = -67718
- case invalidSubServiceID = -67719
- case attributeNotInContext = -67720
- case moduleManagerInitializeFailed = -67721
- case moduleManagerNotFound = -67722
- case eventNotificationCallbackNotFound = -67723
- case inputLengthError = -67724
- case outputLengthError = -67725
- case privilegeNotSupported = -67726
- case deviceError = -67727
- case attachHandleBusy = -67728
- case notLoggedIn = -67729
- case algorithmMismatch = -67730
- case keyUsageIncorrect = -67731
- case keyBlobTypeIncorrect = -67732
- case keyHeaderInconsistent = -67733
- case unsupportedKeyFormat = -67734
- case unsupportedKeySize = -67735
- case invalidKeyUsageMask = -67736
- case unsupportedKeyUsageMask = -67737
- case invalidKeyAttributeMask = -67738
- case unsupportedKeyAttributeMask = -67739
- case invalidKeyLabel = -67740
- case unsupportedKeyLabel = -67741
- case invalidKeyFormat = -67742
- case unsupportedVectorOfBuffers = -67743
- case invalidInputVector = -67744
- case invalidOutputVector = -67745
- case invalidContext = -67746
- case invalidAlgorithm = -67747
- case invalidAttributeKey = -67748
- case missingAttributeKey = -67749
- case invalidAttributeInitVector = -67750
- case missingAttributeInitVector = -67751
- case invalidAttributeSalt = -67752
- case missingAttributeSalt = -67753
- case invalidAttributePadding = -67754
- case missingAttributePadding = -67755
- case invalidAttributeRandom = -67756
- case missingAttributeRandom = -67757
- case invalidAttributeSeed = -67758
- case missingAttributeSeed = -67759
- case invalidAttributePassphrase = -67760
- case missingAttributePassphrase = -67761
- case invalidAttributeKeyLength = -67762
- case missingAttributeKeyLength = -67763
- case invalidAttributeBlockSize = -67764
- case missingAttributeBlockSize = -67765
- case invalidAttributeOutputSize = -67766
- case missingAttributeOutputSize = -67767
- case invalidAttributeRounds = -67768
- case missingAttributeRounds = -67769
- case invalidAlgorithmParms = -67770
- case missingAlgorithmParms = -67771
- case invalidAttributeLabel = -67772
- case missingAttributeLabel = -67773
- case invalidAttributeKeyType = -67774
- case missingAttributeKeyType = -67775
- case invalidAttributeMode = -67776
- case missingAttributeMode = -67777
- case invalidAttributeEffectiveBits = -67778
- case missingAttributeEffectiveBits = -67779
- case invalidAttributeStartDate = -67780
- case missingAttributeStartDate = -67781
- case invalidAttributeEndDate = -67782
- case missingAttributeEndDate = -67783
- case invalidAttributeVersion = -67784
- case missingAttributeVersion = -67785
- case invalidAttributePrime = -67786
- case missingAttributePrime = -67787
- case invalidAttributeBase = -67788
- case missingAttributeBase = -67789
- case invalidAttributeSubprime = -67790
- case missingAttributeSubprime = -67791
- case invalidAttributeIterationCount = -67792
- case missingAttributeIterationCount = -67793
- case invalidAttributeDLDBHandle = -67794
- case missingAttributeDLDBHandle = -67795
- case invalidAttributeAccessCredentials = -67796
- case missingAttributeAccessCredentials = -67797
- case invalidAttributePublicKeyFormat = -67798
- case missingAttributePublicKeyFormat = -67799
- case invalidAttributePrivateKeyFormat = -67800
- case missingAttributePrivateKeyFormat = -67801
- case invalidAttributeSymmetricKeyFormat = -67802
- case missingAttributeSymmetricKeyFormat = -67803
- case invalidAttributeWrappedKeyFormat = -67804
- case missingAttributeWrappedKeyFormat = -67805
- case stagedOperationInProgress = -67806
- case stagedOperationNotStarted = -67807
- case verifyFailed = -67808
- case querySizeUnknown = -67809
- case blockSizeMismatch = -67810
- case publicKeyInconsistent = -67811
- case deviceVerifyFailed = -67812
- case invalidLoginName = -67813
- case alreadyLoggedIn = -67814
- case invalidDigestAlgorithm = -67815
- case invalidCRLGroup = -67816
- case certificateCannotOperate = -67817
- case certificateExpired = -67818
- case certificateNotValidYet = -67819
- case certificateRevoked = -67820
- case certificateSuspended = -67821
- case insufficientCredentials = -67822
- case invalidAction = -67823
- case invalidAuthority = -67824
- case verifyActionFailed = -67825
- case invalidCertAuthority = -67826
- case invaldCRLAuthority = -67827
- case invalidCRLEncoding = -67828
- case invalidCRLType = -67829
- case invalidCRL = -67830
- case invalidFormType = -67831
- case invalidID = -67832
- case invalidIdentifier = -67833
- case invalidIndex = -67834
- case invalidPolicyIdentifiers = -67835
- case invalidTimeString = -67836
- case invalidReason = -67837
- case invalidRequestInputs = -67838
- case invalidResponseVector = -67839
- case invalidStopOnPolicy = -67840
- case invalidTuple = -67841
- case multipleValuesUnsupported = -67842
- case notTrusted = -67843
- case noDefaultAuthority = -67844
- case rejectedForm = -67845
- case requestLost = -67846
- case requestRejected = -67847
- case unsupportedAddressType = -67848
- case unsupportedService = -67849
- case invalidTupleGroup = -67850
- case invalidBaseACLs = -67851
- case invalidTupleCredendtials = -67852
- case invalidEncoding = -67853
- case invalidValidityPeriod = -67854
- case invalidRequestor = -67855
- case requestDescriptor = -67856
- case invalidBundleInfo = -67857
- case invalidCRLIndex = -67858
- case noFieldValues = -67859
- case unsupportedFieldFormat = -67860
- case unsupportedIndexInfo = -67861
- case unsupportedLocality = -67862
- case unsupportedNumAttributes = -67863
- case unsupportedNumIndexes = -67864
- case unsupportedNumRecordTypes = -67865
- case fieldSpecifiedMultiple = -67866
- case incompatibleFieldFormat = -67867
- case invalidParsingModule = -67868
- case databaseLocked = -67869
- case datastoreIsOpen = -67870
- case missingValue = -67871
- case unsupportedQueryLimits = -67872
- case unsupportedNumSelectionPreds = -67873
- case unsupportedOperator = -67874
- case invalidDBLocation = -67875
- case invalidAccessRequest = -67876
- case invalidIndexInfo = -67877
- case invalidNewOwner = -67878
- case invalidModifyMode = -67879
- case missingRequiredExtension = -67880
- case extendedKeyUsageNotCritical = -67881
- case timestampMissing = -67882
- case timestampInvalid = -67883
- case timestampNotTrusted = -67884
- case timestampServiceNotAvailable = -67885
- case timestampBadAlg = -67886
- case timestampBadRequest = -67887
- case timestampBadDataFormat = -67888
- case timestampTimeNotAvailable = -67889
- case timestampUnacceptedPolicy = -67890
- case timestampUnacceptedExtension = -67891
- case timestampAddInfoNotAvailable = -67892
- case timestampSystemFailure = -67893
- case signingTimeMissing = -67894
- case timestampRejection = -67895
- case timestampWaiting = -67896
- case timestampRevocationWarning = -67897
- case timestampRevocationNotification = -67898
- case unexpectedError = -99999
- }
- extension Status: RawRepresentable, CustomStringConvertible {
- public init(status: OSStatus) {
- if let mappedStatus = Status(rawValue: status) {
- self = mappedStatus
- } else {
- self = .unexpectedError
- }
- }
- public var description: String {
- switch self {
- case .success:
- return "No error."
- case .unimplemented:
- return "Function or operation not implemented."
- case .diskFull:
- return "The disk is full."
- case .io:
- return "I/O error (bummers)"
- case .opWr:
- return "file already open with with write permission"
- case .param:
- return "One or more parameters passed to a function were not valid."
- case .wrPerm:
- return "write permissions error"
- case .allocate:
- return "Failed to allocate memory."
- case .userCanceled:
- return "User canceled the operation."
- case .badReq:
- return "Bad parameter or invalid state for operation."
- case .internalComponent:
- return ""
- case .notAvailable:
- return "No keychain is available. You may need to restart your computer."
- case .readOnly:
- return "This keychain cannot be modified."
- case .authFailed:
- return "The user name or passphrase you entered is not correct."
- case .noSuchKeychain:
- return "The specified keychain could not be found."
- case .invalidKeychain:
- return "The specified keychain is not a valid keychain file."
- case .duplicateKeychain:
- return "A keychain with the same name already exists."
- case .duplicateCallback:
- return "The specified callback function is already installed."
- case .invalidCallback:
- return "The specified callback function is not valid."
- case .duplicateItem:
- return "The specified item already exists in the keychain."
- case .itemNotFound:
- return "The specified item could not be found in the keychain."
- case .bufferTooSmall:
- return "There is not enough memory available to use the specified item."
- case .dataTooLarge:
- return "This item contains information which is too large or in a format that cannot be displayed."
- case .noSuchAttr:
- return "The specified attribute does not exist."
- case .invalidItemRef:
- return "The specified item is no longer valid. It may have been deleted from the keychain."
- case .invalidSearchRef:
- return "Unable to search the current keychain."
- case .noSuchClass:
- return "The specified item does not appear to be a valid keychain item."
- case .noDefaultKeychain:
- return "A default keychain could not be found."
- case .interactionNotAllowed:
- return "User interaction is not allowed."
- case .readOnlyAttr:
- return "The specified attribute could not be modified."
- case .wrongSecVersion:
- return "This keychain was created by a different version of the system software and cannot be opened."
- case .keySizeNotAllowed:
- return "This item specifies a key size which is too large."
- case .noStorageModule:
- return "A required component (data storage module) could not be loaded. You may need to restart your computer."
- case .noCertificateModule:
- return "A required component (certificate module) could not be loaded. You may need to restart your computer."
- case .noPolicyModule:
- return "A required component (policy module) could not be loaded. You may need to restart your computer."
- case .interactionRequired:
- return "User interaction is required, but is currently not allowed."
- case .dataNotAvailable:
- return "The contents of this item cannot be retrieved."
- case .dataNotModifiable:
- return "The contents of this item cannot be modified."
- case .createChainFailed:
- return "One or more certificates required to validate this certificate cannot be found."
- case .invalidPrefsDomain:
- return "The specified preferences domain is not valid."
- case .inDarkWake:
- return "In dark wake, no UI possible"
- case .aclNotSimple:
- return "The specified access control list is not in standard (simple) form."
- case .policyNotFound:
- return "The specified policy cannot be found."
- case .invalidTrustSetting:
- return "The specified trust setting is invalid."
- case .noAccessForItem:
- return "The specified item has no access control."
- case .invalidOwnerEdit:
- return "Invalid attempt to change the owner of this item."
- case .trustNotAvailable:
- return "No trust results are available."
- case .unsupportedFormat:
- return "Import/Export format unsupported."
- case .unknownFormat:
- return "Unknown format in import."
- case .keyIsSensitive:
- return "Key material must be wrapped for export."
- case .multiplePrivKeys:
- return "An attempt was made to import multiple private keys."
- case .passphraseRequired:
- return "Passphrase is required for import/export."
- case .invalidPasswordRef:
- return "The password reference was invalid."
- case .invalidTrustSettings:
- return "The Trust Settings Record was corrupted."
- case .noTrustSettings:
- return "No Trust Settings were found."
- case .pkcs12VerifyFailure:
- return "MAC verification failed during PKCS12 import (wrong password?)"
- case .invalidCertificate:
- return "This certificate could not be decoded."
- case .notSigner:
- return "A certificate was not signed by its proposed parent."
- case .policyDenied:
- return "The certificate chain was not trusted due to a policy not accepting it."
- case .invalidKey:
- return "The provided key material was not valid."
- case .decode:
- return "Unable to decode the provided data."
- case .`internal`:
- return "An internal error occurred in the Security framework."
- case .unsupportedAlgorithm:
- return "An unsupported algorithm was encountered."
- case .unsupportedOperation:
- return "The operation you requested is not supported by this key."
- case .unsupportedPadding:
- return "The padding you requested is not supported."
- case .itemInvalidKey:
- return "A string key in dictionary is not one of the supported keys."
- case .itemInvalidKeyType:
- return "A key in a dictionary is neither a CFStringRef nor a CFNumberRef."
- case .itemInvalidValue:
- return "A value in a dictionary is an invalid (or unsupported) CF type."
- case .itemClassMissing:
- return "No kSecItemClass key was specified in a dictionary."
- case .itemMatchUnsupported:
- return "The caller passed one or more kSecMatch keys to a function which does not support matches."
- case .useItemListUnsupported:
- return "The caller passed in a kSecUseItemList key to a function which does not support it."
- case .useKeychainUnsupported:
- return "The caller passed in a kSecUseKeychain key to a function which does not support it."
- case .useKeychainListUnsupported:
- return "The caller passed in a kSecUseKeychainList key to a function which does not support it."
- case .returnDataUnsupported:
- return "The caller passed in a kSecReturnData key to a function which does not support it."
- case .returnAttributesUnsupported:
- return "The caller passed in a kSecReturnAttributes key to a function which does not support it."
- case .returnRefUnsupported:
- return "The caller passed in a kSecReturnRef key to a function which does not support it."
- case .returnPersitentRefUnsupported:
- return "The caller passed in a kSecReturnPersistentRef key to a function which does not support it."
- case .valueRefUnsupported:
- return "The caller passed in a kSecValueRef key to a function which does not support it."
- case .valuePersistentRefUnsupported:
- return "The caller passed in a kSecValuePersistentRef key to a function which does not support it."
- case .returnMissingPointer:
- return "The caller passed asked for something to be returned but did not pass in a result pointer."
- case .matchLimitUnsupported:
- return "The caller passed in a kSecMatchLimit key to a call which does not support limits."
- case .itemIllegalQuery:
- return "The caller passed in a query which contained too many keys."
- case .waitForCallback:
- return "This operation is incomplete, until the callback is invoked (not an error)."
- case .missingEntitlement:
- return "Internal error when a required entitlement isn't present, client has neither application-identifier nor keychain-access-groups entitlements."
- case .upgradePending:
- return "Error returned if keychain database needs a schema migration but the device is locked, clients should wait for a device unlock notification and retry the command."
- case .mpSignatureInvalid:
- return "Signature invalid on MP message"
- case .otrTooOld:
- return "Message is too old to use"
- case .otrIDTooNew:
- return "Key ID is too new to use! Message from the future?"
- case .serviceNotAvailable:
- return "The required service is not available."
- case .insufficientClientID:
- return "The client ID is not correct."
- case .deviceReset:
- return "A device reset has occurred."
- case .deviceFailed:
- return "A device failure has occurred."
- case .appleAddAppACLSubject:
- return "Adding an application ACL subject failed."
- case .applePublicKeyIncomplete:
- return "The public key is incomplete."
- case .appleSignatureMismatch:
- return "A signature mismatch has occurred."
- case .appleInvalidKeyStartDate:
- return "The specified key has an invalid start date."
- case .appleInvalidKeyEndDate:
- return "The specified key has an invalid end date."
- case .conversionError:
- return "A conversion error has occurred."
- case .appleSSLv2Rollback:
- return "A SSLv2 rollback error has occurred."
- case .quotaExceeded:
- return "The quota was exceeded."
- case .fileTooBig:
- return "The file is too big."
- case .invalidDatabaseBlob:
- return "The specified database has an invalid blob."
- case .invalidKeyBlob:
- return "The specified database has an invalid key blob."
- case .incompatibleDatabaseBlob:
- return "The specified database has an incompatible blob."
- case .incompatibleKeyBlob:
- return "The specified database has an incompatible key blob."
- case .hostNameMismatch:
- return "A host name mismatch has occurred."
- case .unknownCriticalExtensionFlag:
- return "There is an unknown critical extension flag."
- case .noBasicConstraints:
- return "No basic constraints were found."
- case .noBasicConstraintsCA:
- return "No basic CA constraints were found."
- case .invalidAuthorityKeyID:
- return "The authority key ID is not valid."
- case .invalidSubjectKeyID:
- return "The subject key ID is not valid."
- case .invalidKeyUsageForPolicy:
- return "The key usage is not valid for the specified policy."
- case .invalidExtendedKeyUsage:
- return "The extended key usage is not valid."
- case .invalidIDLinkage:
- return "The ID linkage is not valid."
- case .pathLengthConstraintExceeded:
- return "The path length constraint was exceeded."
- case .invalidRoot:
- return "The root or anchor certificate is not valid."
- case .crlExpired:
- return "The CRL has expired."
- case .crlNotValidYet:
- return "The CRL is not yet valid."
- case .crlNotFound:
- return "The CRL was not found."
- case .crlServerDown:
- return "The CRL server is down."
- case .crlBadURI:
- return "The CRL has a bad Uniform Resource Identifier."
- case .unknownCertExtension:
- return "An unknown certificate extension was encountered."
- case .unknownCRLExtension:
- return "An unknown CRL extension was encountered."
- case .crlNotTrusted:
- return "The CRL is not trusted."
- case .crlPolicyFailed:
- return "The CRL policy failed."
- case .idpFailure:
- return "The issuing distribution point was not valid."
- case .smimeEmailAddressesNotFound:
- return "An email address mismatch was encountered."
- case .smimeBadExtendedKeyUsage:
- return "The appropriate extended key usage for SMIME was not found."
- case .smimeBadKeyUsage:
- return "The key usage is not compatible with SMIME."
- case .smimeKeyUsageNotCritical:
- return "The key usage extension is not marked as critical."
- case .smimeNoEmailAddress:
- return "No email address was found in the certificate."
- case .smimeSubjAltNameNotCritical:
- return "The subject alternative name extension is not marked as critical."
- case .sslBadExtendedKeyUsage:
- return "The appropriate extended key usage for SSL was not found."
- case .ocspBadResponse:
- return "The OCSP response was incorrect or could not be parsed."
- case .ocspBadRequest:
- return "The OCSP request was incorrect or could not be parsed."
- case .ocspUnavailable:
- return "OCSP service is unavailable."
- case .ocspStatusUnrecognized:
- return "The OCSP server did not recognize this certificate."
- case .endOfData:
- return "An end-of-data was detected."
- case .incompleteCertRevocationCheck:
- return "An incomplete certificate revocation check occurred."
- case .networkFailure:
- return "A network failure occurred."
- case .ocspNotTrustedToAnchor:
- return "The OCSP response was not trusted to a root or anchor certificate."
- case .recordModified:
- return "The record was modified."
- case .ocspSignatureError:
- return "The OCSP response had an invalid signature."
- case .ocspNoSigner:
- return "The OCSP response had no signer."
- case .ocspResponderMalformedReq:
- return "The OCSP responder was given a malformed request."
- case .ocspResponderInternalError:
- return "The OCSP responder encountered an internal error."
- case .ocspResponderTryLater:
- return "The OCSP responder is busy, try again later."
- case .ocspResponderSignatureRequired:
- return "The OCSP responder requires a signature."
- case .ocspResponderUnauthorized:
- return "The OCSP responder rejected this request as unauthorized."
- case .ocspResponseNonceMismatch:
- return "The OCSP response nonce did not match the request."
- case .codeSigningBadCertChainLength:
- return "Code signing encountered an incorrect certificate chain length."
- case .codeSigningNoBasicConstraints:
- return "Code signing found no basic constraints."
- case .codeSigningBadPathLengthConstraint:
- return "Code signing encountered an incorrect path length constraint."
- case .codeSigningNoExtendedKeyUsage:
- return "Code signing found no extended key usage."
- case .codeSigningDevelopment:
- return "Code signing indicated use of a development-only certificate."
- case .resourceSignBadCertChainLength:
- return "Resource signing has encountered an incorrect certificate chain length."
- case .resourceSignBadExtKeyUsage:
- return "Resource signing has encountered an error in the extended key usage."
- case .trustSettingDeny:
- return "The trust setting for this policy was set to Deny."
- case .invalidSubjectName:
- return "An invalid certificate subject name was encountered."
- case .unknownQualifiedCertStatement:
- return "An unknown qualified certificate statement was encountered."
- case .mobileMeRequestQueued:
- return "The MobileMe request will be sent during the next connection."
- case .mobileMeRequestRedirected:
- return "The MobileMe request was redirected."
- case .mobileMeServerError:
- return "A MobileMe server error occurred."
- case .mobileMeServerNotAvailable:
- return "The MobileMe server is not available."
- case .mobileMeServerAlreadyExists:
- return "The MobileMe server reported that the item already exists."
- case .mobileMeServerServiceErr:
- return "A MobileMe service error has occurred."
- case .mobileMeRequestAlreadyPending:
- return "A MobileMe request is already pending."
- case .mobileMeNoRequestPending:
- return "MobileMe has no request pending."
- case .mobileMeCSRVerifyFailure:
- return "A MobileMe CSR verification failure has occurred."
- case .mobileMeFailedConsistencyCheck:
- return "MobileMe has found a failed consistency check."
- case .notInitialized:
- return "A function was called without initializing CSSM."
- case .invalidHandleUsage:
- return "The CSSM handle does not match with the service type."
- case .pvcReferentNotFound:
- return "A reference to the calling module was not found in the list of authorized callers."
- case .functionIntegrityFail:
- return "A function address was not within the verified module."
- case .internalError:
- return "An internal error has occurred."
- case .memoryError:
- return "A memory error has occurred."
- case .invalidData:
- return "Invalid data was encountered."
- case .mdsError:
- return "A Module Directory Service error has occurred."
- case .invalidPointer:
- return "An invalid pointer was encountered."
- case .selfCheckFailed:
- return "Self-check has failed."
- case .functionFailed:
- return "A function has failed."
- case .moduleManifestVerifyFailed:
- return "A module manifest verification failure has occurred."
- case .invalidGUID:
- return "An invalid GUID was encountered."
- case .invalidHandle:
- return "An invalid handle was encountered."
- case .invalidDBList:
- return "An invalid DB list was encountered."
- case .invalidPassthroughID:
- return "An invalid passthrough ID was encountered."
- case .invalidNetworkAddress:
- return "An invalid network address was encountered."
- case .crlAlreadySigned:
- return "The certificate revocation list is already signed."
- case .invalidNumberOfFields:
- return "An invalid number of fields were encountered."
- case .verificationFailure:
- return "A verification failure occurred."
- case .unknownTag:
- return "An unknown tag was encountered."
- case .invalidSignature:
- return "An invalid signature was encountered."
- case .invalidName:
- return "An invalid name was encountered."
- case .invalidCertificateRef:
- return "An invalid certificate reference was encountered."
- case .invalidCertificateGroup:
- return "An invalid certificate group was encountered."
- case .tagNotFound:
- return "The specified tag was not found."
- case .invalidQuery:
- return "The specified query was not valid."
- case .invalidValue:
- return "An invalid value was detected."
- case .callbackFailed:
- return "A callback has failed."
- case .aclDeleteFailed:
- return "An ACL delete operation has failed."
- case .aclReplaceFailed:
- return "An ACL replace operation has failed."
- case .aclAddFailed:
- return "An ACL add operation has failed."
- case .aclChangeFailed:
- return "An ACL change operation has failed."
- case .invalidAccessCredentials:
- return "Invalid access credentials were encountered."
- case .invalidRecord:
- return "An invalid record was encountered."
- case .invalidACL:
- return "An invalid ACL was encountered."
- case .invalidSampleValue:
- return "An invalid sample value was encountered."
- case .incompatibleVersion:
- return "An incompatible version was encountered."
- case .privilegeNotGranted:
- return "The privilege was not granted."
- case .invalidScope:
- return "An invalid scope was encountered."
- case .pvcAlreadyConfigured:
- return "The PVC is already configured."
- case .invalidPVC:
- return "An invalid PVC was encountered."
- case .emmLoadFailed:
- return "The EMM load has failed."
- case .emmUnloadFailed:
- return "The EMM unload has failed."
- case .addinLoadFailed:
- return "The add-in load operation has failed."
- case .invalidKeyRef:
- return "An invalid key was encountered."
- case .invalidKeyHierarchy:
- return "An invalid key hierarchy was encountered."
- case .addinUnloadFailed:
- return "The add-in unload operation has failed."
- case .libraryReferenceNotFound:
- return "A library reference was not found."
- case .invalidAddinFunctionTable:
- return "An invalid add-in function table was encountered."
- case .invalidServiceMask:
- return "An invalid service mask was encountered."
- case .moduleNotLoaded:
- return "A module was not loaded."
- case .invalidSubServiceID:
- return "An invalid subservice ID was encountered."
- case .attributeNotInContext:
- return "An attribute was not in the context."
- case .moduleManagerInitializeFailed:
- return "A module failed to initialize."
- case .moduleManagerNotFound:
- return "A module was not found."
- case .eventNotificationCallbackNotFound:
- return "An event notification callback was not found."
- case .inputLengthError:
- return "An input length error was encountered."
- case .outputLengthError:
- return "An output length error was encountered."
- case .privilegeNotSupported:
- return "The privilege is not supported."
- case .deviceError:
- return "A device error was encountered."
- case .attachHandleBusy:
- return "The CSP handle was busy."
- case .notLoggedIn:
- return "You are not logged in."
- case .algorithmMismatch:
- return "An algorithm mismatch was encountered."
- case .keyUsageIncorrect:
- return "The key usage is incorrect."
- case .keyBlobTypeIncorrect:
- return "The key blob type is incorrect."
- case .keyHeaderInconsistent:
- return "The key header is inconsistent."
- case .unsupportedKeyFormat:
- return "The key header format is not supported."
- case .unsupportedKeySize:
- return "The key size is not supported."
- case .invalidKeyUsageMask:
- return "The key usage mask is not valid."
- case .unsupportedKeyUsageMask:
- return "The key usage mask is not supported."
- case .invalidKeyAttributeMask:
- return "The key attribute mask is not valid."
- case .unsupportedKeyAttributeMask:
- return "The key attribute mask is not supported."
- case .invalidKeyLabel:
- return "The key label is not valid."
- case .unsupportedKeyLabel:
- return "The key label is not supported."
- case .invalidKeyFormat:
- return "The key format is not valid."
- case .unsupportedVectorOfBuffers:
- return "The vector of buffers is not supported."
- case .invalidInputVector:
- return "The input vector is not valid."
- case .invalidOutputVector:
- return "The output vector is not valid."
- case .invalidContext:
- return "An invalid context was encountered."
- case .invalidAlgorithm:
- return "An invalid algorithm was encountered."
- case .invalidAttributeKey:
- return "A key attribute was not valid."
- case .missingAttributeKey:
- return "A key attribute was missing."
- case .invalidAttributeInitVector:
- return "An init vector attribute was not valid."
- case .missingAttributeInitVector:
- return "An init vector attribute was missing."
- case .invalidAttributeSalt:
- return "A salt attribute was not valid."
- case .missingAttributeSalt:
- return "A salt attribute was missing."
- case .invalidAttributePadding:
- return "A padding attribute was not valid."
- case .missingAttributePadding:
- return "A padding attribute was missing."
- case .invalidAttributeRandom:
- return "A random number attribute was not valid."
- case .missingAttributeRandom:
- return "A random number attribute was missing."
- case .invalidAttributeSeed:
- return "A seed attribute was not valid."
- case .missingAttributeSeed:
- return "A seed attribute was missing."
- case .invalidAttributePassphrase:
- return "A passphrase attribute was not valid."
- case .missingAttributePassphrase:
- return "A passphrase attribute was missing."
- case .invalidAttributeKeyLength:
- return "A key length attribute was not valid."
- case .missingAttributeKeyLength:
- return "A key length attribute was missing."
- case .invalidAttributeBlockSize:
- return "A block size attribute was not valid."
- case .missingAttributeBlockSize:
- return "A block size attribute was missing."
- case .invalidAttributeOutputSize:
- return "An output size attribute was not valid."
- case .missingAttributeOutputSize:
- return "An output size attribute was missing."
- case .invalidAttributeRounds:
- return "The number of rounds attribute was not valid."
- case .missingAttributeRounds:
- return "The number of rounds attribute was missing."
- case .invalidAlgorithmParms:
- return "An algorithm parameters attribute was not valid."
- case .missingAlgorithmParms:
- return "An algorithm parameters attribute was missing."
- case .invalidAttributeLabel:
- return "A label attribute was not valid."
- case .missingAttributeLabel:
- return "A label attribute was missing."
- case .invalidAttributeKeyType:
- return "A key type attribute was not valid."
- case .missingAttributeKeyType:
- return "A key type attribute was missing."
- case .invalidAttributeMode:
- return "A mode attribute was not valid."
- case .missingAttributeMode:
- return "A mode attribute was missing."
- case .invalidAttributeEffectiveBits:
- return "An effective bits attribute was not valid."
- case .missingAttributeEffectiveBits:
- return "An effective bits attribute was missing."
- case .invalidAttributeStartDate:
- return "A start date attribute was not valid."
- case .missingAttributeStartDate:
- return "A start date attribute was missing."
- case .invalidAttributeEndDate:
- return "An end date attribute was not valid."
- case .missingAttributeEndDate:
- return "An end date attribute was missing."
- case .invalidAttributeVersion:
- return "A version attribute was not valid."
- case .missingAttributeVersion:
- return "A version attribute was missing."
- case .invalidAttributePrime:
- return "A prime attribute was not valid."
- case .missingAttributePrime:
- return "A prime attribute was missing."
- case .invalidAttributeBase:
- return "A base attribute was not valid."
- case .missingAttributeBase:
- return "A base attribute was missing."
- case .invalidAttributeSubprime:
- return "A subprime attribute was not valid."
- case .missingAttributeSubprime:
- return "A subprime attribute was missing."
- case .invalidAttributeIterationCount:
- return "An iteration count attribute was not valid."
- case .missingAttributeIterationCount:
- return "An iteration count attribute was missing."
- case .invalidAttributeDLDBHandle:
- return "A database handle attribute was not valid."
- case .missingAttributeDLDBHandle:
- return "A database handle attribute was missing."
- case .invalidAttributeAccessCredentials:
- return "An access credentials attribute was not valid."
- case .missingAttributeAccessCredentials:
- return "An access credentials attribute was missing."
- case .invalidAttributePublicKeyFormat:
- return "A public key format attribute was not valid."
- case .missingAttributePublicKeyFormat:
- return "A public key format attribute was missing."
- case .invalidAttributePrivateKeyFormat:
- return "A private key format attribute was not valid."
- case .missingAttributePrivateKeyFormat:
- return "A private key format attribute was missing."
- case .invalidAttributeSymmetricKeyFormat:
- return "A symmetric key format attribute was not valid."
- case .missingAttributeSymmetricKeyFormat:
- return "A symmetric key format attribute was missing."
- case .invalidAttributeWrappedKeyFormat:
- return "A wrapped key format attribute was not valid."
- case .missingAttributeWrappedKeyFormat:
- return "A wrapped key format attribute was missing."
- case .stagedOperationInProgress:
- return "A staged operation is in progress."
- case .stagedOperationNotStarted:
- return "A staged operation was not started."
- case .verifyFailed:
- return "A cryptographic verification failure has occurred."
- case .querySizeUnknown:
- return "The query size is unknown."
- case .blockSizeMismatch:
- return "A block size mismatch occurred."
- case .publicKeyInconsistent:
- return "The public key was inconsistent."
- case .deviceVerifyFailed:
- return "A device verification failure has occurred."
- case .invalidLoginName:
- return "An invalid login name was detected."
- case .alreadyLoggedIn:
- return "The user is already logged in."
- case .invalidDigestAlgorithm:
- return "An invalid digest algorithm was detected."
- case .invalidCRLGroup:
- return "An invalid CRL group was detected."
- case .certificateCannotOperate:
- return "The certificate cannot operate."
- case .certificateExpired:
- return "An expired certificate was detected."
- case .certificateNotValidYet:
- return "The certificate is not yet valid."
- case .certificateRevoked:
- return "The certificate was revoked."
- case .certificateSuspended:
- return "The certificate was suspended."
- case .insufficientCredentials:
- return "Insufficient credentials were detected."
- case .invalidAction:
- return "The action was not valid."
- case .invalidAuthority:
- return "The authority was not valid."
- case .verifyActionFailed:
- return "A verify action has failed."
- case .invalidCertAuthority:
- return "The certificate authority was not valid."
- case .invaldCRLAuthority:
- return "The CRL authority was not valid."
- case .invalidCRLEncoding:
- return "The CRL encoding was not valid."
- case .invalidCRLType:
- return "The CRL type was not valid."
- case .invalidCRL:
- return "The CRL was not valid."
- case .invalidFormType:
- return "The form type was not valid."
- case .invalidID:
- return "The ID was not valid."
- case .invalidIdentifier:
- return "The identifier was not valid."
- case .invalidIndex:
- return "The index was not valid."
- case .invalidPolicyIdentifiers:
- return "The policy identifiers are not valid."
- case .invalidTimeString:
- return "The time specified was not valid."
- case .invalidReason:
- return "The trust policy reason was not valid."
- case .invalidRequestInputs:
- return "The request inputs are not valid."
- case .invalidResponseVector:
- return "The response vector was not valid."
- case .invalidStopOnPolicy:
- return "The stop-on policy was not valid."
- case .invalidTuple:
- return "The tuple was not valid."
- case .multipleValuesUnsupported:
- return "Multiple values are not supported."
- case .notTrusted:
- return "The trust policy was not trusted."
- case .noDefaultAuthority:
- return "No default authority was detected."
- case .rejectedForm:
- return "The trust policy had a rejected form."
- case .requestLost:
- return "The request was lost."
- case .requestRejected:
- return "The request was rejected."
- case .unsupportedAddressType:
- return "The address type is not supported."
- case .unsupportedService:
- return "The service is not supported."
- case .invalidTupleGroup:
- return "The tuple group was not valid."
- case .invalidBaseACLs:
- return "The base ACLs are not valid."
- case .invalidTupleCredendtials:
- return "The tuple credentials are not valid."
- case .invalidEncoding:
- return "The encoding was not valid."
- case .invalidValidityPeriod:
- return "The validity period was not valid."
- case .invalidRequestor:
- return "The requestor was not valid."
- case .requestDescriptor:
- return "The request descriptor was not valid."
- case .invalidBundleInfo:
- return "The bundle information was not valid."
- case .invalidCRLIndex:
- return "The CRL index was not valid."
- case .noFieldValues:
- return "No field values were detected."
- case .unsupportedFieldFormat:
- return "The field format is not supported."
- case .unsupportedIndexInfo:
- return "The index information is not supported."
- case .unsupportedLocality:
- return "The locality is not supported."
- case .unsupportedNumAttributes:
- return "The number of attributes is not supported."
- case .unsupportedNumIndexes:
- return "The number of indexes is not supported."
- case .unsupportedNumRecordTypes:
- return "The number of record types is not supported."
- case .fieldSpecifiedMultiple:
- return "Too many fields were specified."
- case .incompatibleFieldFormat:
- return "The field format was incompatible."
- case .invalidParsingModule:
- return "The parsing module was not valid."
- case .databaseLocked:
- return "The database is locked."
- case .datastoreIsOpen:
- return "The data store is open."
- case .missingValue:
- return "A missing value was detected."
- case .unsupportedQueryLimits:
- return "The query limits are not supported."
- case .unsupportedNumSelectionPreds:
- return "The number of selection predicates is not supported."
- case .unsupportedOperator:
- return "The operator is not supported."
- case .invalidDBLocation:
- return "The database location is not valid."
- case .invalidAccessRequest:
- return "The access request is not valid."
- case .invalidIndexInfo:
- return "The index information is not valid."
- case .invalidNewOwner:
- return "The new owner is not valid."
- case .invalidModifyMode:
- return "The modify mode is not valid."
- case .missingRequiredExtension:
- return "A required certificate extension is missing."
- case .extendedKeyUsageNotCritical:
- return "The extended key usage extension was not marked critical."
- case .timestampMissing:
- return "A timestamp was expected but was not found."
- case .timestampInvalid:
- return "The timestamp was not valid."
- case .timestampNotTrusted:
- return "The timestamp was not trusted."
- case .timestampServiceNotAvailable:
- return "The timestamp service is not available."
- case .timestampBadAlg:
- return "An unrecognized or unsupported Algorithm Identifier in timestamp."
- case .timestampBadRequest:
- return "The timestamp transaction is not permitted or supported."
- case .timestampBadDataFormat:
- return "The timestamp data submitted has the wrong format."
- case .timestampTimeNotAvailable:
- return "The time source for the Timestamp Authority is not available."
- case .timestampUnacceptedPolicy:
- return "The requested policy is not supported by the Timestamp Authority."
- case .timestampUnacceptedExtension:
- return "The requested extension is not supported by the Timestamp Authority."
- case .timestampAddInfoNotAvailable:
- return "The additional information requested is not available."
- case .timestampSystemFailure:
- return "The timestamp request cannot be handled due to system failure."
- case .signingTimeMissing:
- return "A signing time was expected but was not found."
- case .timestampRejection:
- return "A timestamp transaction was rejected."
- case .timestampWaiting:
- return "A timestamp transaction is waiting."
- case .timestampRevocationWarning:
- return "A timestamp authority revocation warning was issued."
- case .timestampRevocationNotification:
- return "A timestamp authority revocation notification was issued."
- case .unexpectedError:
- return "Unexpected error has occurred."
- }
- }
- }
- extension Status: CustomNSError {
- public static let errorDomain = KeychainAccessErrorDomain
- public var errorCode: Int {
- return Int(rawValue)
- }
- public var errorUserInfo: [String : Any] {
- return [NSLocalizedDescriptionKey: description]
- }
- }
|