@@ -51,6 +51,7 @@ public class VaultManager {
5151 guard VaultManager . cachedDecorators [ vaultUID] == nil else {
5252 throw VaultManagerError . vaultAlreadyExists
5353 }
54+ let vaultVersion = 7
5455 let masterkey = try Masterkey . createNew ( )
5556 let cryptor = Cryptor ( masterkey: masterkey)
5657 let delegate = try providerManager. getProvider ( with: delegateAccountUID)
@@ -60,7 +61,7 @@ public class VaultManager {
6061 let tmpDirURL = URL ( fileURLWithPath: NSTemporaryDirectory ( ) , isDirectory: true ) . appendingPathComponent ( UUID ( ) . uuidString, isDirectory: true )
6162 try FileManager . default. createDirectory ( at: tmpDirURL, withIntermediateDirectories: true )
6263 let localMasterkeyURL = tmpDirURL. appendingPathComponent ( UUID ( ) . uuidString, isDirectory: false )
63- let masterkeyData = try self . exportMasterkey ( masterkey, password: password)
64+ let masterkeyData = try self . exportMasterkey ( masterkey, vaultVersion : vaultVersion , password: password)
6465 try masterkeyData. write ( to: localMasterkeyURL)
6566 let masterkeyCloudPath = vaultPath. appendingPathComponent ( " masterkey.cryptomator " )
6667 return delegate. uploadFile ( from: localMasterkeyURL, to: masterkeyCloudPath, replaceExisting: false )
@@ -76,8 +77,10 @@ public class VaultManager {
7677 let shorteningDecorator = try VaultFormat7ShorteningProviderDecorator ( delegate: decorator, vaultPath: vaultPath)
7778 let account = VaultAccount ( vaultUID: vaultUID, delegateAccountUID: delegateAccountUID, vaultPath: vaultPath, lastUpToDateCheck: Date ( ) )
7879 try self . vaultAccountManager. saveNewAccount ( account)
79- try self . saveFileProviderConformMasterkeyToKeychain ( masterkey, forVaultUID: vaultUID, password: password, storePasswordInKeychain: storePasswordInKeychain)
80+ try self . saveFileProviderConformMasterkeyToKeychain ( masterkey, forVaultUID: vaultUID, vaultVersion : vaultVersion , password: password, storePasswordInKeychain: storePasswordInKeychain)
8081 VaultManager . cachedDecorators [ vaultUID] = shorteningDecorator
82+ } . then {
83+ self . addFileProviderDomain ( forVaultUID: vaultUID, vaultPath: vaultPath)
8184 }
8285 } catch {
8386 return Promise ( error)
@@ -102,19 +105,20 @@ public class VaultManager {
102105 */
103106 public func manualUnlockVault( withUID vaultUID: String , password: String ) throws -> CloudProvider {
104107 let keychainEntry = try getVaultFromKeychain ( forVaultUID: vaultUID)
105- let masterkey = try Masterkey . createFromMasterkeyFile ( jsonData: keychainEntry. masterkeyData, password: password)
106- return try createVaultDecorator ( from: masterkey, vaultUID: vaultUID)
108+ let masterkeyFile = try MasterkeyFile . withContentFromData ( data: keychainEntry. masterkeyData)
109+ let masterkey = try masterkeyFile. unlock ( passphrase: password)
110+ return try createVaultDecorator ( from: masterkey, vaultUID: vaultUID, vaultVersion: masterkeyFile. version)
107111 }
108112
109- func createVaultDecorator( from masterkey: Masterkey , vaultUID: String ) throws -> CloudProvider {
113+ func createVaultDecorator( from masterkey: Masterkey , vaultUID: String , vaultVersion : Int ) throws -> CloudProvider {
110114 let vaultAccount = try vaultAccountManager. getAccount ( with: vaultUID)
111115 let delegate = try providerManager. getProvider ( with: vaultAccount. delegateAccountUID)
112- return try createVaultDecorator ( from: masterkey, delegate: delegate, vaultPath: vaultAccount. vaultPath, vaultUID: vaultUID)
116+ return try createVaultDecorator ( from: masterkey, delegate: delegate, vaultPath: vaultAccount. vaultPath, vaultUID: vaultUID, vaultVersion : vaultVersion )
113117 }
114118
115- func createVaultDecorator( from masterkey: Masterkey , delegate: CloudProvider , vaultPath: CloudPath , vaultUID: String ) throws -> CloudProvider {
119+ func createVaultDecorator( from masterkey: Masterkey , delegate: CloudProvider , vaultPath: CloudPath , vaultUID: String , vaultVersion : Int ) throws -> CloudProvider {
116120 let cryptor = Cryptor ( masterkey: masterkey)
117- switch masterkey . version {
121+ switch vaultVersion {
118122 case 7 :
119123 let decorator = try VaultFormat7ProviderDecorator ( delegate: delegate, vaultPath: vaultPath, cryptor: cryptor)
120124 let shorteningDecorator = try VaultFormat7ShorteningProviderDecorator ( delegate: decorator, vaultPath: vaultPath)
@@ -140,8 +144,9 @@ public class VaultManager {
140144 guard let password = vault. password else {
141145 throw VaultManagerError . passwordNotInKeychain
142146 }
143- let masterkey = try Masterkey . createFromMasterkeyFile ( jsonData: vault. masterkeyData, password: password)
144- return try createVaultDecorator ( from: masterkey, vaultUID: vaultUID)
147+ let masterkeyFile = try MasterkeyFile . withContentFromData ( data: vault. masterkeyData)
148+ let masterkey = try masterkeyFile. unlock ( passphrase: password)
149+ return try createVaultDecorator ( from: masterkey, vaultUID: vaultUID, vaultVersion: masterkeyFile. version)
145150 }
146151
147152 /**
@@ -161,12 +166,15 @@ public class VaultManager {
161166 let tmpDirURL = FileManager . default. temporaryDirectory
162167 let localMasterkeyURL = tmpDirURL. appendingPathComponent ( UUID ( ) . uuidString, isDirectory: false )
163168 return delegate. downloadFile ( from: masterkeyPath, to: localMasterkeyURL) . then {
164- let masterkey = try Masterkey . createFromMasterkeyFile ( fileURL: localMasterkeyURL, password: password)
169+ let masterkeyFile = try MasterkeyFile . withContentFromURL ( url: localMasterkeyURL)
170+ let masterkey = try masterkeyFile. unlock ( passphrase: password)
165171 let vaultPath = self . getVaultPath ( from: masterkeyPath)
166- _ = try self . createVaultDecorator ( from: masterkey, delegate: delegate, vaultPath: vaultPath, vaultUID: vaultUID)
172+ _ = try self . createVaultDecorator ( from: masterkey, delegate: delegate, vaultPath: vaultPath, vaultUID: vaultUID, vaultVersion : masterkeyFile . version )
167173 let vaultAccount = VaultAccount ( vaultUID: vaultUID, delegateAccountUID: delegateAccountUID, vaultPath: vaultPath, lastUpToDateCheck: Date ( ) )
168- try self . saveFileProviderConformMasterkeyToKeychain ( masterkey, forVaultUID: vaultUID, password: password, storePasswordInKeychain: storePasswordInKeychain)
174+ try self . saveFileProviderConformMasterkeyToKeychain ( masterkey, forVaultUID: vaultUID, vaultVersion : masterkeyFile . version , password: password, storePasswordInKeychain: storePasswordInKeychain)
169175 try self . vaultAccountManager. saveNewAccount ( vaultAccount)
176+ } . then {
177+ self . addFileProviderDomain ( forVaultUID: vaultUID, vaultPath: self . getVaultPath ( from: masterkeyPath) )
170178 }
171179 } catch {
172180 VaultManager . cachedDecorators [ vaultUID] = nil
@@ -220,8 +228,8 @@ public class VaultManager {
220228 /**
221229 - Postcondition: The masterkey is stored in the keychain with a ScryptCostParameter, which allows the usage in the FileProviderExtension (15mb Memory Limit). Additionally: storePasswordInKeychain <=> the password for the masterkey is also stored in the keychain.
222230 */
223- func saveFileProviderConformMasterkeyToKeychain( _ masterkey: Masterkey , forVaultUID vaultUID: String , password: String , storePasswordInKeychain: Bool ) throws {
224- let masterkeyDataForFileProvider = try masterkey . exportEncrypted ( password : password, pepper: [ UInt8] ( ) , scryptCostParam: VaultManager . scryptCostParamForFileProvider)
231+ func saveFileProviderConformMasterkeyToKeychain( _ masterkey: Masterkey , forVaultUID vaultUID: String , vaultVersion : Int , password: String , storePasswordInKeychain: Bool ) throws {
232+ let masterkeyDataForFileProvider = try MasterkeyFile . lock ( masterkey : masterkey , vaultVersion : vaultVersion , passphrase : password, pepper: [ UInt8] ( ) , scryptCostParam: VaultManager . scryptCostParamForFileProvider)
225233 let keychainEntry = VaultKeychainEntry ( masterkeyData: masterkeyDataForFileProvider, password: storePasswordInKeychain ? password : nil )
226234 let jsonEnccoder = JSONEncoder ( )
227235 let encodedEntry = try jsonEnccoder. encode ( keychainEntry)
@@ -239,8 +247,8 @@ public class VaultManager {
239247 return masterkeyPath. deletingLastPathComponent ( )
240248 }
241249
242- func exportMasterkey( _ masterkey: Masterkey , password: String ) throws -> Data {
243- return try masterkey . exportEncrypted ( password : password)
250+ func exportMasterkey( _ masterkey: Masterkey , vaultVersion : Int , password: String ) throws -> Data {
251+ return try MasterkeyFile . lock ( masterkey : masterkey , vaultVersion : vaultVersion , passphrase : password)
244252 }
245253
246254 func removeFileProviderDomain( withVaultUID vaultUID: String ) -> Promise < Void > {
@@ -254,6 +262,12 @@ public class VaultManager {
254262 NSFileProviderManager . remove ( domainForVault)
255263 }
256264 }
265+
266+ func addFileProviderDomain( forVaultUID vaultUID: String , vaultPath: CloudPath ) -> Promise < Void > {
267+ let identifier = NSFileProviderDomainIdentifier ( vaultUID)
268+ let domain = NSFileProviderDomain ( identifier: identifier, displayName: vaultPath. lastPathComponent, pathRelativeToDocumentStorage: vaultUID)
269+ return NSFileProviderManager . add ( domain)
270+ }
257271}
258272
259273extension NSFileProviderManager {
@@ -280,4 +294,16 @@ extension NSFileProviderManager {
280294 }
281295 }
282296 }
297+
298+ class func add( _ domain: NSFileProviderDomain ) -> Promise < Void > {
299+ return Promise< Void> { fulfill, reject in
300+ NSFileProviderManager . add ( domain) { error in
301+ if let error = error {
302+ reject ( error)
303+ } else {
304+ fulfill ( ( ) )
305+ }
306+ }
307+ }
308+ }
283309}
0 commit comments