Files
simplex-chat/apps/ios/SimpleXChat/CryptoFile.swift
Evgeny Poberezkin 748572ace9 ui: types and stubs to encrypt local files (#3003)
* ui: types and stubs to encrypt local files

* ios: encrypt automatically received images in local storage

* encrypt sent images, marked to be received via NSE

* ios: encrypt sent and received local voice files

* encrypt sent and received local files

* fix NSE

* remove comment

* decrypt files in background thread
2023-09-07 11:28:37 +01:00

65 lines
2.4 KiB
Swift

//
// CryptoFile.swift
// SimpleX (iOS)
//
// Created by Evgeny on 05/09/2023.
// Copyright © 2023 SimpleX Chat. All rights reserved.
//
import Foundation
enum WriteFileResult: Decodable {
case result(cryptoArgs: CryptoFileArgs)
case error(writeError: String)
}
public func writeCryptoFile(path: String, data: Data) throws -> CryptoFileArgs {
let ptr: UnsafeMutableRawPointer = malloc(data.count)
memcpy(ptr, (data as NSData).bytes, data.count)
var cPath = path.cString(using: .utf8)!
let cjson = chat_write_file(&cPath, ptr, Int32(data.count))!
let d = fromCString(cjson).data(using: .utf8)!
switch try jsonDecoder.decode(WriteFileResult.self, from: d) {
case let .result(cfArgs): return cfArgs
case let .error(err): throw RuntimeError(err)
}
}
enum ReadFileResult: Decodable {
case result(fileSize: Int)
case error(readError: String)
}
public func readCryptoFile(path: String, cryptoArgs: CryptoFileArgs) throws -> Data {
var cPath = path.cString(using: .utf8)!
var cKey = cryptoArgs.fileKey.cString(using: .utf8)!
var cNonce = cryptoArgs.fileNonce.cString(using: .utf8)!
let r = chat_read_file(&cPath, &cKey, &cNonce)!
let d = String.init(cString: r).data(using: .utf8)!
switch try jsonDecoder.decode(ReadFileResult.self, from: d) {
case let .error(err): throw RuntimeError(err)
case let .result(size): return Data(bytes: r.advanced(by: d.count + 1), count: size)
}
}
public func encryptCryptoFile(fromPath: String, toPath: String) throws -> CryptoFileArgs {
var cFromPath = fromPath.cString(using: .utf8)!
var cToPath = toPath.cString(using: .utf8)!
let cjson = chat_encrypt_file(&cFromPath, &cToPath)!
let d = fromCString(cjson).data(using: .utf8)!
switch try jsonDecoder.decode(WriteFileResult.self, from: d) {
case let .result(cfArgs): return cfArgs
case let .error(err): throw RuntimeError(err)
}
}
public func decryptCryptoFile(fromPath: String, cryptoArgs: CryptoFileArgs, toPath: String) throws {
var cFromPath = fromPath.cString(using: .utf8)!
var cKey = cryptoArgs.fileKey.cString(using: .utf8)!
var cNonce = cryptoArgs.fileNonce.cString(using: .utf8)!
var cToPath = toPath.cString(using: .utf8)!
let cErr = chat_decrypt_file(&cFromPath, &cKey, &cNonce, &cToPath)!
let err = fromCString(cErr)
if err != "" { throw RuntimeError(err) }
}