This commit is contained in:
Marino Faggiana 2023-08-09 17:54:00 +02:00
Родитель 64005a25c9
Коммит 657ba0d9f9
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 2F5F63C3EF460487
3 изменённых файлов: 179 добавлений и 37 удалений

Просмотреть файл

@ -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")
}
}
}