diff --git a/PersistentKey+CoreDataClass.swift b/PersistentKey+CoreDataClass.swift new file mode 100644 index 0000000000000000000000000000000000000000..c543f143fb76fa9fc297635b8506658fa6b70d8c --- /dev/null +++ b/PersistentKey+CoreDataClass.swift @@ -0,0 +1,15 @@ +// +// PersistentKey+CoreDataClass.swift +// +// +// Created by Oliver Wiese on 27.09.17. +// +// + +import Foundation +import CoreData + +@objc(PersistentKey) +public class PersistentKey: NSManagedObject { + +} diff --git a/PersistentKey+CoreDataProperties.swift b/PersistentKey+CoreDataProperties.swift new file mode 100644 index 0000000000000000000000000000000000000000..9c1b74c20ee024f5c319b3c4ab26e008657c4fc9 --- /dev/null +++ b/PersistentKey+CoreDataProperties.swift @@ -0,0 +1,46 @@ +// +// PersistentKey+CoreDataProperties.swift +// +// +// Created by Oliver Wiese on 27.09.17. +// +// + +import Foundation +import CoreData + + +extension PersistentKey { + + @nonobjc public class func fetchRequest() -> NSFetchRequest<PersistentKey> { + return NSFetchRequest<PersistentKey>(entityName: "PersistentKey") + } + + @NSManaged public var keyID: Int64 + @NSManaged public var verifiedDate: NSDate? + @NSManaged public var encryptionType: Int16 + @NSManaged public var lastSeen: NSDate? + @NSManaged public var lastSeenAutocrypt: NSDate? + @NSManaged public var preferEncryption: Int16 + @NSManaged public var discoveryDate: NSDate? + @NSManaged public var mailaddress: NSSet? + @NSManaged public var firstMail: PersistentMail? + +} + +// MARK: Generated accessors for mailaddress +extension PersistentKey { + + @objc(addMailaddressObject:) + @NSManaged public func addToMailaddress(_ value: Mail_Address) + + @objc(removeMailaddressObject:) + @NSManaged public func removeFromMailaddress(_ value: Mail_Address) + + @objc(addMailaddress:) + @NSManaged public func addToMailaddress(_ values: NSSet) + + @objc(removeMailaddress:) + @NSManaged public func removeFromMailaddress(_ values: NSSet) + +} diff --git a/PersistentMail +CoreDataClass.swift b/PersistentMail +CoreDataClass.swift index 1836f6d32594459705ffc950cfe08f3b6226728d..78d333ba993f0880736ae9b6ad3224e7172f7c4a 100644 --- a/PersistentMail +CoreDataClass.swift +++ b/PersistentMail +CoreDataClass.swift @@ -127,6 +127,8 @@ open class PersistentMail: NSManagedObject, Mail { return receivers } + /* + TODO: REMOVE //decrypt and/or check signature func decryptIfPossible() { let encType = EnzevalosEncryptionHandler.getEncryptionTypeForMail(self) @@ -169,6 +171,7 @@ open class PersistentMail: NSManagedObject, Mail { } return nil } + */ func getSubjectWithFlagsString() -> String { let subj: String diff --git a/enzevalos_iphone.xcodeproj/project.pbxproj b/enzevalos_iphone.xcodeproj/project.pbxproj index 23fd14af060b0e7fcd563bfe56b4a9d9985a6198..f350dde29b74dcdf997c834a99ac4872ab5f11bc 100644 --- a/enzevalos_iphone.xcodeproj/project.pbxproj +++ b/enzevalos_iphone.xcodeproj/project.pbxproj @@ -75,6 +75,8 @@ 475B00331F7B9565006CDD41 /* SwiftPGP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475B00301F7B9565006CDD41 /* SwiftPGP.swift */; }; 475B00341F7B9565006CDD41 /* Cryptography.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475B00311F7B9565006CDD41 /* Cryptography.swift */; }; 475B00351F7B9565006CDD41 /* CryptoObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475B00321F7B9565006CDD41 /* CryptoObject.swift */; }; + 475B00421F7BB6D6006CDD41 /* PersistentKey+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475B00401F7BB6D6006CDD41 /* PersistentKey+CoreDataClass.swift */; }; + 475B00431F7BB6D6006CDD41 /* PersistentKey+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475B00411F7BB6D6006CDD41 /* PersistentKey+CoreDataProperties.swift */; }; 475DF4791F0D54C9009D807F /* Folder+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475DF4771F0D54C9009D807F /* Folder+CoreDataClass.swift */; }; 475DF47A1F0D54C9009D807F /* Folder+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475DF4781F0D54C9009D807F /* Folder+CoreDataProperties.swift */; }; 476142081E07E52B00FD5E4F /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 476142071E07E52B00FD5E4F /* Theme.swift */; }; @@ -87,6 +89,7 @@ 479BBDDD1EFEA3CB00A2107C /* dave_enezvalos_public.asc in Resources */ = {isa = PBXBuildFile; fileRef = 479BBDDC1EFEA3CB00A2107C /* dave_enezvalos_public.asc */; }; 479BBDE01EFEA4D800A2107C /* bob_enzvalos_private.asc in Resources */ = {isa = PBXBuildFile; fileRef = 479BBDDE1EFEA4D800A2107C /* bob_enzvalos_private.asc */; }; 479BBDE11EFEA4D800A2107C /* alice_enzvalos_private.asc in Resources */ = {isa = PBXBuildFile; fileRef = 479BBDDF1EFEA4D800A2107C /* alice_enzvalos_private.asc */; }; + 47D1302B1F7CEE6D007B14DF /* DebugSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47D1302A1F7CEE6D007B14DF /* DebugSettings.swift */; }; 9935BC866A86C4A4B9819F35 /* Pods_enzevalos_iphone.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4AE42F42E91A1BFBF1D5BF6A /* Pods_enzevalos_iphone.framework */; }; 9C1FA3A01B089C653802A88C /* Pods_enzevalos_iphoneUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 48FB10FF406523D174F4202A /* Pods_enzevalos_iphoneUITests.framework */; }; A102AA8A1EDDB4F40024B457 /* videoOnboarding2.m4v in Resources */ = {isa = PBXBuildFile; fileRef = A102AA891EDDB4E80024B457 /* videoOnboarding2.m4v */; }; @@ -200,6 +203,8 @@ 475B00301F7B9565006CDD41 /* SwiftPGP.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftPGP.swift; sourceTree = "<group>"; }; 475B00311F7B9565006CDD41 /* Cryptography.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cryptography.swift; sourceTree = "<group>"; }; 475B00321F7B9565006CDD41 /* CryptoObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CryptoObject.swift; sourceTree = "<group>"; }; + 475B00401F7BB6D6006CDD41 /* PersistentKey+CoreDataClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PersistentKey+CoreDataClass.swift"; sourceTree = "<group>"; }; + 475B00411F7BB6D6006CDD41 /* PersistentKey+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PersistentKey+CoreDataProperties.swift"; sourceTree = "<group>"; }; 475BFF931F7B953B006CDD41 /* PGPCryptoHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PGPCryptoHash.h; sourceTree = "<group>"; }; 475BFF941F7B953B006CDD41 /* PGPCryptoHash.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PGPCryptoHash.m; sourceTree = "<group>"; }; 475BFF951F7B953B006CDD41 /* PGPCryptoUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PGPCryptoUtils.h; sourceTree = "<group>"; }; @@ -320,6 +325,7 @@ 479BBDDE1EFEA4D800A2107C /* bob_enzvalos_private.asc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = bob_enzvalos_private.asc; path = keys/bob_enzvalos_private.asc; sourceTree = "<group>"; }; 479BBDDF1EFEA4D800A2107C /* alice_enzvalos_private.asc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = alice_enzvalos_private.asc; path = keys/alice_enzvalos_private.asc; sourceTree = "<group>"; }; 47B2318A1F0D458100961B28 /* enzevalos_iphone 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "enzevalos_iphone 2.xcdatamodel"; sourceTree = "<group>"; }; + 47D1302A1F7CEE6D007B14DF /* DebugSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DebugSettings.swift; sourceTree = "<group>"; }; 48FB10FF406523D174F4202A /* Pods_enzevalos_iphoneUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_enzevalos_iphoneUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4AE42F42E91A1BFBF1D5BF6A /* Pods_enzevalos_iphone.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_enzevalos_iphone.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 796D16D79BED5D60B580E602 /* Pods-enzevalos_iphoneUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-enzevalos_iphoneUITests.release.xcconfig"; path = "../workspace/Pods/Target Support Files/Pods-enzevalos_iphoneUITests/Pods-enzevalos_iphoneUITests.release.xcconfig"; sourceTree = "<group>"; }; @@ -607,6 +613,8 @@ 47B91AC01EC0C1CF000AE3EE /* coredata */ = { isa = PBXGroup; children = ( + 475B00401F7BB6D6006CDD41 /* PersistentKey+CoreDataClass.swift */, + 475B00411F7BB6D6006CDD41 /* PersistentKey+CoreDataProperties.swift */, 472F39781E1D0B0B009260FB /* PersistentMail +CoreDataProperties.swift */, 475DF4771F0D54C9009D807F /* Folder+CoreDataClass.swift */, 475DF4781F0D54C9009D807F /* Folder+CoreDataProperties.swift */, @@ -672,6 +680,7 @@ 475B00301F7B9565006CDD41 /* SwiftPGP.swift */, 475B00311F7B9565006CDD41 /* Cryptography.swift */, 475B00321F7B9565006CDD41 /* CryptoObject.swift */, + 47D1302A1F7CEE6D007B14DF /* DebugSettings.swift */, ); name = Encryption; sourceTree = "<group>"; @@ -1198,6 +1207,7 @@ 475B002F1F7B953B006CDD41 /* NSMutableData+PGPUtils.m in Sources */, 475B00021F7B953B006CDD41 /* PGPCryptoUtils.m in Sources */, A1EB05821D95685B008659C1 /* CollectionDataDelegate.swift in Sources */, + 47D1302B1F7CEE6D007B14DF /* DebugSettings.swift in Sources */, A17C04841DC6504E00F66EDB /* LogHandler.swift in Sources */, A1EB05801D956851008659C1 /* SendViewController.swift in Sources */, 475B001B1F7B953B006CDD41 /* PGPUserIDPacket.m in Sources */, @@ -1235,6 +1245,7 @@ 475DF47A1F0D54C9009D807F /* Folder+CoreDataProperties.swift in Sources */, 475B00101F7B953B006CDD41 /* PGPSecretKeyPacket.m in Sources */, 472F392C1E1277D2009260FB /* PersistentMail +CoreDataClass.swift in Sources */, + 475B00431F7BB6D6006CDD41 /* PersistentKey+CoreDataProperties.swift in Sources */, F119D2901E364B59001D732A /* AnimatedSendIcon.swift in Sources */, 475B00231F7B953B006CDD41 /* PGPKeyID.m in Sources */, 475B00181F7B953B006CDD41 /* PGPTrustPacket.m in Sources */, @@ -1251,6 +1262,7 @@ 475B00271F7B953B006CDD41 /* PGPPartialSubKey.m in Sources */, F18B44621E73286C0080C041 /* ReadVENDelegate.swift in Sources */, 475B000F1F7B953B006CDD41 /* PGPPublicSubKeyPacket.m in Sources */, + 475B00421F7BB6D6006CDD41 /* PersistentKey+CoreDataClass.swift in Sources */, 475B00051F7B953B006CDD41 /* PGPRSA.m in Sources */, A1D5076F1E80257A00B68B38 /* KeyViewController.swift in Sources */, 472F39901E252470009260FB /* CNMailAddressesExtension.swift in Sources */, diff --git a/enzevalos_iphone/AddressHandler.swift b/enzevalos_iphone/AddressHandler.swift index 749d64e3a713ee71c21a227842041dab17af7447..67dfed914209b41ad2a67ef978cf21949e0f090a 100644 --- a/enzevalos_iphone/AddressHandler.swift +++ b/enzevalos_iphone/AddressHandler.swift @@ -142,12 +142,15 @@ class AddressHandler { return list } + /* + REMOVE??? static func proveAddress(_ s: NSString) -> Bool { if addresses.contains((s as String).lowercased()) { return true } return EnzevalosEncryptionHandler.hasKey(DataHandler.handler.getContactByAddress((s as String).lowercased())) } + */ static func inContacts(_ name: String) -> Bool { AppDelegate.getAppDelegate().requestForAccess({ access in }) diff --git a/enzevalos_iphone/CNMailAddressesExtension.swift b/enzevalos_iphone/CNMailAddressesExtension.swift index 3f28bb2a9e4b44771ea8044648beb1522402122d..45786a16b33de38aa497845e5fb7227d531408d1 100644 --- a/enzevalos_iphone/CNMailAddressesExtension.swift +++ b/enzevalos_iphone/CNMailAddressesExtension.swift @@ -32,7 +32,7 @@ open class CNMailAddressExtension: MailAddress{ } - open var keyID: String?{ + open var Key: PersistentKey?{ get{ return nil } diff --git a/enzevalos_iphone/ContactViewController.swift b/enzevalos_iphone/ContactViewController.swift index 80c54aa235b68b3bc0e6b7b8b8ae32cc02121719..e90cc3fd3e3120cc5d7340ae4fe3c266b2951942 100644 --- a/enzevalos_iphone/ContactViewController.swift +++ b/enzevalos_iphone/ContactViewController.swift @@ -35,7 +35,13 @@ class ContactViewController: UIViewController { self.navigationController?.navigationBar.barTintColor = ThemeManager.defaultColor if let con = keyRecord { - hasKey = EnzevalosEncryptionHandler.hasKey(con.ezContact) + hasKey = false + if let adrs = con.ezContact.addresses{ + for adr in adrs{ + let a = adr as! MailAddress + hasKey = hasKey || a.hasKey + } + } let myAddress = UserManager.loadUserValue(Attribute.userAddr) as! String if con.addresses.contains(where: { $0.mailAddress.lowercased() == myAddress @@ -155,7 +161,7 @@ class ContactViewController: UIViewController { performSegue(withIdentifier: "newMail", sender: mail) } else if sender.titleLabel?.text == NSLocalizedString("verifyNow", comment: "Verify now") && keyRecord!.key != nil { AppUtility.lockOrientation(.portrait, andRotateTo: .portrait) - performSegue(withIdentifier: "verifyQRCode", sender: EnzevalosEncryptionHandler.getEncryption(.PGP)?.getKey(keyRecord!.key!)?.fingerprint) + performSegue(withIdentifier: "verifyQRCode", sender: keyRecord?.fingerprint) } } @@ -191,15 +197,14 @@ class ContactViewController: UIViewController { destinationViewController.record = keyRecord } else if segue.identifier == "verifyQRCode" { if let DestinationViewController = segue.destination as? QRScannerView { - DestinationViewController.fingerprint = EnzevalosEncryptionHandler.getEncryption(.PGP)!.getKey(keyRecord!.key!)!.fingerprint + DestinationViewController.fingerprint = keyRecord?.fingerprint DestinationViewController.callback = verifySuccessfull } } } func verifySuccessfull() { - var keyWrapper = EnzevalosEncryptionHandler.getEncryption(.PGP)!.getKey(keyRecord!.key!)! - keyWrapper.verified = true + keyRecord?.verify() tableView.reloadData() } } @@ -236,7 +241,7 @@ extension ContactViewController: UITableViewDataSource { } else if indexPath.row == 1 { if isUser && keyRecord!.hasKey { let qrCodeCell = tableView.dequeueReusableCell(withIdentifier: "QRCodeCell", for: indexPath) as! QRCodeCell - let qrCode = QRCode.generate(input: "OPENPGP4FPR:\(EnzevalosEncryptionHandler.getEncryption(.PGP)!.getKey(keyRecord!.key!)!.fingerprint)") + let qrCode = QRCode.generate(input: "OPENPGP4FPR:\(keyRecord?.fingerprint)") let scaleX = qrCodeCell.qrCode.frame.size.width / qrCode.extent.size.width let scaleY = qrCodeCell.qrCode.frame.size.height / qrCode.extent.size.height @@ -286,11 +291,11 @@ extension ContactViewController: UITableViewDataSource { case 3 where !((keyRecord?.hasKey) ?? false): let cell = tableView.dequeueReusableCell(withIdentifier: "RecordCell", for: indexPath) as! RecordCell if let r = otherRecords { - if let key = r[indexPath.row].key, let time = EnzevalosEncryptionHandler.getEncryption(.PGP)?.getKey(key)?.discoveryTime { + if let key = r[indexPath.row].key, let pk = DataHandler.handler.findKey(keyID: key), let time = pk.discoveryDate { let dateFormatter = DateFormatter() dateFormatter.locale = Locale.current dateFormatter.dateStyle = .medium - cell.dateLabel.text = dateFormatter.string(from: time) + cell.dateLabel.text = dateFormatter.string(from: time as Date) cell.iconImage.image = IconsStyleKit.imageOfLetter } else { cell.dateLabel.text = "" @@ -306,11 +311,11 @@ extension ContactViewController: UITableViewDataSource { case 4 where (keyRecord?.hasKey) ?? false: let cell = tableView.dequeueReusableCell(withIdentifier: "RecordCell", for: indexPath) as! RecordCell if let r = otherRecords { - if let key = r[indexPath.row].key, let time = EnzevalosEncryptionHandler.getEncryption(.PGP)?.getKey(key)?.discoveryTime { + if let key = r[indexPath.row].key, let pk = DataHandler.handler.findKey(keyID: key), let time = pk.discoveryDate { let dateFormatter = DateFormatter() dateFormatter.locale = Locale.current dateFormatter.dateStyle = .medium - cell.dateLabel.text = dateFormatter.string(from: time) + cell.dateLabel.text = dateFormatter.string(from: time as Date) cell.iconImage.image = IconsStyleKit.imageOfLetter } else { cell.dateLabel.text = "" diff --git a/enzevalos_iphone/CryptoObject.swift b/enzevalos_iphone/CryptoObject.swift index 5b6f6c4cbf5c6ee2329d7333be91b2017fb347dc..40ff412ed273b4c93a79565a564503562aa17e22 100644 --- a/enzevalos_iphone/CryptoObject.swift +++ b/enzevalos_iphone/CryptoObject.swift @@ -28,15 +28,17 @@ enum CryptoScheme { public class CryptoObject{ let chiphertext: Data? let plaintext: String? + let decryptedData: Data? let signatureState: SignatureState let encryptionState: EncryptionState let signKey: String? let encType: CryptoScheme - init(chiphertext: Data?, plaintext: String?, sigState: SignatureState, encState: EncryptionState, signKey: String?, encType: CryptoScheme){ + init(chiphertext: Data?, plaintext: String?, decryptedData: Data?, sigState: SignatureState, encState: EncryptionState, signKey: String?, encType: CryptoScheme){ self.chiphertext = chiphertext self.plaintext = plaintext + self.decryptedData = decryptedData self.signatureState = sigState self.encryptionState = encState self.signKey = signKey diff --git a/enzevalos_iphone/Cryptography.swift b/enzevalos_iphone/Cryptography.swift index d8d10bce51d6699ddf9d4acf0f68b1874183fe26..6d242b65d05860f4f4adea747f624b59d846c28b 100644 --- a/enzevalos_iphone/Cryptography.swift +++ b/enzevalos_iphone/Cryptography.swift @@ -13,10 +13,11 @@ public protocol Encryption{ // Key handling func generateKey(adr: String) -> String func importKeys(key: String, isSecretKey: Bool, autocrypt: Bool) -> [String] + func importKeysFromFile(file: String) -> [String] func exportKey(id: String, isSecretkey: Bool, autocrypt: Bool) -> String? // operations on keys func encrypt(plaintext: String, ids: [String], myId: String) -> CryptoObject - func decrypt(data: Data, decryptionId: String, verifyIds: [String]) -> CryptoObject + func decrypt(data: Data, decryptionId: String?, verifyIds: [String]) -> CryptoObject } diff --git a/enzevalos_iphone/DataHandler.swift b/enzevalos_iphone/DataHandler.swift index 71a88daabd6bd9b3b8b641c4651d1dc542bf393b..1f4f9b2a7eeae738868c543168c75359f3a52506 100644 --- a/enzevalos_iphone/DataHandler.swift +++ b/enzevalos_iphone/DataHandler.swift @@ -71,6 +71,8 @@ class DataHandler { } + + func callForFolders(done: @escaping ((_ error: Bool) -> ())){ // Maybe call back? Look for new Folder? AppDelegate.getAppDelegate().mailHandler.allFolders{ (err, array) -> Void in guard err == nil else { @@ -266,9 +268,78 @@ class DataHandler { removeAll(entity: "Mail_Address") removeAll(entity: "State") removeAll(entity: "Folder") + removeAll(entity: "SecretKey") + removeAll(entity: "PersistentKey") + } // Save, load, search + + func newSecretKey(keyID: String) -> SecretKey{ + let sk: SecretKey + if let key = findSecretKey(keyID: keyID){ + sk = key + } + else { + sk = NSEntityDescription.insertNewObject(forEntityName: "SecretKey", into: managedObjectContext) as! SecretKey + sk.keyID = keyID + sk.obsolete = false + } + return sk + } + + func newPublicKey(keyID: String, cryptoType: CryptoScheme, adr: String, autocrypt: Bool, firstMail: PersistentMail? = nil) -> PersistentKey{ + let date = Date.init() as NSDate + let adr = getMailAddress(adr, temporary: false) as! Mail_Address + var pk: PersistentKey + if let search = findKey(keyID: keyID){ + search.lastSeen = date + if autocrypt{ + search.lastSeenAutocrypt = date + } + search.addToMailaddress(adr) + pk = search + } + else{ + pk = NSEntityDescription.insertNewObject(forEntityName: "PersistentKey", into: managedObjectContext) as! PersistentKey + pk.addToMailaddress(adr) + pk.keyID = keyID + pk.encryptionType = Int16(cryptoType.hashValue) + pk.lastSeen = date + pk.discoveryDate = date + pk.firstMail = firstMail + if autocrypt{ + pk.lastSeenAutocrypt = date + } + } + save() + return pk + } + + func findSecretKeys() ->[SecretKey]{ + if let result = findAll("SecretKey"){ + return result as! [SecretKey] + } + return [SecretKey]() + } + + func findSecretKey(keyID: String)-> SecretKey?{ + if let result = find("SecretKey", type: "keyID", search: keyID){ + for r in result{ + return r as? SecretKey + } + } + return nil + } + + func findKey(keyID: String) -> PersistentKey?{ + if let result = find("PersistentKey", type: "keyID", search: keyID){ + for r in result{ + return r as? PersistentKey + } + } + return nil + } private func find(_ entityName: String, type: String, search: String) -> [AnyObject]? { let fReq: NSFetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName) @@ -338,7 +409,6 @@ class DataHandler { else { let mail_address = NSEntityDescription.insertNewObject(forEntityName: "Mail_Address", into: managedObjectContext) as! Mail_Address mail_address.address = address - mail_address.prefer_encryption = EncState.NOAUTOCRYPT return mail_address } } @@ -346,6 +416,15 @@ class DataHandler { return search![0] as! Mail_Address } } + + func findMailAddress(adr: String)-> Mail_Address?{ + if let search = find("Mail_Address", type: "address", search: adr){ + if search.count > 0{ + return search[0] as! Mail_Address + } + } + return nil + } func getMailAddressesByString(_ addresses: [String], temporary: Bool) -> [MailAddress] { var mailaddresses = [MailAddress]() @@ -412,8 +491,8 @@ class DataHandler { func getContact(_ name: String, address: String, key: String, prefer_enc: Bool) -> EnzevalosContact { let contact = getContactByAddress(address) contact.displayname = name - contact.getAddress(address)?.keyID = key - _ = contact.getAddress(address)?.prefer_encryption //TODO IOptimize: look for Mail_Address and than for contact! + contact.getAddress(address)?.key?.adding(key) + //TODO IOptimize: look for Mail_Address and than for contact! return contact } @@ -442,6 +521,7 @@ class DataHandler { let adr: Mail_Address let contact = getContactByMCOAddress(sender) adr = contact.getAddressByMCOAddress(sender)! + /* TODO: Handle AUtocrypt again! if adr.lastSeen > fromMail.date{ adr.lastSeen = fromMail.date } @@ -459,6 +539,7 @@ class DataHandler { else if adr.lastSeen < adr.lastSeenAutocrypt && adr.prefer_encryption != EncState.NOAUTOCRYPT{ adr.prefer_encryption = EncState.RESET } + */ fromMail.from = adr } @@ -474,7 +555,7 @@ class DataHandler { // -------- End handle to, cc, from addresses -------- - func createMail(_ uid: UInt64, sender: MCOAddress?, receivers: [MCOAddress], cc: [MCOAddress], time: Date, received: Bool, subject: String, body: String?, flags: MCOMessageFlag, record: KeyRecord?, autocrypt: AutocryptContact?, decryptedData: DecryptedData?, folderPath: String) { + func createMail(_ uid: UInt64, sender: MCOAddress?, receivers: [MCOAddress], cc: [MCOAddress], time: Date, received: Bool, subject: String, body: String?, flags: MCOMessageFlag, record: KeyRecord?, autocrypt: AutocryptContact?, decryptedData: CryptoObject?, folderPath: String) { let finding = findNum("PersistentMail", type: "uid", search: uid) let mail: PersistentMail @@ -511,7 +592,7 @@ class DataHandler { if let decData = decryptedData{ let encState: EncryptionState = decData.encryptionState let signState: SignatureState = decData.signatureState - mail.keyID = decData.keyID + mail.keyID = decData.signKey switch encState { case EncryptionState.NoEncryption: @@ -545,7 +626,7 @@ class DataHandler { else{ // Maybe PGPInline? // TODO: Refactoring! - mail.decryptIfPossible() + //mail.decryptIfPossible() } } else { @@ -607,7 +688,12 @@ class DataHandler { - + func hasKey(adr: String) -> Bool{ + if let madr = findMailAddress(adr: adr){ + return madr.hasKey + } + return false + } func folderRecords(folderPath: String) -> [KeyRecord]{ let folder = findFolder(with: folderPath) as Folder diff --git a/enzevalos_iphone/KeyRecord.swift b/enzevalos_iphone/KeyRecord.swift index 88e2abbf952196cf46c60ea967506d64ac66fda1..3beab13b0367cd8eabe3dfa0f758d4fa12a154ca 100644 --- a/enzevalos_iphone/KeyRecord.swift +++ b/enzevalos_iphone/KeyRecord.swift @@ -20,8 +20,71 @@ open class KeyRecord: Record { let key: String? + let cryptoscheme = CryptoScheme.PGP + let folder: Folder + var pgpKey: PGPKey?{ + get{ + if let k = key{ + let pgp = SwiftPGP() + return pgp.loadKey(id: k) + } + return nil + } + } + + var storedKey: PersistentKey?{ + get{ + if let k = keyId{ + return DataHandler.handler.findKey(keyID: k) + } + return nil + } + + } + + + + public var isVerified: Bool{ + get{ + if let k = key{ + if let pk = DataHandler.handler.findKey(keyID: k){ + return pk.isVerified() + } + } + return false + + } + } + + func verify(){ + if let k = key{ + if let pk = DataHandler.handler.findKey(keyID: k){ + pk.verify() + } + } + } + + var fingerprint: String?{ + get{ + if let k = pgpKey{ + return k.keyID.longKeyString + } + return nil + } + } + + var keyId: String?{ + get{ + if let k = pgpKey{ + return k.keyID.shortKeyString + } + return nil + } + + } + open var mails: [PersistentMail] { get{ return mailsInFolder(folder: folder) @@ -34,6 +97,17 @@ open class KeyRecord: Record { } return [] } + + var addressNames:[String]{ + get{ + let adrs = addresses + var names = [String]() + for adr in adrs{ + names.append(adr.mailAddress) + } + return names + } + } open var name: String { return ezContact.name @@ -45,15 +119,6 @@ open class KeyRecord: Record { open var isSecure: Bool = false - open var isVerified: Bool { - if let key = self.key { - if let keywrapper = EnzevalosEncryptionHandler.getEncryption(EncryptionType.PGP)?.getKey(key) { - return keywrapper.verified - } - - } - return false - } open var ezContact: EnzevalosContact diff --git a/enzevalos_iphone/KeyViewController.swift b/enzevalos_iphone/KeyViewController.swift index 80bc5962489125cc619ff92be629268d681bd3c0..8b8961d97e0776f6f2474c5e9d275e8b1d67211a 100644 --- a/enzevalos_iphone/KeyViewController.swift +++ b/enzevalos_iphone/KeyViewController.swift @@ -15,19 +15,14 @@ class KeyViewController: UIViewController { var record: KeyRecord? override func viewDidLoad() { super.viewDidLoad() - if let rec = record, rec.key != nil { - //TODO use EncryptionType from KeyRecord - keyWrapper = EnzevalosEncryptionHandler.getEncryption(.PGP)?.getKey(rec.key!) - } tableView.dataSource = self tableView.delegate = self } @IBAction func deleteKey(_ sender: AnyObject) { - if let key = keyWrapper { - EnzevalosEncryptionHandler.getEncryption(key.type)?.removeKey(key) - } + //TODO: REMOVE KEY! + } } @@ -42,8 +37,8 @@ extension KeyViewController: UITableViewDataSource { return returnValue } if toSectionType(section) == .addresses { - if let key = keyWrapper, key.mailAddresses != nil { - return key.mailAddressesInKey!.count + if let key = record?.storedKey, key.mailaddress != nil{ + return key.mailaddress!.count } return 0 } @@ -55,20 +50,20 @@ extension KeyViewController: UITableViewDataSource { if toRowType(indexPath) == .keyID { let cell = tableView.dequeueReusableCell(withIdentifier: "KeyIDCell")! cell.textLabel?.text = NSLocalizedString("KeyID", comment: "Identifier of the key") - cell.detailTextLabel?.text = keyWrapper?.keyID + cell.detailTextLabel?.text = record?.keyId return cell } else if toRowType(indexPath) == .fingerprint { let cell = tableView.dequeueReusableCell(withIdentifier: "FingerprintCell")! cell.detailTextLabel?.numberOfLines = 0 - cell.detailTextLabel?.text = keyWrapper?.fingerprint + cell.detailTextLabel?.text = record?.fingerprint cell.textLabel?.text = NSLocalizedString("Fingerprint", comment: "Fingerprint of key") cell.frame = CGRect(x: cell.frame.minX, y: cell.frame.minY, width: cell.frame.width, height: cell.frame.height+20.5) return cell } else if toRowType(indexPath) == .encryptionType { let cell = tableView.dequeueReusableCell(withIdentifier: "EncryptionTypeCell")! - cell.detailTextLabel?.text = keyWrapper?.type.rawValue + cell.detailTextLabel?.text = "\(record?.cryptoscheme)" cell.textLabel?.text = NSLocalizedString("EncryptionType", comment: "Type of Encryption") return cell } @@ -79,9 +74,10 @@ extension KeyViewController: UITableViewDataSource { formatter.locale = Locale.current formatter.dateStyle = .medium formatter.timeStyle = .medium - if let keyWrapper = keyWrapper { - cell.detailTextLabel?.text = formatter.string(from: keyWrapper.discoveryTime as Date) + if let discoveryDate = record?.storedKey?.discoveryDate{ + cell.detailTextLabel?.text = formatter.string(from: discoveryDate as Date) } + return cell } else if toRowType(indexPath) == .discoveryMail { @@ -91,27 +87,27 @@ extension KeyViewController: UITableViewDataSource { } else if toRowType(indexPath) == .verified { let cell = tableView.dequeueReusableCell(withIdentifier: "VerifiedCell")! - cell.textLabel?.text = NSLocalizedString("KeyIsVerified", comment: "The Key is verified. The time when the Key was verified") + "\(String(describing: keyWrapper?.verifyTime))" + cell.textLabel?.text = NSLocalizedString("KeyIsVerified", comment: "The Key is verified. The time when the Key was verified") + "\(String(describing: record?.storedKey?.verifiedDate))" return cell } else if toRowType(indexPath) == .revoked { let cell = tableView.dequeueReusableCell(withIdentifier: "RevokedCell")! - cell.textLabel?.text = NSLocalizedString("KeyIsRevoked", comment: "The Key is revoked. The time when the Key was revoked") + "\(String(describing: keyWrapper?.revokeTime))" + cell.textLabel?.text = NSLocalizedString("KeyIsRevoked", comment: "The Key is revoked. The time when the Key was revoked") + "NOt SUPPORTED" //TODO Revoke keys return cell } } else if toSectionType(indexPath.section) == .addresses { let cell = tableView.dequeueReusableCell(withIdentifier: "MailAddressCell")! - if let addr = keyWrapper?.mailAddressesInKey?[indexPath.row] { - for ourAddr in (keyWrapper?.mailAddresses)! { + if let addr = record?.addressNames[indexPath.row] { //TODO: Or of key??? + for ourAddr in (record?.addressNames)! { if addr.localizedCaseInsensitiveContains(ourAddr) { cell.accessoryType = UITableViewCellAccessoryType.checkmark break } } } - cell.textLabel?.text = keyWrapper?.mailAddressesInKey?[indexPath.row] + cell.textLabel?.text = record?.addressNames[indexPath.row] return cell } @@ -128,9 +124,9 @@ extension KeyViewController: UITableViewDataSource { } func numberOfSections(in tableView: UITableView) -> Int { - if let key = keyWrapper { + if let key = record?.storedKey { var sections = 1 - if let addrs = key.mailAddresses, addrs != [] { + if let addrs = key.mailaddress, addrs != nil{ sections += 1 } return sections @@ -151,7 +147,7 @@ extension KeyViewController: UITableViewDataSource { func toSectionType(_ sectionNumber: Int) -> KeyViewSectionType { var returnValue: KeyViewSectionType = .noKey - if keyWrapper != nil { + if record?.storedKey != nil { returnValue = .keyDetails//.KeyID //addresses if sectionNumber != 0 { @@ -164,7 +160,7 @@ extension KeyViewController: UITableViewDataSource { func toRowType(_ index: IndexPath) -> KeyViewRowType { var returnValue: KeyViewRowType = .noKey var row = index.row - if let key = keyWrapper, toSectionType(index.section) == .keyDetails { + if let key = record?.storedKey, toSectionType(index.section) == .keyDetails { returnValue = .keyID //Fingerprint if row != 0 { @@ -182,17 +178,17 @@ extension KeyViewController: UITableViewDataSource { row -= 1 } //DiscoveryMail - if row != 0 && key.discoveryMailUID != nil { + if row != 0 && key.firstMail != nil { returnValue = KeyViewRowType(rawValue: returnValue.rawValue + 1)! row -= 1 } //verified - if row != 0 && key.verified { + if row != 0 && key.isVerified() { returnValue = KeyViewRowType(rawValue: returnValue.rawValue + 1)! row -= 1 } - //revoked - if row != 0 && key.revoked { + //TODO revoked + if row != 0 && key.isExpired() { returnValue = KeyViewRowType(rawValue: returnValue.rawValue + 1)! row -= 1 } diff --git a/enzevalos_iphone/MailAddress.swift b/enzevalos_iphone/MailAddress.swift index fd1b0a9161a154c76b3d59c362c6ae88cf5efd07..4e8347829393e9888e55926314889a00d9e8c438 100644 --- a/enzevalos_iphone/MailAddress.swift +++ b/enzevalos_iphone/MailAddress.swift @@ -67,10 +67,10 @@ public enum EncState { public protocol MailAddress { var mailAddress:String{get} var label: CNLabeledValue<NSString>{get} //FIXME: ist der NSString hier wirklich richtig? (http://stackoverflow.com/questions/39648830/how-to-add-new-email-to-cnmutablecontact-in-swift-3) - var prefEnc: EncState{get set} + // var prefEnc: EncState{get set} var hasKey: Bool{get} - var keyID: String?{get} + var Key: PersistentKey?{get} var contact: EnzevalosContact?{get} } diff --git a/enzevalos_iphone/MailHandler.swift b/enzevalos_iphone/MailHandler.swift index 3a2f5507b201bf65cda8805ab1019e1b2b916f90..d7b11da471a6668d0af012972035846bdd12d5c5 100644 --- a/enzevalos_iphone/MailHandler.swift +++ b/enzevalos_iphone/MailHandler.swift @@ -46,13 +46,13 @@ let KEY = "key" class AutocryptContact { var addr: String = "" - var type: EncryptionType = .PGP + var type: CryptoScheme = .PGP var prefer_encryption: EncState = EncState.NOAUTOCRYPT var key: String = "" init(addr: String, type: String, prefer_encryption: String, key: String) { self.addr = addr - self.type = EncryptionType.typeFromAutocrypt(type) + // TODO: Other crypto schemes? _ = setPrefer_encryption(prefer_encryption) self.key = key } @@ -105,14 +105,14 @@ class AutocryptContact { } func validateContact() -> Bool { - if addr != "" && type != .unknown && key != "" { + if addr != "" && type != .UNKNOWN && key != "" { return true } return false } func setPrefer_encryption(_ input: String) -> Bool { - var pref = input.lowercased() + let pref = input.lowercased() if pref == "yes" || pref == "mutal" { self.prefer_encryption = EncState.MUTAL return true @@ -149,13 +149,13 @@ class MailHandler { var IMAPIdleSession: MCOIMAPSession? var IMAPIdleSupported: Bool? - //TODO: signatur hinzufügen func addAutocryptHeader(_ builder: MCOMessageBuilder) { let adr = (UserManager.loadUserValue(Attribute.userAddr) as! String).lowercased() - let pgpenc = EnzevalosEncryptionHandler.getEncryption(EncryptionType.PGP) as! PGPEncryption - if let header = pgpenc.autocryptHeader(adr) { - builder.header.setExtraHeaderValue(header, forName: AUTOCRYPTHEADER) - } + // TODO: Autocryptheader! + // let pgpenc = EnzevalosEncryptionHandler.getEncryption(EncryptionType.PGP) as! PGPEncryption + // if let header = pgpenc.autocryptHeader(adr) { + // builder.header.setExtraHeaderValue(header, forName: AUTOCRYPTHEADER) + // } } fileprivate func createHeader(_ builder: MCOMessageBuilder, toEntrys: [String], ccEntrys: [String], bccEntrys: [String], subject: String) { @@ -189,6 +189,37 @@ class MailHandler { addAutocryptHeader(builder) } + + private func orderReceiver(receiver: [String]) -> [CryptoScheme: [MCOAddress]]{ + var orderedReceiver = [CryptoScheme: [MCOAddress]]() + orderedReceiver[CryptoScheme.PGP] = [MCOAddress]() + orderedReceiver[CryptoScheme.UNKNOWN] = [MCOAddress]() + + for r in receiver{ + let mco = MCOAddress(displayName: r, mailbox: r) + if let adr = DataHandler.handler.findMailAddress(adr: r){ + if adr.hasKey{ //TODO: CONSIDER AUTOCRYPT! + orderedReceiver[CryptoScheme.PGP]?.append(mco!) + } + else{ + orderedReceiver[CryptoScheme.UNKNOWN]?.append(mco!) + } + } + } + return orderedReceiver + } + + private func addKeys(adrs: [MCOAddress]) -> [String]{ + var ids = [String]() + for a in adrs{ + if let adr = DataHandler.handler.findMailAddress(adr: a.mailbox), let key = adr.Key?.keyID { + ids.append(key) + } + } + + return ids + } + //return if send successfully func send(_ toEntrys: [String], ccEntrys: [String], bccEntrys: [String], subject: String, message: String, sendEncryptedIfPossible: Bool = true, callback: @escaping (Error?) -> Void) { @@ -207,42 +238,35 @@ class MailHandler { allRec.append(contentsOf: ccEntrys) // What about BCC?? - //TODO add support for different Encryptions here - //edit sortMailaddressesByEncryptionMCOAddress and sortMailaddressesByEncryption because a mailaddress can be found in multiple Encryptions - let ordered = EnzevalosEncryptionHandler.sortMailaddressesByEncryptionMCOAddress(allRec, sendEncryptedIfPossible: sendEncryptedIfPossible) + + let ordered = orderReceiver(receiver: allRec) let userID = MCOAddress(displayName: useraddr, mailbox: useraddr) var encryption: Encryption var sendData: Data - let orderedString = EnzevalosEncryptionHandler.sortMailaddressesByEncryption(allRec) + //let orderedString = EnzevalosEncryptionHandler.sortMailaddressesByEncryption(allRec) var sendOperation: MCOSMTPSendOperation - //TODO: Consider pref enc = false - - if let encPGP = ordered[EncryptionType.PGP] { - encryption = EnzevalosEncryptionHandler.getEncryption(EncryptionType.PGP)! - let keyID = encryption.getActualKeyID(allRec[0]) - var encFor = orderedString[EncryptionType.PGP]! - encFor.append(useraddr) - print("Keyid : \(String(describing: keyID)) of \(allRec[0])") - if let encData = encryption.signAndEncrypt("\n" + message, mailaddresses: encFor) { //ohne "\n" wird der erste Teil der Nachricht, bis sich ein einzelnen \n in einer Zeile befindet nicht in die Nachricht getan + if let encPGP = ordered[CryptoScheme.PGP] { + var keyIDs = addKeys(adrs: encPGP) + //added own public key here, so we can decrypt our own message to read it in sent-folder + let sks = DataHandler.handler.findSecretKeys() + if sks.count > 0 { + keyIDs.append(sks[0].keyID!) + } + + let pgp = SwiftPGP() + print("Keyid : \(String(describing: keyIDs)) of \(allRec[0])") + let cryptoObject = pgp.encrypt(plaintext: "\n" + message, ids: keyIDs, myId:sks[0].keyID!) + if let encData = cryptoObject.chiphertext{ sendData = encData - //added own public key here, so we can decrypt our own message to read it in sent-folder - - - // builder.textBody = String(data: encData, encoding: String.Encoding.utf8) - // sendData = builder.data() - //sendOperation = session.sendOperation(with: sendData, from: userID, recipients: encPGP) builder.textBody = "Dies ist verschlüsselt!" - //builder.addAttachment(MCOAttachment.init(text: "Dies ist verschlüsselt!")) - //builder.addAttachment(MCOAttachment.init(rfc822Message: encData)) - //builder.addAttachment(MCOAttachment.init(rfc822Message: MCOMessageBuilder().openPGPEncryptedMessageData(withEncryptedData: sendData))) sendOperation = session.sendOperation(with: builder.openPGPEncryptedMessageData(withEncryptedData: sendData), from: userID, recipients: encPGP) //TODO handle different callbacks sendOperation.start(callback) - if ordered[EncryptionType.unknown] == nil { + if ordered[CryptoScheme.UNKNOWN] == nil { createSendCopy(sendData: builder.openPGPEncryptedMessageData(withEncryptedData: sendData)) } builder.textBody = message @@ -252,7 +276,7 @@ class MailHandler { } } - if let unenc = ordered[EncryptionType.unknown] { + if let unenc = ordered[CryptoScheme.UNKNOWN] { builder.textBody = message sendData = builder.data() sendOperation = session.sendOperation(with: sendData, from: userID, recipients: unenc) @@ -296,23 +320,28 @@ class MailHandler { var sendData: Data //TODO: Consider pref enc = false - - encryption = EnzevalosEncryptionHandler.getEncryption(EncryptionType.PGP)! - if let encData = encryption.signAndEncrypt("\n" + message, mailaddresses: [useraddr]) { //ohne "\n" wird der erste Teil der Nachricht, bis sich ein einzelnen \n in einer Zeile befindet nicht in die Nachricht getan - sendData = builder.openPGPEncryptedMessageData(withEncryptedData: encData) - - let drafts = UserManager.backendDraftFolderPath - - if !DataHandler.handler.existsFolder(with: drafts) { - let op = IMAPSession.createFolderOperation(drafts) - op?.start({ _ in self.saveDraft(data: sendData, callback: callback)}) - } - else { - saveDraft(data: sendData, callback: callback) - } - } else { + let pgp = SwiftPGP() + let keys = DataHandler.handler.findSecretKeys() + if keys.count > 0{ + let mykey = keys[0] //TODO: multiple privatekeys + let receiverIds = [mykey.keyID] as! [String] + let cryptoObject = pgp.encrypt(plaintext: "\n" + message, ids: receiverIds, myId: mykey.keyID!) + if let encData = cryptoObject.chiphertext { + sendData = builder.openPGPEncryptedMessageData(withEncryptedData: encData) + + let drafts = UserManager.backendDraftFolderPath + + if !DataHandler.handler.existsFolder(with: drafts) { + let op = IMAPSession.createFolderOperation(drafts) + op?.start({ _ in self.saveDraft(data: sendData, callback: callback)}) + } + else { + saveDraft(data: sendData, callback: callback) + } + } else { //TODO do it better - callback(NSError(domain: NSCocoaErrorDomain, code: NSPropertyListReadCorruptError, userInfo: nil)) + callback(NSError(domain: NSCocoaErrorDomain, code: NSPropertyListReadCorruptError, userInfo: nil)) + } } } @@ -572,19 +601,7 @@ class MailHandler { var autocrypt: AutocryptContact? = nil if let _ = header?.extraHeaderValue(forName: AUTOCRYPTHEADER) { - autocrypt = AutocryptContact(header: header!) - if autocrypt?.type == EncryptionType.PGP && autocrypt?.key.characters.count > 0 { - let pgp = ObjectivePGP.init() - pgp.importPublicKey(fromHeader: (autocrypt?.key)!, allowDuplicates: false) - let enc = EnzevalosEncryptionHandler.getEncryption(EncryptionType.PGP) - do { - let pgpKey = try pgp.keys[0].export() - _ = enc?.addKey(pgpKey, forMailAddresses: [(header?.from.mailbox)!]) - } - catch { - print("Could not conntect key! \(autocrypt?.toString() ?? "empty autocrypt")") - } - } + autocrypt = AutocryptContact(header: header!) } if let to = header?.to { @@ -604,7 +621,7 @@ class MailHandler { let html: String var body: String var lineArray: [String] - var dec: DecryptedData? = nil + var dec: CryptoObject? = nil for a in (msgParser?.attachments())! { let at = a as! MCOAttachment @@ -623,9 +640,9 @@ class MailHandler { body = lineArray.joined(separator: "\n") body = body.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) body.append("\n") - dec = decryptText(body: body, from: message.header.from.mailbox) - if (dec?.decryptedBody != nil) { - msgParser = MCOMessageParser(data: dec?.decryptedBody) + dec = decryptText(body: body, from: message.header.from.mailbox, autocrypt: autocrypt) + if (dec?.plaintext != nil) { + msgParser = MCOMessageParser(data: dec?.decryptedData) body = msgParser!.plainTextBodyRenderingAndStripWhitespace(false) } } else { @@ -650,12 +667,37 @@ class MailHandler { } } - private func decryptText(body: String, from: String) -> DecryptedData? { - if let encryption = EnzevalosEncryptionHandler.getEncryption(EncryptionType.PGP) { - if let data = body.data(using: String.Encoding.utf8, allowLossyConversion: true) as Data? { - return encryption.decryptedMime(data, from: from) + private func decryptText(body: String, from: String, autocrypt: AutocryptContact?) -> CryptoObject? { + + + if let data = body.data(using: String.Encoding.utf8, allowLossyConversion: true) as Data? { + let pgp = SwiftPGP() + let adr = DataHandler.handler.findMailAddress(adr: from) + var keyIds = [String]() + + if let keys = adr?.key{ + for k in keys{ + let key = k as! PersistentKey + keyIds.append(key.keyID) + } } + if let a = autocrypt{ + let key = pgp.importKeys(key: a.key, isSecretKey: false, autocrypt: true) + keyIds.append(contentsOf: key) + } + let secretkeys = DataHandler.handler.findSecretKeys() + var decId: String? = nil + for s in secretkeys{ + if !s.obsolete{ + decId = s.keyID + break + } + } + + return pgp.decrypt(data: data, decryptionId: decId, verifyIds: keyIds) + } + return nil } diff --git a/enzevalos_iphone/Mail_Address+CoreDataClass.swift b/enzevalos_iphone/Mail_Address+CoreDataClass.swift index d24d9497e47bc58e32248e501acb86cff29761e0..ef883b7a9430224b8c37809882ade20cccf3b2a1 100644 --- a/enzevalos_iphone/Mail_Address+CoreDataClass.swift +++ b/enzevalos_iphone/Mail_Address+CoreDataClass.swift @@ -29,50 +29,18 @@ open class Mail_Address: NSManagedObject, MailAddress { return CNLabeledValue.init(label: CNLabelOther, value: address as NSString) } - open var prefEnc: EncState { - get{ - return prefer_encryption - } - set{ - prefer_encryption = newValue - } - } - - //TODO think about it! Better safe state or update state??? - open var keyID: String? { - get { - if self.encryptionType == EncryptionType.unknown{ - self.encryptionType = EnzevalosEncryptionHandler.getEncryptionType(self.address) - } - if let encryption = EnzevalosEncryptionHandler.getEncryption(self.encryptionType) { - return encryption.getActualKeyID(self.address) - } - return nil - } - set (newID) { - if let id = newID { - if let encryption = EnzevalosEncryptionHandler.getEncryption(self.encryptionType) { - if encryption.keyIDExists(id) { - if let currentID = self.keyID { - encryption.removeMailAddressForKey(self.mailAddress, keyID: currentID) - } - encryption.addMailAddressForKey(mailAddress, keyID: id) - } - } - } - else { - if let encryption = EnzevalosEncryptionHandler.getEncryption(self.encryptionType) { - if let currentID = self.keyID { - encryption.removeMailAddressForKey(self.mailAddress, keyID: currentID) - } - } - } + + open var Key: PersistentKey?{ + if hasKey{ + return self.key?.anyObject() as? PersistentKey } + return nil } + open var hasKey: Bool { - if let encryption = EnzevalosEncryptionHandler.getEncryption(self.encryptionType) { - return encryption.hasKey(self.mailAddress) + if key != nil && (key?.count)! > 0{ + return true } return false } diff --git a/enzevalos_iphone/Mail_Address+CoreDataProperties.swift b/enzevalos_iphone/Mail_Address+CoreDataProperties.swift index df9368537bd5890bc95e6d99cfc3e92b6960da31..4314b04c4cba5808c64544087b64683ab4b16afb 100644 --- a/enzevalos_iphone/Mail_Address+CoreDataProperties.swift +++ b/enzevalos_iphone/Mail_Address+CoreDataProperties.swift @@ -17,52 +17,13 @@ extension Mail_Address { } @NSManaged public var address: String - @NSManaged public var contact: EnzevalosContact? - @NSManaged public var lastSeen: Date? - @NSManaged public var lastSeenAutocrypt: Date? - - public var prefer_encryption: EncState{ - set { - let name = "prefer_encryption" - self.willChangeValue(forKey: name) - self.setPrimitiveValue(newValue.asInt(), forKey: name) - self.didChangeValue(forKey: name) - } - get { - - let name = "prefer_encryption" - self.willAccessValue(forKey: name) - let i = self.primitiveValue(forKey: name) as! Int - self.didAccessValue(forKey: name) - return EncState.find(i: i) - } - - - } - - - public var encryptionType: EncryptionType{ - set { - let name = "encryptionType" - self.willChangeValue(forKey: name) - self.setPrimitiveValue(newValue.rawValue, forKey: name) - self.didChangeValue(forKey: name) - } - get { - - let name = "encryptionType" - self.willAccessValue(forKey: name) - let string = self.primitiveValue(forKey: name) as! String? - self.didAccessValue(forKey: name) - return EncryptionType.fromString(string) - } - } - - + @NSManaged public var contact: EnzevalosContact? @NSManaged public var bcc: NSSet? @NSManaged public var cc: NSSet? @NSManaged public var from: NSSet? @NSManaged public var to: NSSet? + @NSManaged public var key: NSSet? + } @@ -117,3 +78,20 @@ extension Mail_Address { @NSManaged public func removeFromTo(_ values: NSSet) } + +// MARK: Generated accessors for key +extension Mail_Address { + + @objc(addKeyObject:) + @NSManaged public func addToKey(_ value: PersistentKey) + + @objc(removeKeyObject:) + @NSManaged public func removeFromKey(_ value: PersistentKey) + + @objc(addKey:) + @NSManaged public func addToKey(_ values: NSSet) + + @objc(removeKey:) + @NSManaged public func removeFromKey(_ values: NSSet) + +} diff --git a/enzevalos_iphone/ObjectivePGP/PGPBigNum+Private.h b/enzevalos_iphone/ObjectivePGP/PGPBigNum+Private.h index d8dd38ed69bd511766f37b84d29fa02236e9f34a..1fc0e6018c2a49306e415319a67facce11e0867e 100644 --- a/enzevalos_iphone/ObjectivePGP/PGPBigNum+Private.h +++ b/enzevalos_iphone/ObjectivePGP/PGPBigNum+Private.h @@ -6,8 +6,8 @@ // Copyright © 2017 Marcin Krzyżanowski. All rights reserved. // -#import <ObjectivePGP/PGPBigNum.h> -#import <ObjectivePGP/PGPMacros.h> +#import "PGPBigNum.h" +#import "PGPMacros.h" #import <openssl/bn.h> #import <Foundation/Foundation.h> diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPPacket+Private.h b/enzevalos_iphone/ObjectivePGP/Packets/PGPPacket+Private.h index ca4d3c6a92f99a47cd6cbf03222be0118cf92648..4cd0cfaf5281aae0c50dcbbce83e308ffbbe3bdf 100644 --- a/enzevalos_iphone/ObjectivePGP/Packets/PGPPacket+Private.h +++ b/enzevalos_iphone/ObjectivePGP/Packets/PGPPacket+Private.h @@ -7,7 +7,7 @@ // #import "PGPPacket.h" -#import <ObjectivePGP/ObjectivePGP.h> +#import "ObjectivePGP.h" NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPPublicKeyPacket+Private.h b/enzevalos_iphone/ObjectivePGP/Packets/PGPPublicKeyPacket+Private.h index c8c1137940956659343aaae1ab035d7aaefcefdc..198de9fa7785385b5a6afc63cc0f1d57762234bf 100644 --- a/enzevalos_iphone/ObjectivePGP/Packets/PGPPublicKeyPacket+Private.h +++ b/enzevalos_iphone/ObjectivePGP/Packets/PGPPublicKeyPacket+Private.h @@ -7,7 +7,7 @@ // #import "PGPPublicKeyPacket.h" -#import <ObjectivePGP/ObjectivePGP.h> +#import "ObjectivePGP.h" NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPSecretKeyPacket+Private.h b/enzevalos_iphone/ObjectivePGP/Packets/PGPSecretKeyPacket+Private.h index b0fb1d842e9a3041a7febfb734f95cb72a6ad737..21e6b81fa9a1dc19ebe8e64ac18b2bea6b92d117 100644 --- a/enzevalos_iphone/ObjectivePGP/Packets/PGPSecretKeyPacket+Private.h +++ b/enzevalos_iphone/ObjectivePGP/Packets/PGPSecretKeyPacket+Private.h @@ -7,7 +7,7 @@ // #import "PGPPublicKeyPacket+Private.h" -#import <ObjectivePGP/ObjectivePGP.h> +#import "ObjectivePGP.h" NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPSignaturePacket+Private.h b/enzevalos_iphone/ObjectivePGP/Packets/PGPSignaturePacket+Private.h index 4fba03882af1dfbb9bc974eb08fdef660f4f66ed..7e9ac9ca7afa636a62bf42ae8aaf80c32b8d0f07 100644 --- a/enzevalos_iphone/ObjectivePGP/Packets/PGPSignaturePacket+Private.h +++ b/enzevalos_iphone/ObjectivePGP/Packets/PGPSignaturePacket+Private.h @@ -6,7 +6,7 @@ // Copyright © 2017 Marcin Krzyżanowski. All rights reserved. // -#import <ObjectivePGP/ObjectivePGP.h> +#import "ObjectivePGP.h" NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/Onboarding.swift b/enzevalos_iphone/Onboarding.swift index 69f5de2ee88f34db48991fc6ad8f91d0ae928555..e015ab4e3dabcbfd4f34737285bfdf238bf8ab94 100644 --- a/enzevalos_iphone/Onboarding.swift +++ b/enzevalos_iphone/Onboarding.swift @@ -656,195 +656,7 @@ class Onboarding: NSObject { } } - static func importprivateKey(path: String) { - let pgp = ObjectivePGP.init() - pgp.importKeys(fromFile: path, allowDuplicates: false) - let enc = EnzevalosEncryptionHandler.getEncryption(EncryptionType.PGP) - do { - let data = try pgp.keys[0].export() - _ = enc?.addKey(data, forMailAddresses: []) - } - catch _ { } - } - - static func keyHandling() { - self.credentialFails = 0 - for encType in iterateEnum(EncryptionType.self) { - if let enc = EnzevalosEncryptionHandler.getEncryption(encType) { - enc.removeAllKeys() - } - } - EnzevalosEncryptionHandler.getEncryption(.PGP)?.printAllKeyIDs() - //--------------------------------------- - //Import private Key BEGIN - - var path: String? - print(UserManager.loadUserValue(Attribute.userAddr)! as! String) - let name = (UserManager.loadUserValue(Attribute.userAddr)! as! String).lowercased() - switch name { // TODO: @Jakob hast du das aus dem Study branch hier her geholt? - case "idsolutions@enzevalos.de": - importprivateKey(path: Bundle.main.path(forResource: "idsolutions-private", ofType: "gpg")!) - break - case "nchr@enzevalos.de": - importprivateKey(path: Bundle.main.path(forResource: "nchr-private", ofType: "gpg")!) - break - case "ncpayroll@enzevalos.de": - importprivateKey(path: Bundle.main.path(forResource: "ncpayroll-private", ofType: "gpg")!) - break - case "ullimuelle@web.de": - importprivateKey(path: Bundle.main.path(forResource: "ullimuelle-private", ofType: "gpg")!) - break - case "bob2005@web.de": - importprivateKey(path: Bundle.main.path(forResource: "bob-private", ofType: "gpg")!) - break - case "alice2005@web.de": - importprivateKey(path: Bundle.main.path(forResource: "alice2005-private", ofType: "gpg")!) - break - default: - let enc = EnzevalosEncryptionHandler.getEncryption(EncryptionType.PGP) - if let user = UserManager.loadUserValue(Attribute.userAddr) { - if let key = enc?.generateKey(adr: user as! String) { - print("My Key: \(key.keyID) for \(user) date: \(key.creationDate)") - } - } - - } - - - - - //Import private key END - //--------------------------------------- - //--------------------------------------- - //Import public Key BEGIN - - let enc = EnzevalosEncryptionHandler.getEncryption(EncryptionType.PGP) - var pgp = ObjectivePGP.init() - path = Bundle.main.path(forResource: "JakobBode", ofType: "asc") //<---- Schlüsseldatei - pgp.importKeys(fromFile: path!, allowDuplicates: false) - do { - let data = try pgp.keys[0].export() - _ = enc?.addKey(data, forMailAddresses: ["jakob.bode@fu-berlin.de"]) //<---- Emailadresse - } - catch _ { } - - //Import public key END - //---------------------------------------//--------------------------------------- - //Import public Key BEGIN - - path = Bundle.main.path(forResource: "JakobBode", ofType: "asc") //<---- Schlüsseldatei - pgp = ObjectivePGP.init() - pgp.importKeys(fromFile: path!, allowDuplicates: false) - do { - let data = try pgp.keys[0].export() - _ = enc?.addKey(data, forMailAddresses: ["jakob.bode@fu-berlin.de"]) //<---- Emailadresse - } - catch _ { } - - //Import public key END - //--------------------------------------- - //--------------------------------------- - //Import public Key BEGIN - - path = Bundle.main.path(forResource: "alice_enzevalos_public", ofType: "asc") //<---- Schlüsseldatei - pgp = ObjectivePGP.init() - pgp.importKeys(fromFile: path!, allowDuplicates: false) - do { - let data = try pgp.keys[0].export() - _ = enc?.addKey(data, forMailAddresses: ["alice@enzevalos.de"]) //<---- Emailadresse - } - catch _ { } - path = Bundle.main.path(forResource: "alice_enzevalos_public", ofType: "asc") //<---- Schlüsseldatei - pgp = ObjectivePGP.init() - pgp.importKeys(fromFile: path!, allowDuplicates: false) - do { - let data = try pgp.keys[0].export() - _ = enc?.addKey(data, forMailAddresses: ["alice@enzevalos.de"]) //<---- Emailadresse - } - catch _ { } - /* - path = Bundle.main.path(forResource: "dave_enzevalos_public", ofType: "asc") //<---- Schlüsseldatei - pgp = ObjectivePGP.init() - pgp.importKeys(fromFile: path!, allowDuplicates: false) - do { - let data = try pgp.keys[0].export() - _ = enc?.addKey(data, forMailAddresses: ["dave@enzevalos.de"]) //<---- Emailadresse - } - catch _ { } - */ - //Import public key END - //--------------------------------------- - //--------------------------------------- - //Import public Key BEGIN - - path = Bundle.main.path(forResource: "bob_enzevalos_public", ofType: "asc") //<---- Schlüsseldatei - pgp = ObjectivePGP.init() - pgp.importKeys(fromFile: path!, allowDuplicates: false) - do { - let data = try pgp.keys[0].export() - _ = enc?.addKey(data, forMailAddresses: ["bob@enzevalos.de"]) //<---- Emailadresse - } - catch _ { } - - //Import public key END - //--------------------------------------- - //--------------------------------------- - //Import public keys for labstudy BEGIN - - path = Bundle.main.path(forResource: "idsolutions-public", ofType: "gpg") - pgp = ObjectivePGP.init() - pgp.importKeys(fromFile: path!, allowDuplicates: false) - do { - let data = try pgp.keys[0].export() - _ = enc?.addKey(data, forMailAddresses: ["idsolutions@enzevalos.de"]) - } - catch _ { } - - path = Bundle.main.path(forResource: "nchr-public", ofType: "gpg") - pgp = ObjectivePGP.init() - pgp.importKeys(fromFile: path!, allowDuplicates: false) - do { - let data = try pgp.keys[0].export() - _ = enc?.addKey(data, forMailAddresses: ["nchr@enzevalos.de"]) - } - catch _ { } - - path = Bundle.main.path(forResource: "ncpayroll-public", ofType: "gpg") - pgp = ObjectivePGP.init() - pgp.importKeys(fromFile: path!, allowDuplicates: false) - do { - let data = try pgp.keys[0].export() - _ = enc?.addKey(data, forMailAddresses: ["ncpayroll@enzevalos.de"]) - } - catch _ { } - - switch name { - case "bob2005@web.de": - path = Bundle.main.path(forResource: "bob-public", ofType: "gpg") - pgp = ObjectivePGP.init() - pgp.importKeys(fromFile: path!, allowDuplicates: false) - do { - let data = try pgp.keys[0].export() - _ = enc?.addKey(data, forMailAddresses: ["bob2005@web.de"]) - } - catch _ { } - case "ullimuelle@web.de": - path = Bundle.main.path(forResource: "ullimuelle-public", ofType: "gpg") - pgp = ObjectivePGP.init() - pgp.importKeys(fromFile: path!, allowDuplicates: false) - do { - let data = try pgp.keys[0].export() - _ = enc?.addKey(data, forMailAddresses: ["ullimuelle@web.de"]) - } - catch _ { } - default: - break - } - - //Import public keys for labstudy END - //--------------------------------------- - } - + static func iterateEnum<T: Hashable>(_: T.Type) -> AnyIterator<T> { var i = 0 return AnyIterator { diff --git a/enzevalos_iphone/PersistentKey+CoreDataClass.swift b/enzevalos_iphone/PersistentKey+CoreDataClass.swift new file mode 100644 index 0000000000000000000000000000000000000000..97210527afdb4cb415d1b2cfb58ef48d41f864d7 --- /dev/null +++ b/enzevalos_iphone/PersistentKey+CoreDataClass.swift @@ -0,0 +1,52 @@ +// +// PersistentKey+CoreDataClass.swift +// +// +// Created by Oliver Wiese on 27.09.17. +// +// + +import Foundation +import CoreData + +@objc(PersistentKey) +public class PersistentKey: NSManagedObject { + + /* + discoveryDate = Date.init() as NSDate + firstMail = mail + addToMailaddress(adr) + self.keyID = keyID + */ + + open var prefEnc: EncState { + get{ + return prefer_encryption + } + set{ + prefer_encryption = newValue + } + } + + func verify(){ + self.verifiedDate = Date.init() as NSDate + } + + func isVerified() -> Bool{ + return self.verifiedDate != nil + } + + func isExpired()-> Bool{ + // TODO: Consider different cryptotypes! + let pgp = SwiftPGP() + if let key = pgp.loadKey(id: self.keyID){ + if let expire = key.expirationDate{ + return expire < Date.init() + } + return false + } + return true + } + + +} diff --git a/enzevalos_iphone/PersistentKey+CoreDataProperties.swift b/enzevalos_iphone/PersistentKey+CoreDataProperties.swift new file mode 100644 index 0000000000000000000000000000000000000000..6955d4c97a44b2331554a32c56112f74f6800d41 --- /dev/null +++ b/enzevalos_iphone/PersistentKey+CoreDataProperties.swift @@ -0,0 +1,63 @@ +// +// PersistentKey+CoreDataProperties.swift +// +// +// Created by Oliver Wiese on 27.09.17. +// +// + +import Foundation +import CoreData + + +extension PersistentKey { + + @nonobjc public class func fetchRequest() -> NSFetchRequest<PersistentKey> { + return NSFetchRequest<PersistentKey>(entityName: "PersistentKey") + } + + @NSManaged public var keyID: String + @NSManaged public var verifiedDate: NSDate? + @NSManaged public var encryptionType: Int16 + @NSManaged public var lastSeen: NSDate? + @NSManaged public var lastSeenAutocrypt: NSDate? + @NSManaged public var discoveryDate: NSDate? + @NSManaged public var mailaddress: NSSet? + @NSManaged public var firstMail: PersistentMail? + + public var prefer_encryption: EncState{ + set { + let name = "prefer_encryption" + self.willChangeValue(forKey: name) + self.setPrimitiveValue(newValue.asInt(), forKey: name) + self.didChangeValue(forKey: name) + } + get { + + let name = "prefer_encryption" + self.willAccessValue(forKey: name) + let i = self.primitiveValue(forKey: name) as! Int + self.didAccessValue(forKey: name) + return EncState.find(i: i) + } + + + } +} + +// MARK: Generated accessors for mailaddress +extension PersistentKey { + + @objc(addMailaddressObject:) + @NSManaged public func addToMailaddress(_ value: Mail_Address) + + @objc(removeMailaddressObject:) + @NSManaged public func removeFromMailaddress(_ value: Mail_Address) + + @objc(addMailaddress:) + @NSManaged public func addToMailaddress(_ values: NSSet) + + @objc(removeMailaddress:) + @NSManaged public func removeFromMailaddress(_ values: NSSet) + +} diff --git a/enzevalos_iphone/ReadVENDelegate.swift b/enzevalos_iphone/ReadVENDelegate.swift index 58a9cde28661b74a8407ec680014864e4683dbf3..940207b5f42339a190de3a16a83a9579b36fcb23 100644 --- a/enzevalos_iphone/ReadVENDelegate.swift +++ b/enzevalos_iphone/ReadVENDelegate.swift @@ -70,8 +70,10 @@ extension ReadVENDelegate: VENTokenFieldDelegate { } func tokenField(_ tokenField: VENTokenField, colorSchemeForTokenAt index: UInt) -> UIColor { - if EnzevalosEncryptionHandler.hasKey(DataHandler.handler.getContactByAddress(tokenField.mailTokens[Int(index)] as! String)) { //unfassbar langsam! - return UIColor.init(red: 0, green: 122.0 / 255.0, blue: 1, alpha: 1) + if let adr = DataHandler.handler.findMailAddress(adr: tokenField.mailTokens[Int(index)] as! String){ + if adr.hasKey{ + return UIColor.init(red: 0, green: 122.0 / 255.0, blue: 1, alpha: 1) + } } return UIColor.orange } diff --git a/enzevalos_iphone/ReadViewController.swift b/enzevalos_iphone/ReadViewController.swift index b46c00d3f8b68983f435d6b92505e2a2e0ea25e8..b0f3c7ba01bcdad3d573c1ef05a4007185031d68 100644 --- a/enzevalos_iphone/ReadViewController.swift +++ b/enzevalos_iphone/ReadViewController.swift @@ -89,8 +89,8 @@ class ReadViewController: UITableViewController { _ = mail?.from.contact?.records.flatMap { x in if x.hasKey && x.key != nil { - let keyWrapper = EnzevalosEncryptionHandler.getEncryption(.PGP)?.getKey(x.key!) - keyDiscoveryDate = keyWrapper?.discoveryTime + let keyWrapper = DataHandler.handler.findKey(keyID: x.key!) + keyDiscoveryDate = keyWrapper?.discoveryDate as! Date } } } @@ -124,7 +124,7 @@ class ReadViewController: UITableViewController { let records = DataHandler.handler.getContactByAddress(email).records for r in records { for address in r.addresses { - if address.mailAddress == email && address.prefEnc.canEnc() == r.hasKey { + if address.mailAddress == email && address.hasKey == r.hasKey { performSegue(withIdentifier: "showContact", sender: ["record": r, "email": email]) return } diff --git a/enzevalos_iphone/SendViewController.swift b/enzevalos_iphone/SendViewController.swift index ecef162fea7d97909b40febd89abf52b2c9c5673..82cf67b1899d82ef6668e6a076fee6f688db415b 100644 --- a/enzevalos_iphone/SendViewController.swift +++ b/enzevalos_iphone/SendViewController.swift @@ -213,7 +213,7 @@ class SendViewController: UIViewController { let records = DataHandler.handler.getContactByAddress(email).records for r in records { for address in r.addresses { - if address.mailAddress == email && address.prefEnc.canEnc() == r.hasKey { + if address.mailAddress == email && address.hasKey == r.hasKey { performSegue(withIdentifier: "showContact", sender: ["record": r, "email": email]) self.view.endEditing(true) return @@ -237,12 +237,12 @@ class SendViewController: UIViewController { var to = [MailAddress]() var cc = [MailAddress]() for mail in toText.mailTokens { - if let mail = mail as? String, !EnzevalosEncryptionHandler.hasKey(mail) { + if let mail = mail as? String{ // , !EnzevalosEncryptionHandler.hasKey(mail) to.append(DataHandler.handler.getMailAddress(mail, temporary: true)) } } for mail in ccText.mailTokens { - if let mail = mail as? String, !EnzevalosEncryptionHandler.hasKey(mail) { + if let mail = mail as? String{ // , !EnzevalosEncryptionHandler.hasKey(mail) cc.append(DataHandler.handler.getMailAddress(mail, temporary: true)) } } @@ -604,7 +604,11 @@ extension VENTokenFieldDataSource { func someSecure(_ tokenField: VENTokenField) -> Bool { var secure = false for entry in tokenField.mailTokens { - secure = secure || EnzevalosEncryptionHandler.hasKey(entry as! String) + var hasKey = false + if let madr = DataHandler.handler.findMailAddress(adr: entry as! String){ + hasKey = madr.hasKey + } + secure = secure || hasKey } return secure diff --git a/enzevalos_iphone/SwiftPGP.swift b/enzevalos_iphone/SwiftPGP.swift index 56b8f594481069e22f3af673271a38f9afa5921e..8634d8b9e22baeece6f90b9e31637478ebf84964 100644 --- a/enzevalos_iphone/SwiftPGP.swift +++ b/enzevalos_iphone/SwiftPGP.swift @@ -31,7 +31,7 @@ class SwiftPGP: Encryption{ return id } - private func loadKey(id: String) -> PGPKey?{ + func loadKey(id: String) -> PGPKey?{ do{ if let data = try keychain.getData(id){ let pgp = ObjectivePGP() @@ -66,6 +66,17 @@ class SwiftPGP: Encryption{ } return ids } + + func importKeysFromFile(file: String) -> [String]{ + let pgp = ObjectivePGP() + let keys = pgp.importKeys(fromFile: file) + var ids = [String]() + for k in keys{ + ids.append(storeKey(key: k)) + } + return ids + } + func exportKey(id: String, isSecretkey isSecretKey: Bool, autocrypt: Bool) -> String?{ let pgp = ObjectivePGP() if var key = loadKey(id: id){ @@ -92,7 +103,6 @@ class SwiftPGP: Encryption{ } return nil } - func encrypt(plaintext: String, ids: [String], myId: String) -> CryptoObject{ let pgp = ObjectivePGP() @@ -106,15 +116,15 @@ class SwiftPGP: Encryption{ if let data = plaintext.data(using: String.Encoding.utf8){ do{ let chipher = try pgp.encryptData(data, using: keys, signWith: signKey, passphrase: nil, armored: true) - return CryptoObject(chiphertext: chipher, plaintext: plaintext, sigState: SignatureState.ValidSignature, encState: EncryptionState.ValidedEncryptedWithCurrentKey, signKey: myId, encType: CryptoScheme.PGP) + return CryptoObject(chiphertext: chipher, plaintext: plaintext, decryptedData: data, sigState: SignatureState.ValidSignature, encState: EncryptionState.ValidedEncryptedWithCurrentKey, signKey: myId, encType: CryptoScheme.PGP) } catch { print("Encryption error!") //TODO: Error handling! } } - return CryptoObject(chiphertext: nil, plaintext: nil, sigState: SignatureState.InvalidSignature, encState: EncryptionState.UnableToDecrypt, signKey: nil, encType: cryptoScheme) + return CryptoObject(chiphertext: nil, plaintext: nil,decryptedData: nil, sigState: SignatureState.InvalidSignature, encState: EncryptionState.UnableToDecrypt, signKey: nil, encType: cryptoScheme) } - func decrypt(data: Data,decryptionId: String, verifyIds: [String]) -> CryptoObject{ + func decrypt(data: Data,decryptionId: String?, verifyIds: [String]) -> CryptoObject{ let pgp = ObjectivePGP() //has to be var because it is given as pointer to obj-c-code @@ -129,14 +139,18 @@ class SwiftPGP: Encryption{ var encState = EncryptionState.UnableToDecrypt //TODO: More decryption keys? var sigKey: String? = nil - if let decKey = loadKey(id: decryptionId){ - pgp.importKeys(Set([decKey])) - } - else{ - return CryptoObject(chiphertext: data, plaintext: nil, sigState: SignatureState.NoSignature, encState: EncryptionState.UnableToDecrypt, signKey: nil, encType: CryptoScheme.PGP) + if let decId = decryptionId{ + if let decKey = loadKey(id: decId){ + pgp.importKeys(Set([decKey])) + } + //else{ + // return CryptoObject(chiphertext: data, plaintext: nil, sigState: SignatureState.NoSignature, encState: EncryptionState.UnableToDecrypt, signKey: nil, encType: CryptoScheme.PGP) + // } } + + for id in verifyIds{ let key = loadKey(id: id) do{ @@ -174,6 +188,6 @@ class SwiftPGP: Encryption{ if plaindata != nil{ plaintext = plaindata?.base64EncodedString() } - return CryptoObject(chiphertext: data, plaintext: plaintext , sigState: sigState, encState: encState, signKey: sigKey, encType: CryptoScheme.PGP) + return CryptoObject(chiphertext: data, plaintext: plaintext, decryptedData: plaindata, sigState: sigState, encState: encState, signKey: sigKey, encType: CryptoScheme.PGP) } } diff --git a/enzevalos_iphone/TableViewDataDelegate.swift b/enzevalos_iphone/TableViewDataDelegate.swift index b4a278b06214e5b2f29fc6ee21d267cbc44ac816..4732960d0663a0e1cefa0f6196d97fe73ffc2c0f 100644 --- a/enzevalos_iphone/TableViewDataDelegate.swift +++ b/enzevalos_iphone/TableViewDataDelegate.swift @@ -34,7 +34,7 @@ class TableViewDataDelegate : NSObject, UITableViewDelegate, UITableViewDataSour cell.img.image = img } - if !EnzevalosEncryptionHandler.hasKey(cell.address.text!) { + if !DataHandler.handler.hasKey(adr: cell.address.text!) { cell.name.textColor! = UIColor.orange cell.address.textColor! = UIColor.orange } diff --git a/enzevalos_iphone/UserData.swift b/enzevalos_iphone/UserData.swift index ad7a70b3c7a38e89e5c299e1b8987079437648cc..b0796d88b591ab8b190a13cc423825d2ac516225 100644 --- a/enzevalos_iphone/UserData.swift +++ b/enzevalos_iphone/UserData.swift @@ -16,15 +16,15 @@ enum Attribute: Int{ var defaultValue:AnyObject? { switch self { case .accountname: - return Attribute.attributeValues[Attribute.accountname]! //return "Alice" + return Attribute.attributeValues[Attribute.accountname]! case .userName: - return Attribute.attributeValues[Attribute.userName]! //return "Alice2005" + return Attribute.attributeValues[Attribute.userName]! case .userAddr: - return Attribute.attributeValues[Attribute.userAddr]! //return "alice2005@web.de" + return Attribute.attributeValues[Attribute.userAddr]! case .userPW: - return Attribute.attributeValues[Attribute.userPW]! //return "WJ$CE:EtUo3E$" + return Attribute.attributeValues[Attribute.userPW]! case .smtpHostname: - return Attribute.attributeValues[Attribute.smtpHostname]! //return "smtp.web.de" + return Attribute.attributeValues[Attribute.smtpHostname]! case .smtpPort: return Attribute.attributeValues[Attribute.smtpPort]! case .imapHostname: diff --git a/enzevalos_iphone/VENDataDelegate.swift b/enzevalos_iphone/VENDataDelegate.swift index b7f41d6497194e882b2a0430f2476a29bf3d8eff..e7880d9f9be8243772427a192f05827da467768d 100644 --- a/enzevalos_iphone/VENDataDelegate.swift +++ b/enzevalos_iphone/VENDataDelegate.swift @@ -38,7 +38,12 @@ class VENDataDelegate : NSObject, VENTokenFieldDataSource , VENTokenFieldDelegat } func tokenField(_ tokenField: VENTokenField, colorSchemeForTokenAt index: UInt) -> UIColor { - if EnzevalosEncryptionHandler.hasKey(tokenField.mailTokens[Int(index)] as! String) { + let adr = tokenField.mailTokens[Int(index)] as! String + var hasKey = false + if let madr = DataHandler.handler.findMailAddress(adr: adr){ + hasKey = madr.hasKey + } + if hasKey { return UIColor.init(red: 0, green: 122.0/255.0, blue: 1, alpha: 1) } return UIColor.orange @@ -104,7 +109,9 @@ class VENDataDelegate : NSObject, VENTokenFieldDataSource , VENTokenFieldDelegat } } - //eigene Methoden + //new + + func tokenFieldDidEndEditing(_ tokenF: VENTokenField){ if let last = tokenF.inputText() { @@ -118,7 +125,7 @@ class VENDataDelegate : NSObject, VENTokenFieldDataSource , VENTokenFieldDelegat func isSecure(_ tokenField: VENTokenField) -> Bool { var secure = true for entry in tokenField.mailTokens{ - secure = secure && EnzevalosEncryptionHandler.hasKey(entry as! String) + secure = secure && DataHandler.handler.hasKey(adr: entry as! String) } return secure } diff --git a/enzevalos_iphone/enzevalos_iphone.xcdatamodeld/enzevalos_iphone.xcdatamodel/contents b/enzevalos_iphone/enzevalos_iphone.xcdatamodeld/enzevalos_iphone.xcdatamodel/contents index d0c4bd9ac8170a1279eabe011f7b4b168fad76b3..d388b60e98a0d9c2aeceda102f466ec4e72e8230 100644 --- a/enzevalos_iphone/enzevalos_iphone.xcdatamodeld/enzevalos_iphone.xcdatamodel/contents +++ b/enzevalos_iphone/enzevalos_iphone.xcdatamodeld/enzevalos_iphone.xcdatamodel/contents @@ -4,8 +4,9 @@ <attribute name="accountname" attributeType="String" syncable="YES"/> <attribute name="dispalyname" attributeType="String" syncable="YES"/> <attribute name="pw" attributeType="String" syncable="YES"/> - <relationship name="address" toMany="YES" deletionRule="Nullify" destinationEntity="Mail_Address" syncable="YES"/> + <relationship name="address" maxCount="1" deletionRule="Nullify" destinationEntity="Mail_Address" syncable="YES"/> <relationship name="imap" maxCount="1" deletionRule="Nullify" destinationEntity="Server" syncable="YES"/> + <relationship name="secretkeys" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="SecretKey" syncable="YES"/> <relationship name="smtp" maxCount="1" deletionRule="Nullify" destinationEntity="Server" syncable="YES"/> </entity> <entity name="EnzevalosContact" representedClassName="EnzevalosContact" syncable="YES"> @@ -24,16 +25,24 @@ </entity> <entity name="Mail_Address" representedClassName="Mail_Address" syncable="YES"> <attribute name="address" attributeType="String" defaultValueString="""" syncable="YES"/> - <attribute name="encryptionType" optional="YES" attributeType="String" syncable="YES"/> - <attribute name="lastSeen" optional="YES" attributeType="Date" usesScalarValueType="NO" syncable="YES"/> - <attribute name="lastSeenAutocrypt" optional="YES" attributeType="Date" usesScalarValueType="NO" syncable="YES"/> - <attribute name="prefer_encryption" attributeType="Integer 16" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/> <relationship name="bcc" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="PersistentMail" inverseName="bcc" inverseEntity="PersistentMail" syncable="YES"/> <relationship name="cc" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="PersistentMail" inverseName="cc" inverseEntity="PersistentMail" syncable="YES"/> <relationship name="contact" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="EnzevalosContact" inverseName="addresses" inverseEntity="EnzevalosContact" syncable="YES"/> <relationship name="from" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="PersistentMail" inverseName="from" inverseEntity="PersistentMail" syncable="YES"/> + <relationship name="key" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PersistentKey" inverseName="mailaddress" inverseEntity="PersistentKey" syncable="YES"/> <relationship name="to" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="PersistentMail" inverseName="to" inverseEntity="PersistentMail" syncable="YES"/> </entity> + <entity name="PersistentKey" representedClassName="PersistentKey" syncable="YES"> + <attribute name="discoveryDate" attributeType="Date" usesScalarValueType="NO" syncable="YES"/> + <attribute name="encryptionType" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/> + <attribute name="keyID" attributeType="String" syncable="YES"/> + <attribute name="lastSeen" optional="YES" attributeType="Date" usesScalarValueType="NO" syncable="YES"/> + <attribute name="lastSeenAutocrypt" optional="YES" attributeType="Date" usesScalarValueType="NO" syncable="YES"/> + <attribute name="preferEncryption" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/> + <attribute name="verifiedDate" optional="YES" attributeType="Date" usesScalarValueType="NO" syncable="YES"/> + <relationship name="firstMail" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PersistentMail" syncable="YES"/> + <relationship name="mailaddress" toMany="YES" deletionRule="Nullify" destinationEntity="Mail_Address" inverseName="key" inverseEntity="Mail_Address" syncable="YES"/> + </entity> <entity name="PersistentMail" representedClassName="PersistentMail" syncable="YES"> <attribute name="body" attributeType="String" syncable="YES"/> <attribute name="date" attributeType="Date" defaultDateTimeInterval="-31582140" usesScalarValueType="NO" indexed="YES" syncable="YES"/> @@ -54,6 +63,10 @@ <relationship name="from" maxCount="1" deletionRule="Nullify" destinationEntity="Mail_Address" inverseName="from" inverseEntity="Mail_Address" syncable="YES"/> <relationship name="to" toMany="YES" deletionRule="Nullify" destinationEntity="Mail_Address" inverseName="to" inverseEntity="Mail_Address" syncable="YES"/> </entity> + <entity name="SecretKey" representedClassName="SecretKey" syncable="YES" codeGenerationType="class"> + <attribute name="keyID" optional="YES" attributeType="String" syncable="YES"/> + <attribute name="obsolete" optional="YES" attributeType="Boolean" usesScalarValueType="YES" syncable="YES"/> + </entity> <entity name="Server" representedClassName="Server" syncable="YES" codeGenerationType="class"> <attribute name="authType" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/> <attribute name="connectionType" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/> @@ -67,11 +80,13 @@ <fetchRequest name="getFolder" entity="Folder" predicateString="name == "$folder""/> <fetchRequest name="getMailAddress" entity="Mail_Address" predicateString="address == "$adr""/> <elements> - <element name="Account" positionX="-288" positionY="-9" width="128" height="135"/> + <element name="Account" positionX="-288" positionY="-9" width="128" height="150"/> <element name="EnzevalosContact" positionX="-209" positionY="198" width="128" height="90"/> <element name="Folder" positionX="-297" positionY="-18" width="128" height="150"/> - <element name="Mail_Address" positionX="-297" positionY="-18" width="128" height="195"/> + <element name="Mail_Address" positionX="-297" positionY="-18" width="128" height="150"/> + <element name="PersistentKey" positionX="-315" positionY="-36" width="128" height="180"/> <element name="PersistentMail" positionX="-416" positionY="-189" width="128" height="315"/> + <element name="SecretKey" positionX="-306" positionY="-27" width="128" height="75"/> <element name="Server" positionX="-279" positionY="0" width="128" height="105"/> <element name="State" positionX="-306" positionY="-27" width="128" height="75"/> </elements>