// // EncryptedRequest.swift // Befund // // Created by Irakli Abetschkhrischwili on 15.05.22. // Copyright © 2022 MVZ Dr. Stein und Kollegen. All rights reserved. import Foundation import CryptoKit extension Core.Models.Request { public class EncryptedRequest : Encodable, Decodable { /** * Request types */ public enum Types { case REQUEST_KEY_EXCHANGE case REQUEST_ENCRYPTED_REQUEST case REQUEST_SUBSCRIBE case REQUEST_GET_OPENED case REQUEST_CHECKSUM case REQUEST_VERIFICATOR_HASH case REQUEST_SUPPORT case REQUEST_GET_PIN } public var descriptor: String! public var encrypted_content: String? = nil public var hmac: String? = nil /** * Constructor for EncryptedRequest * * @param descriptor - descriptor of the content object * @param contentObject - content object that should be encrypted * @param requestType - type of request for JSON Encodeer * @param deriveKey - shared deriveKey that should be used in the encrption */ init(descriptor: String, contentObject: Any?, requestType: Types, key: CryptoKit.SymmetricKey) { var encrypted_content: String? = nil; do { if(contentObject != nil) { var data: Data? = nil let encoder = JSONEncoder() switch(requestType) { case .REQUEST_KEY_EXCHANGE: data = try encoder.encode(contentObject as! Core.Models.Request.KeyExchange) break case .REQUEST_SUBSCRIBE: data = try encoder.encode(contentObject as! Core.Models.Request.Subscribe) break case .REQUEST_ENCRYPTED_REQUEST: data = try encoder.encode(contentObject as! Core.Models.Request.EncryptedRequest) break; case .REQUEST_CHECKSUM: data = try encoder.encode(contentObject as! Core.Models.Request.CheckFileChecksum) break; case .REQUEST_GET_OPENED: data = try encoder.encode(contentObject as! Core.Models.Request.GetOpened) break; case .REQUEST_VERIFICATOR_HASH: data = try encoder.encode(contentObject as! Core.Models.Request.ChangeVerificatorHash) break; case .REQUEST_SUPPORT: data = try encoder.encode(contentObject as! Core.Models.Request.Support) break; case .REQUEST_GET_PIN: data = try encoder.encode(contentObject as! Core.Models.Request.GetPIN) break; } if(data != nil) { encrypted_content = String(data: data!, encoding: .utf8) } } self.Encrypt(descriptor: descriptor, encrypted_content: encrypted_content, key: key) } catch { Core.Log.Error(err: error, namespace: "Core.Models.EncryptedRequest", method: "init(String, Any?, Types, SymmetricKey)") } } /** * Encrypts the content of request with derive key * * @param descriptor - descriptor of object * @param encrypted_content - content that should be encrypted * @param deriveKey - derive key that should be used for the encryption */ public func Encrypt(descriptor: String, encrypted_content: String?, key: CryptoKit.SymmetricKey) { self.descriptor = Core.Security.AES.Encrypt(value: descriptor, deriveKey: key) if(encrypted_content != nil) { self.encrypted_content = Core.Security.AES.Encrypt(value: encrypted_content!, deriveKey: key) if(self.encrypted_content != nil) { self.hmac = Core.Security.SHA512.HMAC(message: self.encrypted_content!.data(using: .utf8)!, key: key) } } else { self.hmac = Core.Security.SHA512.HMAC(message: self.descriptor!.data(using: .utf8)!, key: key) } } } }