зеркало из https://github.com/nextcloud/ios.git
coding
This commit is contained in:
Родитель
64005a25c9
Коммит
657ba0d9f9
|
@ -26,4 +26,4 @@ import Foundation
|
|||
// Database Realm
|
||||
//
|
||||
let databaseName = "nextcloud.realm"
|
||||
let databaseSchemaVersion: UInt64 = 304
|
||||
let databaseSchemaVersion: UInt64 = 308
|
||||
|
|
|
@ -25,6 +25,19 @@ import Foundation
|
|||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
class tableE2eEncryptionLock: Object {
|
||||
|
||||
@objc dynamic var account = ""
|
||||
@objc dynamic var date = NSDate()
|
||||
@objc dynamic var fileId = ""
|
||||
@objc dynamic var serverUrl = ""
|
||||
@objc dynamic var e2eToken = ""
|
||||
|
||||
override static func primaryKey() -> String {
|
||||
return "fileId"
|
||||
}
|
||||
}
|
||||
|
||||
class tableE2eEncryption: Object {
|
||||
|
||||
@objc dynamic var account = ""
|
||||
|
@ -47,18 +60,8 @@ class tableE2eEncryption: Object {
|
|||
}
|
||||
}
|
||||
|
||||
class tableE2eEncryptionLock: Object {
|
||||
|
||||
@objc dynamic var account = ""
|
||||
@objc dynamic var date = NSDate()
|
||||
@objc dynamic var fileId = ""
|
||||
@objc dynamic var serverUrl = ""
|
||||
@objc dynamic var e2eToken = ""
|
||||
|
||||
override static func primaryKey() -> String {
|
||||
return "fileId"
|
||||
}
|
||||
}
|
||||
// MARK: -
|
||||
// MARK: Table V1, V1.2
|
||||
|
||||
class tableE2eMetadata: Object {
|
||||
|
||||
|
@ -68,10 +71,38 @@ class tableE2eMetadata: Object {
|
|||
@Persisted var version: Double = 0
|
||||
}
|
||||
|
||||
|
||||
// MARK: -
|
||||
// MARK: Table V2
|
||||
|
||||
class tableE2eMetadataV2: Object {
|
||||
|
||||
@Persisted(primaryKey: true) var accountServerUrl = ""
|
||||
@Persisted var keyChecksums: String = ""
|
||||
@Persisted var deleted: Bool = false
|
||||
@Persisted var counter: Int = 0
|
||||
@Persisted var folders: String = ""
|
||||
@Persisted var version: String = "2.0"
|
||||
}
|
||||
|
||||
class tableE2eUsersV2: Object {
|
||||
|
||||
@Persisted(primaryKey: true) var accountServerUrlUserId = ""
|
||||
@Persisted var certificate = ""
|
||||
@Persisted var encryptedFiledropKey: String?
|
||||
@Persisted var encryptedMetadataKey: String?
|
||||
@Persisted var decryptedFiledropKey: Data?
|
||||
@Persisted var decryptedMetadataKey: Data?
|
||||
@Persisted var filedropKey: String?
|
||||
@Persisted var metadataKey: String?
|
||||
@Persisted var serverUrl = ""
|
||||
@Persisted var userId = ""
|
||||
}
|
||||
|
||||
extension NCManageDatabase {
|
||||
|
||||
// MARK: -
|
||||
// MARK: Table e2e Encryption
|
||||
// MARK: tableE2eEncryption
|
||||
|
||||
@objc func addE2eEncryption(_ e2e: tableE2eEncryption) {
|
||||
|
||||
|
@ -219,7 +250,7 @@ extension NCManageDatabase {
|
|||
}
|
||||
|
||||
// MARK: -
|
||||
// MARK: Table e2ee Metadata
|
||||
// MARK: V1
|
||||
|
||||
func getE2eMetadata(account: String, serverUrl: String) -> tableE2eMetadata? {
|
||||
|
||||
|
@ -251,4 +282,119 @@ extension NCManageDatabase {
|
|||
NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
// MARK: V2
|
||||
|
||||
func setE2EUsersV2(account: String,
|
||||
serverUrl: String,
|
||||
userId: String,
|
||||
certificate: String,
|
||||
encryptedFiledropKey: String?,
|
||||
encryptedMetadataKey: String?,
|
||||
decryptedFiledropKey: Data?,
|
||||
decryptedMetadataKey: Data?,
|
||||
filedropKey: String?,
|
||||
metadataKey: String?) {
|
||||
|
||||
do {
|
||||
let realm = try Realm()
|
||||
try realm.write {
|
||||
let addObject = tableE2eUsersV2()
|
||||
addObject.accountServerUrlUserId = account + serverUrl + userId
|
||||
addObject.certificate = certificate
|
||||
addObject.encryptedFiledropKey = encryptedFiledropKey
|
||||
addObject.encryptedMetadataKey = encryptedMetadataKey
|
||||
addObject.decryptedFiledropKey = decryptedFiledropKey
|
||||
addObject.decryptedMetadataKey = decryptedMetadataKey
|
||||
addObject.filedropKey = filedropKey
|
||||
addObject.metadataKey = metadataKey
|
||||
addObject.serverUrl = serverUrl
|
||||
addObject.userId = userId
|
||||
realm.add(addObject, update: .all)
|
||||
}
|
||||
} catch let error {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func getE2EUsersV2(account: String, serverUrl: String, userId: String) -> tableE2eUsersV2? {
|
||||
|
||||
do {
|
||||
let realm = try Realm()
|
||||
realm.refresh()
|
||||
return realm.objects(tableE2eUsersV2.self).filter("accountServerUrlUserId == %@", account + serverUrl + userId).first
|
||||
} catch let error as NSError {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func deleteE2EUsersV2(account: String, serverUrl: String) {
|
||||
|
||||
do {
|
||||
let realm = try Realm()
|
||||
try realm.write {
|
||||
let results = realm.objects(tableE2eEncryption.self).filter("account == %@ AND serverUrl == %@", account, serverUrl)
|
||||
realm.delete(results)
|
||||
}
|
||||
} catch let error {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func getE2eMetadataV2(account: String, serverUrl: String) -> tableE2eMetadataV2? {
|
||||
|
||||
do {
|
||||
let realm = try Realm()
|
||||
realm.refresh()
|
||||
return realm.objects(tableE2eMetadataV2.self).filter("accountServerUrl == %@", account + serverUrl).first
|
||||
} catch let error as NSError {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func setE2eMetadataV2(account: String, serverUrl: String, keyChecksums: [String]?, deleted: Bool, counter: Int, folders: [String: String]?, version: String) {
|
||||
|
||||
do {
|
||||
let realm = try Realm()
|
||||
try realm.write {
|
||||
let addObject = tableE2eMetadataV2()
|
||||
addObject.accountServerUrl = account + serverUrl
|
||||
if let keyChecksums {
|
||||
addObject.keyChecksums = keyChecksums.joined(separator: ",")
|
||||
}
|
||||
addObject.deleted = deleted
|
||||
addObject.counter = counter
|
||||
if let folders {
|
||||
var arrayFolders: [String] = []
|
||||
for folder in folders {
|
||||
let item = folder.key + ":" + folder.value
|
||||
arrayFolders.append(item)
|
||||
}
|
||||
addObject.folders = arrayFolders.joined(separator: ",")
|
||||
}
|
||||
addObject.version = version
|
||||
realm.add(addObject, update: .all)
|
||||
}
|
||||
} catch let error {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func deleteE2eMetadataV2(account: String, serverUrl: String) {
|
||||
|
||||
do {
|
||||
let realm = try Realm()
|
||||
try realm.write {
|
||||
let results = realm.objects(tableE2eMetadataV2.self).filter("accountServerUrl == %@", account + serverUrl)
|
||||
realm.delete(results)
|
||||
}
|
||||
} catch let error {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,14 +119,6 @@ class NCEndToEndMetadata: NSObject {
|
|||
let version: String
|
||||
}
|
||||
|
||||
struct PlainUsers {
|
||||
let userId: String
|
||||
let certificate: String
|
||||
let metadataKey: String
|
||||
let decryptedMetadataKey: Data
|
||||
let filedropKey: String
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// MARK: Encode JSON Metadata Bridge
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
@ -298,7 +290,6 @@ class NCEndToEndMetadata: NSObject {
|
|||
object.key = key
|
||||
object.initializationVector = initializationVector
|
||||
object.metadataKey = metadataKey
|
||||
object.metadataVersion = metadataVersion
|
||||
object.mimeType = mimetype
|
||||
object.serverUrl = serverUrl
|
||||
|
||||
|
@ -320,8 +311,6 @@ class NCEndToEndMetadata: NSObject {
|
|||
|
||||
let decoder = JSONDecoder()
|
||||
let privateKey = CCUtility.getEndToEndPrivateKey(account)
|
||||
var metadataVersion: Double = 0
|
||||
var plainUsers: [PlainUsers] = []
|
||||
|
||||
do {
|
||||
let json = try decoder.decode(E2eeV20.self, from: data)
|
||||
|
@ -329,9 +318,11 @@ class NCEndToEndMetadata: NSObject {
|
|||
let metadata = json.metadata
|
||||
let users = json.users
|
||||
let filedrop = json.filedrop
|
||||
metadataVersion = Double(json.version) ?? 0
|
||||
let version = json.version as String? ?? "2.0"
|
||||
|
||||
// DATA
|
||||
NCManageDatabase.shared.deleteE2eMetadataV2(account: account, serverUrl: serverUrl)
|
||||
NCManageDatabase.shared.deleteE2EUsersV2(account: account, serverUrl: serverUrl)
|
||||
NCManageDatabase.shared.deleteE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl))
|
||||
|
||||
//
|
||||
|
@ -340,9 +331,10 @@ class NCEndToEndMetadata: NSObject {
|
|||
|
||||
for user in users {
|
||||
|
||||
var metadataKey = ""
|
||||
var filedropKey = ""
|
||||
var decryptedMetadataKey = Data()
|
||||
var decryptedMetadataKey: Data?
|
||||
var decryptedFiledropKey: Data?
|
||||
var metadataKey: String?
|
||||
var filedropKey: String?
|
||||
|
||||
if let encryptedMetadataKey = user.encryptedMetadataKey {
|
||||
let data = Data(base64Encoded: encryptedMetadataKey)
|
||||
|
@ -355,19 +347,20 @@ class NCEndToEndMetadata: NSObject {
|
|||
if let encryptedFiledropKey = user.encryptedFiledropKey {
|
||||
let data = Data(base64Encoded: encryptedFiledropKey)
|
||||
if let decrypted = NCEndToEndEncryption.sharedManager().decryptAsymmetricData(data, privateKey: privateKey) {
|
||||
decryptedFiledropKey = decrypted
|
||||
filedropKey = decrypted.base64EncodedString()
|
||||
}
|
||||
}
|
||||
|
||||
plainUsers.append(PlainUsers(userId: user.userId, certificate: user.certificate, metadataKey: metadataKey, decryptedMetadataKey: decryptedMetadataKey, filedropKey: filedropKey))
|
||||
NCManageDatabase.shared.setE2EUsersV2(account: account, serverUrl: serverUrl, userId: user.userId, certificate: user.certificate, encryptedFiledropKey: user.encryptedFiledropKey, encryptedMetadataKey: user.encryptedMetadataKey, decryptedFiledropKey: decryptedFiledropKey, decryptedMetadataKey: decryptedMetadataKey, filedropKey: filedropKey, metadataKey: metadataKey)
|
||||
}
|
||||
|
||||
//
|
||||
// metadata
|
||||
//
|
||||
|
||||
if let plainUser = plainUsers.first(where: { $0.userId == userId }) {
|
||||
if let decrypted = NCEndToEndEncryption.sharedManager().decryptPayloadFile(metadata.ciphertext, key: plainUser.metadataKey, initializationVector: metadata.nonce, authenticationTag: metadata.authenticationTag) {
|
||||
if let tableE2eUsersV2 = NCManageDatabase.shared.getE2EUsersV2(account: account, serverUrl: serverUrl, userId: userId), let metadataKey = tableE2eUsersV2.metadataKey {
|
||||
if let decrypted = NCEndToEndEncryption.sharedManager().decryptPayloadFile(metadata.ciphertext, key: tableE2eUsersV2.metadataKey, initializationVector: metadata.nonce, authenticationTag: metadata.authenticationTag) {
|
||||
if decrypted.isGzipped {
|
||||
do {
|
||||
let data = try decrypted.gunzipped()
|
||||
|
@ -377,15 +370,18 @@ class NCEndToEndMetadata: NSObject {
|
|||
if let json = try JSONSerialization.jsonObject(with: data) as? [String: AnyObject] {
|
||||
|
||||
let keyChecksums = json["keyChecksums"] as? [String]
|
||||
let deleted = json["deleted"]
|
||||
let deleted = json["deleted"] as? Bool ?? false
|
||||
let counter = json["counter"] as? Int ?? 0
|
||||
|
||||
// TEST hash
|
||||
if let keyChecksums,
|
||||
let hash = NCEndToEndEncryption.sharedManager().createSHA256(from: plainUser.decryptedMetadataKey),
|
||||
let hash = NCEndToEndEncryption.sharedManager().createSHA256(from: tableE2eUsersV2.decryptedMetadataKey),
|
||||
!keyChecksums.contains(hash) {
|
||||
return NKError(errorCode: NCGlobal.shared.errorE2EEKeyChecksums, errorDescription: NSLocalizedString("_e3ee_keyChecksum_", comment: ""))
|
||||
}
|
||||
|
||||
NCManageDatabase.shared.setE2eMetadataV2(account: account, serverUrl: serverUrl, keyChecksums: keyChecksums, deleted: deleted, counter: counter, folders: json["folders"] as? [String: String], version: version)
|
||||
|
||||
if let files = json["files"] as? [String: Any] {
|
||||
for file in files {
|
||||
let uid = file.key
|
||||
|
@ -395,7 +391,7 @@ class NCEndToEndMetadata: NSObject {
|
|||
let mimetype = dic["mimetype"],
|
||||
let key = dic["key"],
|
||||
let filename = dic["filename"] {
|
||||
addE2eEncryption(fileNameIdentifier: uid, filename: filename, authenticationTag: authenticationTag, key: key, initializationVector: nonce, metadataKey: plainUser.metadataKey, mimetype: mimetype)
|
||||
addE2eEncryption(fileNameIdentifier: uid, filename: filename, authenticationTag: authenticationTag, key: key, initializationVector: nonce, metadataKey: metadataKey, mimetype: mimetype)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -403,7 +399,7 @@ class NCEndToEndMetadata: NSObject {
|
|||
|
||||
if let folders = json["folders"] as? [String: String] {
|
||||
for folder in folders {
|
||||
addE2eEncryption(fileNameIdentifier: folder.key, filename: folder.value, authenticationTag: metadata.authenticationTag, key: plainUser.metadataKey, initializationVector: metadata.nonce, metadataKey: plainUser.metadataKey, mimetype: "httpd/unix-directory")
|
||||
addE2eEncryption(fileNameIdentifier: folder.key, filename: folder.value, authenticationTag: metadata.authenticationTag, key: metadataKey, initializationVector: metadata.nonce, metadataKey: metadataKey, mimetype: "httpd/unix-directory")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче