This commit is contained in:
fmodf 2024-09-08 18:16:01 +02:00
parent 18083e0b19
commit fad7112d69
3 changed files with 71 additions and 8 deletions

View file

@ -38,7 +38,14 @@ extension Message {
switch decodingResult {
case .successMessage(let decodedMessage, _):
martinMessage = decodedMessage
// print(decodedMessage, fingerprint)
if let oob = martinMessage.oob {
contentType = .attachment(.init(
type: oob.attachmentType,
localName: nil,
thumbnailName: nil,
remotePath: oob
))
}
case .successTransportKey:
break

View file

@ -28,13 +28,27 @@ final class AESGSMEngine: AES_GCM_Engine {
func decrypt(iv: Data, key: Data, encoded: Data, auth tag: Data?, output: UnsafeMutablePointer<Data>?) -> Bool {
do {
let symmetricKey = SymmetricKey(data: key)
guard let tag = tag else {
print("Tag is missing")
return false
}
let sealedBox = try AES.GCM.SealedBox(nonce: AES.GCM.Nonce(data: iv), ciphertext: encoded, tag: tag)
let decryptedData = try AES.GCM.open(sealedBox, using: symmetricKey)
let sealedBox: AES.GCM.SealedBox
if let tag {
sealedBox = try AES.GCM.SealedBox(nonce: AES.GCM.Nonce(data: iv), ciphertext: encoded, tag: tag)
} else {
let embeddedTag = encoded.subdata(in: (encoded.count - 16) ..< encoded.count)
let payload = encoded.subdata(in: 0 ..< (encoded.count - 16))
sealedBox = try AES.GCM.SealedBox(nonce: AES.GCM.Nonce(data: iv), ciphertext: payload, tag: embeddedTag)
}
let decryptedData = try AES.GCM.open(sealedBox, using: symmetricKey)
// var payload = encoded
//
// var tag = tag
// if tag == nil {
// tag = payload.subdata(in: (payload.count - 16) ..< payload.count)
// encoded = payload.subdata(in: 0 ..< (payload.count - 16))
// }
// let sealedBox = try AES.GCM.SealedBox(nonce: AES.GCM.Nonce(data: iv), ciphertext: encoded, tag: tag)
// let decryptedData = try AES.GCM.open(sealedBox, using: symmetricKey)
//
if let output = output {
output.pointee = decryptedData
}

View file

@ -278,10 +278,23 @@ extension AttachmentsStore {
guard case .attachment(let attachment) = message.contentType else {
return
}
guard let remotePath = attachment.remotePath, let remoteUrl = URL(string: remotePath) else {
guard let remotePath = attachment.remotePath, var remoteUrl = URL(string: remotePath) else {
return
}
do {
// if attachment encrypted, extract the key
// and format remote url
var encryptionKey: String?
if remoteUrl.scheme == "aesgcm", var components = URLComponents(url: remoteUrl, resolvingAgainstBaseURL: true) {
encryptionKey = components.fragment
components.scheme = "https"
components.fragment = nil
if let tmpUrl = components.url {
remoteUrl = tmpUrl
}
}
// make local name/path
let localName = "\(message.id)_\(UUID().uuidString).\(remoteUrl.lastPathComponent)"
let localUrl = FolderWrapper.shared.fileFolder.appendingPathComponent(localName)
@ -289,6 +302,35 @@ extension AttachmentsStore {
let (tempUrl, _) = try await URLSession.shared.download(from: remoteUrl)
try FileManager.default.moveItem(at: tempUrl, to: localUrl)
if let encryptionKey {
// Decrypt the file
guard encryptionKey.count % 2 == 0, encryptionKey.count > 64 else {
throw AppError.securityError
}
let fragmentData = encryptionKey.map { char -> UInt8 in
return UInt8(char.hexDigitValue ?? 0)
}
let ivLen = fragmentData.count - (32 * 2)
var iv = Data()
var key = Data()
for index in 0 ..< (ivLen / 2) {
iv.append(fragmentData[index * 2] * 16 + fragmentData[index * 2 + 1])
}
for index in (ivLen / 2) ..< (fragmentData.count / 2) {
key.append(fragmentData[index * 2] * 16 + fragmentData[index * 2 + 1])
}
let encodedData = try Data(contentsOf: localUrl)
var result = Data()
guard AESGSMEngine.shared.decrypt(iv: iv, key: key, encoded: encodedData, auth: nil, output: &result) else {
throw AppError.securityError
}
try result.write(to: localUrl)
}
var message = message
message.contentType = .attachment(
Attachment(