From 05bf6ce16404ea5df6241486111e8293f1bf89d0 Mon Sep 17 00:00:00 2001
From: Oliver Wiese <oliver.wiese@fu-berlin.de>
Date: Thu, 7 Mar 2019 19:23:31 +0100
Subject: [PATCH] update mail decryption and verification

---
 enzevalos_iphone.xcodeproj/project.pbxproj    |   4 +
 .../UserInterfaceState.xcuserstate            | Bin 7881 -> 16887 bytes
 enzevalos_iphone/CryptoObject.swift           |  25 +-
 enzevalos_iphone/Cryptography.swift           |   2 +-
 enzevalos_iphone/DataHandler.swift            |   2 +-
 enzevalos_iphone/MailHandler.swift            | 340 +---------
 enzevalos_iphone/SwiftPGP.swift               | 203 ++++--
 enzevalos_iphone/mail/IncomingMail.swift      | 596 ++++++++++++++++++
 enzevalos_iphoneTests/CoreDataTests.swift     |   5 +-
 enzevalos_iphoneTests/CryptoTests.swift       |  60 +-
 enzevalos_iphoneTests/MailTest.swift          |  61 +-
 11 files changed, 830 insertions(+), 468 deletions(-)
 create mode 100644 enzevalos_iphone/mail/IncomingMail.swift

diff --git a/enzevalos_iphone.xcodeproj/project.pbxproj b/enzevalos_iphone.xcodeproj/project.pbxproj
index 190d9b6a..651e77bc 100644
--- a/enzevalos_iphone.xcodeproj/project.pbxproj
+++ b/enzevalos_iphone.xcodeproj/project.pbxproj
@@ -162,6 +162,7 @@
 		478154A921FF3FF400A931EC /* Invitation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 478154A821FF3FF400A931EC /* Invitation.swift */; };
 		478154AC21FF6A9600A931EC /* Mailbot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 478154AB21FF6A9600A931EC /* Mailbot.swift */; };
 		478154AE2200641900A931EC /* StudyTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 478154AD2200641900A931EC /* StudyTest.swift */; };
+		478AF715222FD5C600AEF69E /* IncomingMail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 478AF714222FD5C600AEF69E /* IncomingMail.swift */; };
 		479B5977206914BE00B3944D /* CryptoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 479B5976206914BE00B3944D /* CryptoTests.swift */; };
 		479B597820691BE400B3944D /* ObjectivePGP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47CEF4EC2052C3E600887CDB /* ObjectivePGP.framework */; };
 		479B597920691BFB00B3944D /* libbz2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 47F867E32052B49800AA832F /* libbz2.tbd */; };
@@ -363,6 +364,7 @@
 		478154A821FF3FF400A931EC /* Invitation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Invitation.swift; sourceTree = "<group>"; };
 		478154AB21FF6A9600A931EC /* Mailbot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mailbot.swift; sourceTree = "<group>"; };
 		478154AD2200641900A931EC /* StudyTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StudyTest.swift; sourceTree = "<group>"; };
+		478AF714222FD5C600AEF69E /* IncomingMail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = IncomingMail.swift; path = mail/IncomingMail.swift; sourceTree = "<group>"; };
 		479B5976206914BE00B3944D /* CryptoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoTests.swift; sourceTree = "<group>"; };
 		479C649521F2139B00A01071 /* support_pk.asc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = support_pk.asc; sourceTree = "<group>"; };
 		479C649821F45DAF00A01071 /* HideShowPasswordTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HideShowPasswordTextField.swift; sourceTree = "<group>"; };
@@ -633,6 +635,7 @@
 				A1EB057B1D956838008659C1 /* MailHandler.swift */,
 				477548DD21F5DABE000B22A8 /* MailServerConnectionError.swift */,
 				47CEAC97222541B40075B7DC /* MailSession.swift */,
+				478AF714222FD5C600AEF69E /* IncomingMail.swift */,
 			);
 			name = mail;
 			sourceTree = "<group>";
@@ -1588,6 +1591,7 @@
 				3EC35F2D200376A1008BDF95 /* SendViewController+Invitation.swift in Sources */,
 				475B00341F7B9565006CDD41 /* Cryptography.swift in Sources */,
 				A1EB057C1D956838008659C1 /* MailHandler.swift in Sources */,
+				478AF715222FD5C600AEF69E /* IncomingMail.swift in Sources */,
 				A1EB05881D956879008659C1 /* AddressHandler.swift in Sources */,
 				472F39701E14F75C009260FB /* DataHandler.swift in Sources */,
 				A1C62E9A2018F716000E5273 /* OnboardingValueState.swift in Sources */,
diff --git a/enzevalos_iphone.xcodeproj/project.xcworkspace/xcuserdata/Olli.xcuserdatad/UserInterfaceState.xcuserstate b/enzevalos_iphone.xcodeproj/project.xcworkspace/xcuserdata/Olli.xcuserdatad/UserInterfaceState.xcuserstate
index c93b9ff53b8d6cc0260381a2db718b0bf37413fb..cc59415b1fd6ec353f8779ec0721d09d40ad4361 100644
GIT binary patch
literal 16887
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

delta 5327
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

diff --git a/enzevalos_iphone/CryptoObject.swift b/enzevalos_iphone/CryptoObject.swift
index 09a631d9..e6571a8c 100644
--- a/enzevalos_iphone/CryptoObject.swift
+++ b/enzevalos_iphone/CryptoObject.swift
@@ -7,18 +7,19 @@
 //
 
 import Foundation
-enum SignatureState {
-    case NoSignature
-    case NoPublicKey
-    case InvalidSignature
-    case ValidSignature
+enum SignatureState: Int {
+    
+    case NoSignature = 0
+    case NoPublicKey = 1
+    case InvalidSignature = -1
+    case ValidSignature = 2
 }
 
-enum EncryptionState {
-    case NoEncryption
-    case UnableToDecrypt
-    case ValidEncryptedWithOldKey
-    case ValidedEncryptedWithCurrentKey
+enum EncryptionState: Int {
+    case NoEncryption = 0
+    case UnableToDecrypt = 1
+    case ValidEncryptedWithOldKey = 2
+    case ValidedEncryptedWithCurrentKey = 3
 }
 
 public enum CryptoScheme {
@@ -89,8 +90,4 @@ public class CryptoObject {
         self.passcode = nil
         self.signedAdrs = signedAdrs
     }
-
-
-
-
 }
diff --git a/enzevalos_iphone/Cryptography.swift b/enzevalos_iphone/Cryptography.swift
index 26d1991f..2c47db46 100644
--- a/enzevalos_iphone/Cryptography.swift
+++ b/enzevalos_iphone/Cryptography.swift
@@ -20,6 +20,6 @@ public protocol Encryption {
 
     // operations on keys
     func encrypt(plaintext: String, ids: [String], myId: String, encryptForMyID: Bool) -> CryptoObject
-    func decrypt(data: Data, decryptionIDs: [String], verifyIds: [String], fromAdr: String?) -> CryptoObject
+    func decrypt(data: Data, attachedSignature: Data?, decKeyIDs: [String], signatureIDs: [String], fromAddr: String) -> CryptoObject
 
 }
diff --git a/enzevalos_iphone/DataHandler.swift b/enzevalos_iphone/DataHandler.swift
index 3e9987df..764f7fe6 100644
--- a/enzevalos_iphone/DataHandler.swift
+++ b/enzevalos_iphone/DataHandler.swift
@@ -829,7 +829,7 @@ class DataHandler {
             myfolder.maxID = mail.uid
         }
         var record = getKeyRecord(addr: mail.from.mailAddress, keyID: nil, saveRecord: false)
-        if let signedID = mail.signedKey?.keyID {
+        if let signedID = mail.signedKey?.keyID, mail.isSecure {
             record = getKeyRecord(addr: mail.from.mailAddress, keyID: signedID, saveRecord: false)
         }
         record.addToPersistentMails(mail)
diff --git a/enzevalos_iphone/MailHandler.swift b/enzevalos_iphone/MailHandler.swift
index e573b474..2122368c 100644
--- a/enzevalos_iphone/MailHandler.swift
+++ b/enzevalos_iphone/MailHandler.swift
@@ -512,8 +512,8 @@ class MailHandler {
                             return
                         }
                         if let parser = data {
-                            
-                            _ = self.parseMail(parser: parser, record: record, folderPath: folderPath, uid: UInt64(message.uid), flags: message.flags)
+                            let incomingMail = IncomingMail(rawData: parser.data(), uID: UInt64(message.uid), folderPath: folderPath, flags: message.flags)
+                            _ = incomingMail.store(keyRecord: record)
 
                         }
                         dispatchGroup.leave()
@@ -537,342 +537,6 @@ class MailHandler {
         }
     }
 
-    internal func parseMail(parser: MCOMessageParser, record: KeyRecord?, folderPath: String, uid: UInt64, flags: MCOMessageFlag) -> PersistentMail?{
-        var rec: [MCOAddress] = []
-        var cc: [MCOAddress] = []
-        var autocrypt: Autocrypt? = nil
-        var newKeyIds = [String]()
-        var secretKey: String? = nil
-        var isEnc = false
-        var html: String
-        var body: String
-        var lineArray: [String]
-        var dec: CryptoObject? = nil
-        let header = parser.header
-        let msgID = header?.messageID
-        let userAgent = header?.userAgent
-        var references = [String]()
-        var msgParser = parser
-    
-        // 1. parse header
-        if header?.from == nil {
-            // Drops mails with no from field. Otherwise it becomes ugly with no ezcontact,fromadress etc.
-            return nil
-        }
-        if let refs = header?.references {
-            for ref in refs {
-                if let string = ref as? String {
-                    references.append(string)
-                }
-            }
-        }
-        if let _ = header?.extraHeaderValue(forName: Autocrypt.AUTOCRYPTHEADER) {
-            autocrypt = Autocrypt(header: header!)
-        }
-        if let _ = header?.extraHeaderValue(forName: Autocrypt.SETUPMESSAGE) {
-            // TODO: Distinguish between other keys (future work)
-            return nil
-        }
-        if let to = header?.to {
-            for r in to {
-                rec.append(r as! MCOAddress)
-            }
-        }
-        if let c = header?.cc {
-            for r in c {
-                cc.append(r as! MCOAddress)
-            }
-        }
-        var attachedSignature: Data?
-        // 2. parse body
-        for a in (msgParser.attachments())! {
-            let at = a as! MCOAttachment
-            if at.mimeType == "application/pgp-encrypted" {
-                isEnc = true
-            }
-            if let signature = MailHandler.extractPGPSignature(attachment: at) {
-                attachedSignature = signature
-            }
-            if isEnc && at.mimeType == "application/octet-stream" {
-                msgParser = MCOMessageParser(data: at.data)
-            }
-            newKeyIds.append(contentsOf: parsePublicKeys(attachment: at))
-            if let sk = parseSecretKey(attachment: at) {
-                secretKey = sk
-            }
-        }
-        body = msgParser.plainTextBodyRenderingAndStripWhitespace(false)
-        if isEnc {
-            html = msgParser.plainTextRendering()
-            lineArray = html.components(separatedBy: "\n")
-            lineArray.removeFirst(4)
-            body = lineArray.joined(separator: "\n")
-            body = body.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
-            body.append("\n")
-            dec = decryptText(body: body, from: header?.from, autocrypt: autocrypt)
-            if (dec?.plaintext != nil) {
-                msgParser = MCOMessageParser(data: dec?.decryptedData)
-                body = parseBody(msgParser: msgParser)
-                for a in (msgParser.attachments())! {
-                    let at = a as! MCOAttachment
-                    newKeyIds.append(contentsOf: parsePublicKeys(attachment: at))
-                    if let sk = parseSecretKey(attachment: at) {
-                        secretKey = sk
-                    }
-
-                }
-            }
-        }
-        else if let attachedSig = attachedSignature {
-            let signedData = MailHandler.extractSignedData(data: msgParser.data())
-            let pgp = SwiftPGP()
-            var keyIds = [String]()
-            if let sender = header?.from.mailbox {
-                if let adr = DataHandler.handler.findMailAddress(adr: sender) {
-                    for k in adr.publicKeys {
-                        keyIds.append(k.keyID)
-                    }
-                }
-                dec = pgp.verify(data: signedData!, attachedSignature: attachedSig, verifyIds: keyIds, fromAdr: sender)
-            }
-        }
-        else {
-            body = parseBody(msgParser: msgParser)
-            if let chipher = findInlinePGP(text: msgParser.plainTextRendering()) {
-                dec = decryptText(body: chipher, from: header?.from, autocrypt: autocrypt)
-                if dec != nil {
-                    if let text = dec?.decryptedText {
-                        body = text.removeNewLines()
-                    }
-                }
-            }
-        }
-        newKeyIds.append(contentsOf: findKeyString(content: body))
-        if let header = header, let from = header.from, let date = header.date {
-            let mail = DataHandler.handler.createMail(uid, sender: from, receivers: rec, cc: cc, time: date, received: true, subject: header.subject ?? "", body: body, flags: flags, record: record, autocrypt: autocrypt, decryptedData: dec, folderPath: folderPath, secretKey: secretKey, references: references, mailagent: userAgent, messageID: msgID)
-            if let m = mail {
-                let pgp = SwiftPGP()
-                if let autoc = autocrypt {
-                    if let publickeys = try? pgp.importKeys(key: autoc.key, pw: nil, isSecretKey: false, autocrypt: true) {
-                        for pk in publickeys {
-                            _ = DataHandler.handler.newPublicKey(keyID: pk, cryptoType: CryptoScheme.PGP, adr: from.mailbox, autocrypt: true, firstMail: mail)
-                        }
-                    }
-                }
-                for keyId in newKeyIds {
-                    _ = DataHandler.handler.newPublicKey(keyID: keyId, cryptoType: CryptoScheme.PGP, adr: from.mailbox, autocrypt: false, firstMail: mail)
-                }
-                Logger.log(received: m)
-            }
-            return mail
-        }
-        return nil
-    }
-    
-    
-    func findSignedDataAndSignature(data: Data) -> (signedData: Data?, signature: Data?) {
-        var sig: Data?
-        if let parser = MCOMessageParser.init(data: data) {
-            for part in parser.attachments() {
-                if let attachment = part as? MCOAttachment, let data = MailHandler.extractPGPSignature(attachment: attachment) {
-                    sig = data
-                    break
-                }
-            }
-        }
-        
-        return (MailHandler.extractSignedData(data: data), sig)
-    }
-    
-    private static func matches(for regex: String, in text: String) -> [String] {
-        do {
-            let regex = try NSRegularExpression(pattern: regex)
-            let results = regex.matches(in: text,
-                                        range: NSRange(text.startIndex..., in: text))
-            return results.map {
-                String(text[Range($0.range, in: text)!])
-            }
-        } catch {
-            return []
-        }
-    }
-    private static func findBoundary(rawMail: String) -> String? {
-        let boundaries = matches(for: "boundary=.*;", in: rawMail)
-        if let bound = boundaries.first {
-            let splitted = bound.split(separator: "\"")
-            if splitted.count == 3 {
-                return "--"+String(splitted[1]) as String
-            }
-        }
-        return nil
-    }
-    
-    private static func extractSignedData(data: Data) -> Data? {
-        if let dataString = String.init(data: data, encoding: .utf8){
-            if dataString.contains("Content-Type: multipart/signed") , let boundary = findBoundary(rawMail: dataString) {
-                var parts =  dataString.components(separatedBy: boundary).dropFirst().filter({(s: String) -> Bool in
-                    // We drop pgp signature.
-                    // A messages, where a signed part is signed again, are strange and verification can fail -> What about a response etc?
-                    if s.contains("-----BEGIN PGP SIGNATURE-----") {
-                        return false
-                    }
-                    return true
-                })
-                parts = parts.map({(s: String) -> String in
-                    // Convert strings according to RFC3156. See: https://tools.ietf.org/html/rfc3156 page 6
-                    var newString = s.trimmed()
-                    newString = newString.replacingOccurrences(of: "\r\n", with: "\n")
-                    newString = newString.replacingOccurrences(of: "\n", with: "\r\n")
-                    // Sometimes tabs got lost?! TEST TODO
-                    newString = newString.replacingOccurrences(of: "    charset", with: "\tcharset")
-                    //TODO: Remove -- if last symbol
-                    if newString.hasSuffix("--") {
-                        newString = String(newString.dropLast(2))
-                    }
-                    return newString
-                })
-                if parts.count == 0 {
-                    return parts.first?.data(using: .utf8)
-                }
-                else {
-                    let res = parts.joined(separator: "\r\n")
-                    return res.data(using: .utf8)
-                }
-            }
-        }
-        return nil
-    }
-    
-    
-    private static func extractPGPSignature(attachment: MCOAttachment) -> Data? {
-        if attachment.mimeType == "application/pgp-signature" {
-           return attachment.data
-        }
-        return nil
-    }
-
-    
-    private func parseBody(msgParser: MCOMessageParser) -> String {
-        if let text = msgParser.plainTextBodyRenderingAndStripWhitespace(false) {
-            var body = text
-            var c = body.first
-            while (c != nil && CharacterSet.whitespacesAndNewlines.contains((c?.unicodeScalars.first)!)) {
-                body.removeFirst()
-                c = body.first
-            }
-            c = body.last
-            while (c != nil && CharacterSet.whitespacesAndNewlines.contains((c?.unicodeScalars.first)!)) {
-                body.removeLast()
-                c = body.last
-            }
-            return body
-        }
-       return ""
-    }
-    
-    private func findInlinePGP(text: String) -> String? {
-        var range = text.range(of: "-----BEGIN PGP MESSAGE-----")
-        if let lower = range?.lowerBound {
-            range = text.range(of: "-----END PGP MESSAGE-----")
-            if let upper = range?.upperBound {
-                let retValue = String(text[lower..<upper])
-                // We do not try to decrypt a previous mails.
-                if retValue.contains(">"){
-                    return nil
-                }
-                return retValue
-            }
-        }
-        return nil
-    }
-
-    
-    private func findKeyString(content: String) -> [String] {
-        var newKey = [String]()
-        if content.contains("-----BEGIN PGP PUBLIC KEY BLOCK-----") {
-            if let start = content.range(of: "-----BEGIN PGP PUBLIC KEY BLOCK-----") {
-                var end = content.range(of: "-----END PGP PUBLIC KEY BLOCK-----\n")
-                if end == nil {
-                    end = content.range(of: "-----END PGP PUBLIC KEY BLOCK-----")
-                }
-                if let end = end {
-                    let s = start.lowerBound
-                    let e = end.upperBound
-                    let pk = content[s..<e]
-                    let pgp = SwiftPGP()
-                    if let keyId = try? pgp.importKeys(key: String(pk), pw: nil, isSecretKey: false, autocrypt: false) {
-                        newKey.append(contentsOf: keyId)
-                    }
-                }
-            }
-        }
-        return newKey
-    }
-    
-    private func parsePublicKeys(attachment: MCOAttachment) -> [String] {
-        var newKey = [String]()
-        if let content = attachment.decodedString() {
-            newKey.append(contentsOf: findKeyString(content: content))
-        } else if attachment.mimeType == "application/octet-stream", let content = String(data: attachment.data, encoding: String.Encoding.utf8), content.hasPrefix("-----BEGIN PGP PUBLIC KEY BLOCK-----") && (content.hasSuffix("-----END PGP PUBLIC KEY BLOCK-----") || content.hasSuffix("-----END PGP PUBLIC KEY BLOCK-----\n")) {
-            let pgp = SwiftPGP()
-            if let keyId = try? pgp.importKeys(key: content, pw: nil, isSecretKey: false, autocrypt: false) {
-                newKey.append(contentsOf: keyId)
-            }
-        } else if attachment.mimeType == "application/pgp-keys" {
-            let pgp = SwiftPGP()
-            if let keyIds = try? pgp.importKeys(data: attachment.data, pw: nil, secret: false) {
-                newKey.append(contentsOf: keyIds)
-            }
-        }
-        return newKey
-    }
-    private func parseSecretKey(attachment: MCOAttachment) -> String? {
-        if let content = attachment.decodedString() {
-            if content.contains("-----BEGIN PGP PRIVATE KEY BLOCK-----") {
-                if let start = content.range(of: "-----BEGIN PGP PRIVATE KEY BLOCK-----"),
-                    let end = content.range(of: "-----END PGP PRIVATE KEY BLOCK-----") {
-                    let s = start.lowerBound
-                    let e = end.upperBound
-                    let sk = String(content[s..<e])
-                    return sk
-                }
-            }
-        }
-        return nil
-    }
-    private func decryptText(body: String, from: MCOAddress?, autocrypt: Autocrypt?) -> CryptoObject? {
-        var sender: String? = nil
-        if let fromMCO = from {
-            sender = fromMCO.mailbox
-        }
-        if let data = body.data(using: String.Encoding.utf8, allowLossyConversion: true) as Data? {
-            let pgp = SwiftPGP()
-            var keyIds = [String]()
-            if sender != nil, let adr = DataHandler.handler.findMailAddress(adr: sender!) {
-                for k in adr.publicKeys {
-                    keyIds.append(k.keyID)
-                }
-            }
-            if let a = autocrypt {
-                if let key = try? pgp.importKeys(key: a.key, pw: nil, isSecretKey: false, autocrypt: true) {
-                    keyIds.append(contentsOf: key)
-                }
-            }
-            let secretkeys = DataHandler.handler.findSecretKeys()
-            var decIds = [String]()
-            for sk in secretkeys {
-                if let id = sk.keyID {
-                    decIds.append(id)
-                }
-            }
-
-            return pgp.decrypt(data: data, decryptionIDs: decIds, verifyIds: keyIds, fromAdr: sender)
-        }
-
-        return nil
-    }
-
-
     func checkSMTP(_ completion: @escaping (MailServerConnectionError?) -> Void) {
         if AppDelegate.getAppDelegate().currentReachabilityStatus == .notReachable {
             completion(MailServerConnectionError.NoInternetconnection)
diff --git a/enzevalos_iphone/SwiftPGP.swift b/enzevalos_iphone/SwiftPGP.swift
index 428432c6..9ed63aff 100644
--- a/enzevalos_iphone/SwiftPGP.swift
+++ b/enzevalos_iphone/SwiftPGP.swift
@@ -238,6 +238,16 @@ class SwiftPGP: Encryption {
         }
     }
     
+    func importKeys(keys: [String]) -> [String] {
+        var keyIds = [String]()
+        for key in keys {
+            if let newIds = try? importKeys(key: key, pw: nil, isSecretKey: false, autocrypt: false) {
+                keyIds.append(contentsOf: newIds)
+            }
+        }
+        return keyIds
+    }
+    
     func importKeys (key: String,  pw: String?, isSecretKey: Bool, autocrypt: Bool) throws -> [String]{
         var keys = [Key]()
         if autocrypt{
@@ -387,7 +397,55 @@ class SwiftPGP: Encryption {
         
     }
     
-    func decrypt(data: Data, decryptionIDs: [String], verifyIds: [String], fromAdr: String?) -> CryptoObject{
+    func verify(data: Data, attachedSignature: Data, verifyId: String, fromAdr: String) -> CryptoObject {
+        var sigKeyID: String? = nil
+        var signedAdr = [String]()
+        var sigState = SignatureState.NoSignature
+        let encState = EncryptionState.NoEncryption
+        let keyring = Keyring()
+        
+        if let key = loadKey(id: verifyId){
+            keyring.import(keys: [key])
+        }
+        
+        do{
+            let keys = keyring.keys
+            try ObjectivePGP.verify(data, withSignature: attachedSignature, using: keys, passphraseForKey: loadPassword)
+            sigState = SignatureState.ValidSignature
+            sigKeyID = verifyId
+            signedAdr = vaildAddress(key: keys.first)
+        } catch {
+            let nsError = error as NSError
+            print(nsError)
+            switch nsError.code {
+            case 7: // no public key
+                sigState = SignatureState.NoPublicKey
+            case 8: // no signature
+                sigState = SignatureState.NoSignature
+            case 9: // unable to decrypt
+                sigState = SignatureState.InvalidSignature
+            default:
+                sigState = SignatureState.InvalidSignature
+            }
+        }
+        if !signedAdr.contains(fromAdr) && sigState == SignatureState.ValidSignature {
+            sigState = .InvalidSignature
+        }
+        
+        return CryptoObject(chiphertext: data, plaintext: nil, decryptedData: nil, sigState: sigState, encState: encState, signKey: sigKeyID, encType: .PGP, signedAdrs: signedAdr)
+    }
+    
+    func decrypt(mail: IncomingMail) -> CryptoObject {
+        let decIds = mail.decryptionKeyIDs
+        let data = mail.cryptoData
+        let sigIDs = mail.signatureKeyIDs
+        if let addr = mail.signatureAddr {
+            return decrypt(data: data, attachedSignature: nil, decKeyIDs: decIds, signatureIDs: sigIDs, fromAddr: addr)
+        }
+        return CryptoObject(chiphertext: data, plaintext: nil, decryptedData: nil, sigState: .InvalidSignature, encState: .UnableToDecrypt, signKey: nil, encType: .PGP, signedAdrs: []) //TODO: Check decryption only
+    }
+    
+    func decrypt(data: Data, attachedSignature: Data? = nil, decKeyIDs: [String], signatureIDs: [String], fromAddr: String) -> CryptoObject{
         let prefKey = DataHandler.handler.prefSecretKey()
         var plaindata: Data? = nil
         var plaintext: String? = nil
@@ -401,58 +459,59 @@ class SwiftPGP: Encryption {
          DECRYPTION
          */
         // TODO: Maybe consider: try ObjectivePGP.recipientsKeyID(forMessage: ...) but currently not working...
-        for decID in decryptionIDs{
+        for decID in decKeyIDs{
             if let decKey = loadKey(id: decID){
                 if decID == prefID{
+                    keyring.import(keys: [decKey])
                     let (currentPlain, currentEncState) = decryptMessage(data: data, keys: [decKey], encForCurrentSK: true)
                     if encState != EncryptionState.ValidEncryptedWithOldKey || currentEncState == EncryptionState.ValidedEncryptedWithCurrentKey{
                         plaindata = currentPlain
                         encState = currentEncState
+                        break
                     }
                 }
-                keyring.import(keys: [decKey])
             }
         }
         if encState != EncryptionState.ValidedEncryptedWithCurrentKey{
+            for decID in decKeyIDs {
+                if let decKey = loadKey(id: decID) {
+                    keyring.import(keys: [decKey])
+                }
+            }
             (plaindata, encState) = decryptMessage(data: data, keys: keyring.keys, encForCurrentSK: false)
         }
         /*
          VERIFICATION
          */
         // test if message ist signed
-        sigState = verifyMessage(data: data, keys: keyring.keys)
-        
-        for id in verifyIds{
-            if let key = loadKey(id: id){
-                keyring.import(keys: [key])
-                let currentState = verifyMessage(data: data, keys: keyring.keys)
-                if currentState == SignatureState.ValidSignature{
-                    sigState = currentState
-                    sigKeyID = id
-                    signedAdr = vaildAddress(key: key)
-                    break
-                }
-                if currentState == SignatureState.InvalidSignature{
-                    sigState = currentState
+        let (currentSigState, signedID, signedAddr) = verifyData(toVerifyData: data, attachedSignature: attachedSignature, signatureIDs: signatureIDs, keyring: keyring)
+        print(currentSigState)
+        if currentSigState == .ValidSignature {
+            sigState = currentSigState
+            sigKeyID = signedID
+            signedAdr = signedAddr
+        }
+        else {
+            sigState = currentSigState
+            if let plainData = plaindata {
+                let (currentSigState2, signedID2, signedAddr2) = verifyData(toVerifyData: plainData, attachedSignature: attachedSignature, signatureIDs: signatureIDs, keyring: Keyring())
+                if currentSigState2.rawValue > sigState.rawValue {
+                    sigState = currentSigState2
+                    sigKeyID = signedID2
+                    signedAdr = signedAddr2
                 }
             }
         }
         
         if sigState == SignatureState.ValidSignature && sigKeyID == nil{
-            for id in decryptionIDs{
-                if let key = loadKey(id: id){
-                    keyring.import(keys: [key])
-                    let currentState = verifyMessage(data: data, keys: keyring.keys)
-                    if currentState == SignatureState.ValidSignature{
-                        sigState = currentState
-                        sigKeyID = id
-                        signedAdr = vaildAddress(key: key)
-                        break
-                    }
-                    if currentState == SignatureState.InvalidSignature{
-                        sigState = currentState
-                    }
-                }
+            let currentState = verifyData(toVerifyData: data, attachedSignature: attachedSignature, signatureIDs: decKeyIDs, keyring: keyring)
+            if currentState.sigState == SignatureState.ValidSignature{
+                sigState = currentState.sigState
+                sigKeyID = currentState.sigKeyID
+                signedAdr = currentState.signedAdr
+            }
+            if currentState.sigState == SignatureState.InvalidSignature{
+                sigState = currentState.sigState
             }
         }
         
@@ -465,18 +524,37 @@ class SwiftPGP: Encryption {
         else if encState == .NoEncryption{
             plaintext =  String(data: data, encoding: String.Encoding.utf8)
         }
+        
+        if sigState == .ValidSignature && !signedAdr.contains(fromAddr) {
+            sigState = .InvalidSignature
+        }
         return CryptoObject(chiphertext: data, plaintext: plaintext, decryptedData: plaindata, sigState: sigState, encState: encState, signKey: sigKeyID, encType: CryptoScheme.PGP, signedAdrs: signedAdr)
     }
     
-    
-    func decrypt(data: Data,decryptionId: String?, verifyIds: [String], fromAdr: String?) -> CryptoObject{
-        if let decId = decryptionId{
-            return decrypt(data: data, decryptionIDs: [decId], verifyIds: verifyIds, fromAdr: fromAdr)
+    private func verifyData(toVerifyData: Data, attachedSignature: Data?, signatureIDs: [String], keyring: Keyring) -> (sigState: SignatureState, sigKeyID: String?, signedAdr: [String]) {
+        var sigState = verifySignature(data: toVerifyData, attachedSignature: attachedSignature, keys: [])
+        print(sigState)
+        var sigKeyID: String?
+        var signedAdr: [String] = []
+        for id in signatureIDs {
+            if let key = loadKey(id: id){
+                keyring.import(keys: [key])
+                let currentState = verifySignature(data: toVerifyData, attachedSignature: attachedSignature, keys: keyring.keys)
+                print(currentState)
+                if currentState == SignatureState.ValidSignature{
+                    sigState = currentState
+                    sigKeyID = id
+                    signedAdr = vaildAddress(key: key)
+                    break
+                }
+                if currentState == SignatureState.InvalidSignature{
+                    sigState = currentState
+                }
+            }
         }
-        return decrypt(data: data, decryptionIDs: [String](), verifyIds: verifyIds, fromAdr: fromAdr)
+        return (sigState, sigKeyID, signedAdr)
     }
     
-    
     private func decryptMessage(data: Data, keys: [Key], encForCurrentSK: Bool) -> (Data?, EncryptionState){
         if let dataString = String(data: data, encoding: .utf8) {
             do {
@@ -506,28 +584,43 @@ class SwiftPGP: Encryption {
         return (nil, EncryptionState.NoEncryption)
     }
     
-    private func verifyMessage(data: Data, keys: [Key]) -> SignatureState{
-        if let dataString = String(data: data, encoding: .utf8), let unarmored = try? Armor.readArmored(dataString){
-            do{
-                try ObjectivePGP.verify(unarmored, withSignature: nil, using: keys, passphraseForKey: loadPassword)
-                return SignatureState.ValidSignature
-            } catch {
-                let nsError = error as NSError
-                switch nsError.code {
-                case 7: // no public key
-                    return SignatureState.NoPublicKey
-                case 8: // no signature
-                    return SignatureState.NoSignature
-                case 9: // unable to decrypt
-                    return SignatureState.InvalidSignature
-                default:
-                    return SignatureState.InvalidSignature
-                }
-            }
+    private func verifySignature(sigString: String, attachedSignature: Data?, keys: [Key]) -> SignatureState {
+        if let unarmored = try? Armor.readArmored(sigString){
+            return verifySignature(data: unarmored, attachedSignature: attachedSignature, keys: keys)
+        }
+        if let data = sigString.data(using: .utf8) {
+            return verifySignature(data: data, attachedSignature: attachedSignature, keys: keys)
         }
         return SignatureState.NoSignature
     }
     
+    private func verifySignature(data: Data, attachedSignature: Data?, keys: [Key]) -> SignatureState {
+        var sigData = data
+        var sigState = SignatureState.NoSignature
+        if let dataString = String(data: data, encoding: .utf8), let unarmored = try? Armor.readArmored(dataString){
+            sigData = unarmored
+        }
+        do{
+            if keys.isEmpty && attachedSignature != nil {
+                return SignatureState.NoPublicKey
+            }
+            try ObjectivePGP.verify(sigData, withSignature: attachedSignature, using: keys, passphraseForKey: loadPassword)
+            sigState = SignatureState.ValidSignature
+        } catch {
+            let nsError = error as NSError
+            switch nsError.code {
+            case 7: // no public key
+                sigState = SignatureState.NoPublicKey
+            case 8: // no signature
+                sigState = SignatureState.NoSignature
+            case 9: // unable to decrypt
+                sigState = SignatureState.InvalidSignature
+            default:
+                sigState = SignatureState.InvalidSignature
+            }
+        }
+        return sigState
+    }
     
     func vaildAddress(key: Key?) -> [String]{
         var adrs = [String]()
diff --git a/enzevalos_iphone/mail/IncomingMail.swift b/enzevalos_iphone/mail/IncomingMail.swift
new file mode 100644
index 00000000..3b98565c
--- /dev/null
+++ b/enzevalos_iphone/mail/IncomingMail.swift
@@ -0,0 +1,596 @@
+//
+//  IncomingMail.swift
+//  enzevalos_iphone
+//
+//  Created by Oliver Wiese on 06.03.19.
+//  Copyright © 2019 fu-berlin. All rights reserved.
+//
+
+import Foundation
+
+/**
+ We like to parse and store a mail.
+ We like to:
+    find public keys, secret keys
+    decrypt, decrypt and verify or verify a mail
+ */
+
+enum PGPPart {
+    case MESSAGE, PUBLICKEY, SIGNATURE, SECRETKEY;
+    
+    var start: String {
+        get {
+            return pgpBlock(start: true)
+        }
+    }
+    
+    var end: String {
+        get {
+            return pgpBlock(start: false)
+        }
+    }
+    
+    private func pgpBlock(start: Bool) -> String{
+        var type = "END"
+        if start {
+            type = "BEGIN"
+        }
+        switch self {
+        case .MESSAGE:
+            return "-----\(type) PGP MESSAGE-----"
+        case .PUBLICKEY:
+            return "-----\(type) PGP PUBLIC KEY BLOCK-----"
+        case .SIGNATURE:
+            return "-----\(type) PGP SIGNATURE-----"
+        case .SECRETKEY:
+            return "-----\(type) PGP SECRET KEY BLOCK-----"
+        }
+    }
+    
+    func findPGPPartInString(content: String) -> [String]{
+        var parts = [String]()
+        let startString = self.start
+        let endString = self.end
+        if content.contains(startString) {
+            if let start = content.range(of: startString) {
+                var end = content.range(of: endString+"\n")
+                if end == nil {
+                    end = content.range(of: endString)
+                }
+                if let end = end {
+                    let s = start.lowerBound
+                    let e = end.upperBound
+                    let part = content[s..<e]
+                    // We do not consider parts of previous mails.
+                    if !part.contains(">"){
+                        parts.append(String(part))
+                    }
+                }
+            }
+        }
+        return parts
+    }
+}
+
+enum PgpMIMEType {
+    case SIGNATURE, ENCRYPTED, OCTET, KEYS;
+    
+    static let allValues = [PgpMIMEType.ENCRYPTED, PgpMIMEType.KEYS, PgpMIMEType.OCTET, PgpMIMEType.SIGNATURE]
+    
+    var name: String {
+        get{
+            switch self {
+            case .SIGNATURE:
+                return "application/pgp-signature"
+            case .ENCRYPTED:
+                return "application/pgp-encrypted"
+            case .OCTET:
+                return "application/octet-stream"
+            case .KEYS:
+                return "application/pgp-keys"
+            }
+        }
+    }
+    
+    func isTypeOf(attachment: MCOAttachment) -> Bool {
+        return attachment.mimeType == self.name
+    }
+    
+    static func findType(attachment: MCOAttachment) -> PgpMIMEType? {
+        return findType(name: attachment.mimeType)
+    }
+    
+    static func findType(name: String) -> PgpMIMEType? {
+        for type in PgpMIMEType.allValues {
+            if type.name == name {
+                return type
+            }
+        }
+        return nil
+    }
+}
+
+class IncomingMail {
+    private let rawData: Data
+    private var msgParser: MCOMessageParser
+    private let firstParser: MCOMessageParser
+    // Header fields
+    private let flags: MCOMessageFlag
+    private let uID: UInt64
+    private let folderPath: String
+    
+    private var rec: [MCOAddress] = []
+    private var cc: [MCOAddress] = []
+    private var from: MCOAddress?
+    private var fromKeyIds: [String] {
+        get{
+            var keyIds: [String] = []
+            keyIds.append(contentsOf: newAutocrypPublicKeys)
+            keyIds.append(contentsOf: newPublicKeys)
+            if let fromAdr = from?.mailbox{
+                if let adr = DataHandler.handler.findMailAddress(adr: fromAdr) {
+                    for k in adr.publicKeys {
+                        keyIds.append(k.keyID)
+                    }
+                }
+            }
+            return keyIds
+        }
+    }
+    private var subject: String = ""
+    private var date: Date = Date()
+    private var autocrypt: Autocrypt? = nil
+    private var references: [String] = []
+    private var boundary: String?
+    private var msgID: String = ""
+    private var userAgent: String = ""
+    
+    
+    // Body info
+    private var secretKey: String? = nil
+    private var isEnc = false
+    private var html: String = ""
+    private var lineArray: [String] = []
+    private var cryptoObj: CryptoObject? = nil
+    private var body: String = ""
+    private var secretKeys: [String] = []
+    private var newPublicKeys: [String] = []
+    private var newAutocrypPublicKeys: [String] = []
+    
+    
+    // Crypto info
+    var cryptoData: Data {
+        get {
+            if let data = body.data(using: String.Encoding.utf8, allowLossyConversion: true) {
+                return data
+            }
+            return msgParser.data()
+        }
+    }
+    var decryptionKeyIDs: [String] {
+        get {
+            let secretkeys = DataHandler.handler.findSecretKeys()
+            var decIds = [String]()
+            for sk in secretkeys {
+                if let id = sk.keyID {
+                    decIds.append(id)
+                }
+            }
+            return decIds
+        }
+    }
+    
+    var primaryDecryptionKeyID: String? {
+        let sk = DataHandler.handler.prefSecretKey()
+        return sk.keyID
+    }
+    
+    var signatureKeyIDs: [String] {
+        get {
+            return fromKeyIds
+        }
+    }
+    
+    var signatureAddr: String? {
+        get {
+            if let adr = from?.mailbox {
+                return adr
+            }
+            return nil
+        }
+    }
+    
+    
+    init(rawData: Data, uID: UInt64, folderPath: String, flags: MCOMessageFlag){
+        self.rawData = rawData
+        self.uID = uID
+        self.folderPath = folderPath
+        self.flags = flags
+        self.firstParser = MCOMessageParser(data: rawData)
+        self.msgParser = firstParser
+        self.parseHeader()
+        self.parseBody()
+    }
+    
+    func store(keyRecord: KeyRecord?) -> PersistentMail? {
+        let sk = secretKeys.first //TODO FIX
+        let mail = DataHandler.handler.createMail(uID, sender: from, receivers: rec, cc: cc, time: date, received: true, subject: subject, body: body, flags: flags, record: keyRecord, autocrypt: autocrypt, decryptedData: cryptoObj, folderPath: folderPath, secretKey: sk)
+        if let m = mail {
+            let pgp = SwiftPGP()
+            if let autoc = autocrypt, let adr = from?.mailbox {
+                if let publickeys = try? pgp.importKeys(key: autoc.key, pw: nil, isSecretKey: false, autocrypt: true) {
+                    for pk in publickeys {
+                        _ = DataHandler.handler.newPublicKey(keyID: pk, cryptoType: CryptoScheme.PGP, adr: adr, autocrypt: true, firstMail: mail)
+                    }
+                }
+            }
+            if let adr = from?.mailbox {
+                for keyId in newPublicKeys {
+                    _ = DataHandler.handler.newPublicKey(keyID: keyId, cryptoType: CryptoScheme.PGP, adr: adr, autocrypt: false, firstMail: mail)
+                }
+            }
+            Logger.log(received: m)
+        }
+        return mail
+    }
+    
+    
+    
+    
+    
+    private func parseBody() {
+        var isEncrypted = false
+        var isSigned = false
+        var encData: Data?
+        var publicKeyRaw: [String] = []
+        var secretKeyRaw: [String] = []
+        var signaturesRaw: [String] = []
+        let pgp = SwiftPGP()
+        for a in msgParser.attachments() {
+            if let attachment = a as? MCOAttachment {
+                if let pgpType = PgpMIMEType.findType(attachment: attachment) {
+                    if pgpType == PgpMIMEType.ENCRYPTED {
+                        isEncrypted = true
+                    }
+                    else if pgpType == PgpMIMEType.OCTET {
+                        encData = attachment.data
+                    }
+                    else if pgpType == PgpMIMEType.SIGNATURE {
+                        isSigned = true
+                        signaturesRaw.append(contentsOf: IncomingMail.extractPGPSignature(attachment: attachment))
+                    }
+                    else {
+                        publicKeyRaw.append(contentsOf: IncomingMail.findPublicKeys(attachment: attachment))
+                        secretKeyRaw.append(contentsOf: IncomingMail.findSecretKeys(attachment: attachment))
+                    }
+                }
+            }
+        }
+        body = msgParser.plainTextBodyRenderingAndStripWhitespace(false)
+        publicKeyRaw.append(contentsOf:IncomingMail.extractPublicKeys(text: body))
+        secretKeyRaw.append(contentsOf:IncomingMail.extractSecretKeys(text: body))
+        if let encData = encData, isEncrypted {
+            // We drop plaintext keys.
+            publicKeyRaw = []
+            secretKeyRaw = []
+            msgParser = MCOMessageParser(data: encData)
+            prepareDecryption()
+            let cryptoObject = pgp.decrypt(mail: self)                
+            mergeCryptoObject(newCryptoObj: cryptoObject)
+            msgParser = MCOMessageParser(data: cryptoObject.decryptedData)
+            return parseBody()
+        }
+        else if isSigned {
+            
+            let signedStrings = extractSignedParts(data: msgParser.data())
+            //Signatur prüfen und dann mit Rest neu parsen??? Was wenn plainText?
+            var text: String?
+            var signedObject: CryptoObject?
+            if signedStrings.count == 1 {
+                text = signedStrings.first
+            }
+            else if signedStrings.count > 1 {
+                text = signedStrings.joined(separator: "\r\n")
+            }
+            if let signedData = text?.data(using: .utf8){
+                for sig in signaturesRaw {
+                    if let signature = sig.data(using: .utf8), let adr = from?.mailbox {
+                        for id in fromKeyIds {
+                            signedObject = pgp.verify(data: signedData, attachedSignature: signature, verifyId: id, fromAdr: adr)
+                            if let ob = signedObject, ob.signatureState == .ValidSignature {
+                                break
+                            }
+                        }
+                        if let signedObject = signedObject {
+                            mergeCryptoObject(newCryptoObj: signedObject)
+                            if signedObject.signatureState != .NoSignature {
+                                msgParser = MCOMessageParser(data: signedData)
+                                return parseBody()
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        else {
+            plainTextBody()
+            let chiphers = IncomingMail.extractInlinePGP(text: body)
+            // We consider only the first encrypted part! TODO: improve
+            if let text = chiphers.first, let data = text.data(using: .utf8) {
+                msgParser = MCOMessageParser(data: data)
+                let cryptoObject = pgp.decrypt(mail: self)
+                mergeCryptoObject(newCryptoObj: cryptoObject)
+                msgParser = MCOMessageParser(data: cryptoObject.decryptedData)
+                return parseBody()
+                
+            }
+        }
+        newPublicKeys = pgp.importKeys(keys: publicKeyRaw)
+        for sk in secretKeyRaw {
+            if let sks = try? pgp.importKeys(key: sk, pw: nil, isSecretKey: true, autocrypt: false){
+                secretKeys.append(contentsOf: sks)
+            }
+        }
+    }
+    
+    
+    private func mergeCryptoObject(newCryptoObj: CryptoObject) {
+        if let oldCrypto = cryptoObj {
+            var sigState = oldCrypto.signatureState
+            var encState = oldCrypto.encryptionState
+            var signKey = oldCrypto.signKey
+            var signedAddr = oldCrypto.signedAdrs
+            
+            if newCryptoObj.signatureState.rawValue > sigState.rawValue {
+                // TODO: What about dropped information? Users are confused?
+                sigState = newCryptoObj.signatureState
+                signKey = newCryptoObj.signKey
+                signedAddr = newCryptoObj.signedAdrs
+            }
+            if newCryptoObj.encryptionState.rawValue > encState.rawValue {
+                encState = newCryptoObj.encryptionState
+            }
+            cryptoObj = CryptoObject(chiphertext: oldCrypto.chiphertext, plaintext: newCryptoObj.plaintext, decryptedData: newCryptoObj.decryptedData, sigState: sigState, encState: encState, signKey: signKey, encType: newCryptoObj.encType, signedAdrs: signedAddr)
+        }
+        else {
+            cryptoObj = newCryptoObj
+        }
+        
+    }
+    
+    private func prepareDecryption() {
+        html = msgParser.plainTextRendering()
+        lineArray = html.components(separatedBy: "\n")
+        lineArray.removeFirst(4)
+        body = lineArray.joined(separator: "\n")
+        body = body.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
+        body.append("\n")
+    }
+    
+    private func plainTextBody() {
+        if let text = msgParser.plainTextBodyRenderingAndStripWhitespace(false) {
+            body = text
+            var c = body.first
+            while (c != nil && CharacterSet.whitespacesAndNewlines.contains((c?.unicodeScalars.first)!)) {
+                body.removeFirst()
+                c = body.first
+            }
+            c = body.last
+            while (c != nil && CharacterSet.whitespacesAndNewlines.contains((c?.unicodeScalars.first)!)) {
+                body.removeLast()
+                c = body.last
+            }
+        }
+    }
+    
+    private func parseHeader() {
+        if let header = msgParser.header {
+            if let refs = header.references {
+                for ref in refs{
+                    if let string = ref as? String {
+                        references.append(string)
+                    }
+                }
+            }
+            if let tos = header.to {
+                for r in tos{
+                    rec.append(r as! MCOAddress)
+                }
+            }
+            if let ccs = header.cc {
+                for r in ccs {
+                    cc.append(r as! MCOAddress)
+                }
+            }
+            
+            if let _ = header.extraHeaderValue(forName: Autocrypt.AUTOCRYPTHEADER){
+                let autocrypt = Autocrypt(header: header)
+                self.autocrypt = autocrypt
+                let pgp = SwiftPGP()
+                let keys = try? pgp.importKeys(key: autocrypt.key, pw: nil, isSecretKey: false, autocrypt: true)
+                if let keys = keys {
+                    newAutocrypPublicKeys = keys
+                }
+            }
+            if let _ = header.extraHeaderValue(forName: Autocrypt.SETUPMESSAGE) {
+                // TODO: Distinguish between other keys (future work)
+            }
+            if let f = header.from {
+                from = f
+            }
+            if let sub = header.subject {
+                subject = sub
+            }
+            if let d = header.date {
+                date = d
+            }
+            if let id = header.messageID {
+                msgID = id
+            }
+            if let agent = header.userAgent {
+                userAgent = agent
+            }
+            boundary = findBoundary()
+        }
+    }
+
+    
+    private func extractSignedParts(data: Data) -> [String] {
+        if let text = String(data: data, encoding: .utf8) {
+            return extractSignedParts(text: text)
+        }
+        return [String] ()
+    }
+    
+    private func extractSignedParts(text: String) -> [String] {
+        var parts: [String] = []
+        var boundary = IncomingMail.findBoundary(text: text)
+        if boundary == nil {
+            boundary = self.boundary
+        }
+        guard text.contains("Content-Type: multipart/signed") && boundary != nil  else {
+            return parts
+        }
+
+        parts = text.components(separatedBy: boundary!)
+        // If text contains a header -> we drop it
+        if let header = parts.first, IncomingMail.findBoundary(text: header) != nil {
+            parts = Array(parts.dropFirst())
+        }
+        parts = Array(parts.filter({(s: String ) -> Bool in
+            // A messages, where a signed part is signed again, are strange and verification can fail -> What about a response etc?
+            if s.contains(PGPPart.SIGNATURE.start) {
+                return false
+            }
+            return true
+        }))
+        
+        parts = Array(parts.map({(s: String) -> String in
+            // Convert strings according to RFC3156. See: https://tools.ietf.org/html/rfc3156 page 6
+            var newString = s.replacingOccurrences(of: "\r\n", with: "\n")
+            newString = newString.replacingOccurrences(of: "\n", with: "\r\n")
+            // Sometimes we lose tabs... TEST TODO
+            newString = newString.replacingOccurrences(of: "    charset", with: "\tcharset")
+            //TODO: Remove -- if last symbol
+            if newString.hasSuffix("--") {
+                newString = String(newString.dropLast(2))
+            }
+            else if newString.hasSuffix("--\r\n") {
+                newString = String(newString.dropLast(4))
+            }
+            if newString.hasPrefix("\r\n") {
+                newString = String(newString.dropFirst())
+            }
+            if newString.hasSuffix("\r\n") {
+                newString = String(newString.dropLast())
+            }
+            newString = newString.trimmingCharacters(in: .whitespaces)
+            return newString
+        }))
+        
+        parts = Array(parts.filter({(s: String ) -> Bool in
+            if s.isEmpty {
+                return false
+            }
+            return true
+        }))
+        return parts
+    }
+    
+    
+    
+    private func findBoundary() -> String? {
+        if let rawString = String.init(data: rawData, encoding:.utf8) {
+            return IncomingMail.findBoundary(text: rawString)
+        }
+        return nil
+    }
+    
+    func findSignedDataAndSignature(data: Data) -> (signedTexts: [String], signature: [String]) {
+        var sig: [String] = []
+        if let parser = MCOMessageParser.init(data: data) {
+            for part in parser.attachments() {
+                if let attachment = part as? MCOAttachment {
+                    let data = IncomingMail.extractPGPSignature(attachment: attachment)
+                    sig.append(contentsOf: data)
+                    // TODO: What about more signatures?
+                }
+            }
+        }
+        
+        return (extractSignedParts(data: data), sig)
+    }
+    
+    private static func importPublicKeys(attachment: MCOAttachment) -> [String] {
+        var newKey = [String]()
+        let pgp = SwiftPGP()
+        if let content = attachment.decodedString() {
+          newKey = pgp.importKeys(keys: PGPPart.PUBLICKEY.findPGPPartInString(content: content))
+        }
+        else if PgpMIMEType.KEYS.isTypeOf(attachment: attachment) {
+            if let keyIds = try? pgp.importKeys(data: attachment.data, pw: nil, secret: false) {
+                newKey.append(contentsOf: keyIds)
+            }
+        }
+        return newKey
+    }
+    
+    private static func findSecretKeys(attachment: MCOAttachment) -> [String] {
+        if let content = attachment.decodedString() {
+            return PGPPart.SECRETKEY.findPGPPartInString(content: content)
+        }
+        return []
+    }
+    
+    private static func findPublicKeys(attachment: MCOAttachment) -> [String] {
+        if let content = attachment.decodedString() {
+            return PGPPart.PUBLICKEY.findPGPPartInString(content: content)
+        }
+        return []
+    }
+    
+    private static func extractPublicKeys(text: String) -> [String] {
+        return PGPPart.PUBLICKEY.findPGPPartInString(content: text)
+        
+    }
+    
+    private static func extractSecretKeys(text: String) -> [String] {
+        return PGPPart.SECRETKEY.findPGPPartInString(content: text)
+        
+    }
+    
+    private static func extractInlinePGP(text: String) -> [String] {
+       return PGPPart.MESSAGE.findPGPPartInString(content: text)
+    }
+    
+    private static func extractPGPSignature(attachment: MCOAttachment) -> [String] {
+        if let content = String(data: attachment.data, encoding: .utf8) {
+            return PGPPart.SIGNATURE.findPGPPartInString(content: content)
+        }
+        return []
+    }
+
+    
+        
+    private static func findBoundary(text: String) -> String? {
+        let boundaries = matches(for: "boundary=.*;", in: text)
+        if let bound = boundaries.first {
+            let splitted = bound.split(separator: "\"")
+            if splitted.count == 3 {
+                return "--"+String(splitted[1]) as String
+            }
+        }
+        return nil
+    }
+    private static func matches(for regex: String, in text: String) -> [String] {
+        do {
+            let regex = try NSRegularExpression(pattern: regex)
+            let results = regex.matches(in: text, range: NSRange(text.startIndex..., in: text))
+            return results.map {
+                String(text[Range($0.range, in: text)!])
+            }
+        } catch {
+            return []
+        }
+    }
+}
diff --git a/enzevalos_iphoneTests/CoreDataTests.swift b/enzevalos_iphoneTests/CoreDataTests.swift
index 0f467544..97085653 100644
--- a/enzevalos_iphoneTests/CoreDataTests.swift
+++ b/enzevalos_iphoneTests/CoreDataTests.swift
@@ -264,12 +264,11 @@ class CoraDataTests: XCTestCase {
             XCTAssertTrue(myrecord.isSecure)
             XCTAssertEqual(myContact.publicKeys.count, 2)
             let cryptoObject2 = pgp.encrypt(plaintext: body, ids: [newKeyId], myId: keyID)
-            let decryptObject2 = pgp.decrypt(data: cryptoObject2.chiphertext!, decryptionIDs: [newKeyId], verifyIds: [keyID], fromAdr: sender.mailbox)
-
+            let decryptObject2 = pgp.decrypt(data: cryptoObject2.chiphertext!, decKeyIDs: [newKeyId], signatureIDs: [keyID], fromAddr: userAdr)
             _ = testMail(from: sender, to: [user], cc: [], bcc: [], folder: folderName, cryptoObject: decryptObject2)
 
             let cryptoObject3 = pgp.encrypt(plaintext: body, ids: [oldID], myId: keyID)
-            let decryptObject3 = pgp.decrypt(data: cryptoObject3.chiphertext!, decryptionIDs: [oldID], verifyIds: [keyID], fromAdr: sender.mailbox)
+            let decryptObject3 = pgp.decrypt(data: cryptoObject3.chiphertext!, decKeyIDs: [oldID], signatureIDs: [keyID], fromAddr: userAdr)
             let oldMail = testMail(from: sender, to: [user], cc: [], bcc: [], folder: folderName, cryptoObject: decryptObject3)
 
             XCTAssertTrue((oldMail?.decryptedWithOldPrivateKey)!)
diff --git a/enzevalos_iphoneTests/CryptoTests.swift b/enzevalos_iphoneTests/CryptoTests.swift
index 69f8ee17..d8eabec7 100644
--- a/enzevalos_iphoneTests/CryptoTests.swift
+++ b/enzevalos_iphoneTests/CryptoTests.swift
@@ -360,17 +360,15 @@ class CryptoTests: XCTestCase {
     let signedMessage = """
     -----BEGIN PGP SIGNATURE-----
 
-    iQGzBAEBCgAdFiEEJRxNIIPfYdSrprTDTbvambTX/SgFAlq5A9oACgkQTbvambTX
-    /SgIWwwAm1BTBjme8ogPdKcj2fyAzLjWPwttIW3nJN/tlB79TcId2sAAZK0hyhJQ
-    PU+j72x0IrgnJ0Vf40B9QU07RgLtdJPXXN1GWQPaz/69Wiut4T6mUusiqfE4RLiy
-    HJF7OYUNY6adteO1jCm0ZiZl3VW6XVomaXNuZtqXE+4U2k4WyQvaGbYMNvaaAYRf
-    vwYLyj/CO6++7lhYDet+A4OE5w0WcRHqrM4IRs/wF62cgBVl9cnonvl/2MTgR6DX
-    ewEcAeF+BmtMfVZhjEUa/zslLRTCRaxpVCq6BjHydakCTpZCJJTQcm+gVZrtQjl0
-    953zPJUfJ1/pvUextyKihT9a5itsxV2Tboq0mwD09M+hqWlHy0lQujI/hggcVvxE
-    DudoBwBZ4TilZyfRaSb9no1lJjxTZhwtsAvwOSPhRs3pGxkL9TS4GmqSsl8vZUBt
-    LBNFaFMvJfDXqmwIcW1Yl+apk7bWqY7yfTCgdRzhcqFDxdqhchNYvq4x035z4Udz
-    ZMarcccr
-    =OmRP
+    wsDcBAABCgAGBQJcgVq4AAoJEE272pm01/0o2Y0L/jS3UhX5ypJj1SKMVKWxHVW8CkzlHHsEtuhK
+    kkZs7sq9X8pqVGGeLjf+Bvz7dg5epAd76yD7M/hpHpEzAY+j4q0IjAQfkUApJIHnX303g9Xg2qC0
+    KymaoHV2iD7TfkGdCpoP4lmq9DVwQWOs6ixKThO9QjNJFjZRFfI7bQlH2dKg89JVpLfoK438fm3t
+    pNAmcf60wYCc2SI4zGaduyiLBIHR9XG4tb9Tc82Sf3tguBNHpmTvmiJFCL7ZZNWg8lQP2kDmPkds
+    Ugo602abhT64VBxi4YPXHw2tNApEtniMbn03X1Z/oPMNDN3m+/0YZU6+Fc0RwJ9SBHvGxLSXH9qc
+    PH1tdx4Bm1z1P+oQrD9vRbTqxLM6g5vk0bG/5Esa4f1/yQWto5LH0cZXVG2Ugy2x+4fYWCumMXDS
+    Vj+6SjTsZpctBji7OUYA2vMNXRdtOBCrYvEoq+Nm2eATp0zba+2kUVYY5HJqDMxepdBUKI+esXDZ
+    wnNopEkrmkzNWaQZou1QtQ==
+    =p/QU
     -----END PGP SIGNATURE-----
     """
 
@@ -485,7 +483,7 @@ class CryptoTests: XCTestCase {
             XCTFail("No data")
             return
         }
-        let cryptoObject = pgp.decrypt(data: data, decryptionId: userKeyID, verifyIds: [], fromAdr: nil)
+        let cryptoObject = pgp.decrypt(data: data, decKeyIDs: [userKeyID], signatureIDs: [], fromAddr: userAdr)
         XCTAssert(cryptoObject.encryptionState == .NoEncryption)
         XCTAssert(cryptoObject.signatureState == .NoSignature)
         XCTAssert(cryptoObject.decryptedData == nil && cryptoObject.decryptedText == nil && cryptoObject.signKey == nil)
@@ -502,7 +500,7 @@ class CryptoTests: XCTestCase {
             XCTFail("No chipher data")
             return
         }
-        let cryptoObject = pgp.decrypt(data: data, decryptionId: userKeyID, verifyIds: [], fromAdr: nil)
+        let cryptoObject = pgp.decrypt(data: data, attachedSignature: nil, decKeyIDs: [userKeyID], signatureIDs: [], fromAddr: userAdr)
         XCTAssert(cryptoObject.encryptionState == .ValidedEncryptedWithCurrentKey)
         XCTAssert(cryptoObject.signatureState == .NoSignature)
         XCTAssert(cryptoObject.plaintext == body && cryptoObject.plaintext == cryptoObject.decryptedText)
@@ -520,13 +518,18 @@ class CryptoTests: XCTestCase {
         }
 
         // 1. case: correct signed mail
-        var cryptoObject = pgp.decrypt(data: signedData, decryptionId: keys.first, verifyIds: keys, fromAdr: nil)
-        XCTAssert(cryptoObject.encryptionState == .NoEncryption && cryptoObject.signatureState == .ValidSignature)
-        XCTAssert(cryptoObject.decryptedText == "only a signed mail!")
-
-        // 2. case: manipulated mail
-        cryptoObject = pgp.decrypt(data: manipulatedDate, decryptionId: keys.first, verifyIds: keys, fromAdr: nil)
-        XCTAssert(cryptoObject.encryptionState == .NoEncryption && cryptoObject.signatureState == .InvalidSignature)
+        let text = "only a signed mail!"
+        if let data = text.data(using: .utf8) {
+            var cryptoObject = pgp.decrypt(data: data, attachedSignature: signedData, decKeyIDs: [userKeyID], signatureIDs: keys, fromAddr: "alice@enzevalos.de")
+            XCTAssert(cryptoObject.encryptionState == .NoEncryption && cryptoObject.signatureState == .ValidSignature)
+            XCTAssert(cryptoObject.chiperString == text)
+            // 2. case: manipulated mail
+            cryptoObject = pgp.decrypt(data: data, attachedSignature: manipulatedDate, decKeyIDs: keys, signatureIDs: keys, fromAddr: "alice@enzevalos.de")
+            XCTAssert(cryptoObject.encryptionState == .NoEncryption && cryptoObject.signatureState == .InvalidSignature)
+        }
+        else {
+            XCTFail("Can not make String to data.")
+        }
     }
 
     func testEncSignedMail() {
@@ -537,30 +540,29 @@ class CryptoTests: XCTestCase {
         let senderPGP = SwiftPGP()
         let encObject = senderPGP.encrypt(plaintext: body, ids: [userKeyID], myId: senderID)
         XCTAssert(encObject.encryptionState == .ValidedEncryptedWithCurrentKey && encObject.signatureState == SignatureState.ValidSignature)
-        let falseEncObject = senderPGP.encrypt(plaintext: body, ids: [], myId: senderID)
+        let falseEncObject = senderPGP.encrypt(plaintext: body, ids: [id2], myId: senderID)
 
         guard let data = encObject.chiphertext, let data2 = falseEncObject.chiphertext else {
             XCTFail("no chipher data")
             return
         }
         // 1. case: signed but no public key available to verify signature
-        var cryptoObject = pgp.decrypt(data: data, decryptionId: userKeyID, verifyIds: [], fromAdr: nil)
+        var cryptoObject = pgp.decrypt(data: data, attachedSignature: nil, decKeyIDs: [userKeyID], signatureIDs: [], fromAddr: userAdr)
         XCTAssert(cryptoObject.encryptionState == .ValidedEncryptedWithCurrentKey)
-        XCTAssert(cryptoObject.signatureState == .NoPublicKey)
+        XCTAssert(cryptoObject.signatureState != .ValidSignature) // No PK
         XCTAssert(cryptoObject.plaintext == body && cryptoObject.plaintext == cryptoObject.decryptedText)
-
         // 2. case: signed and public key available
-        cryptoObject = pgp.decrypt(data: data, decryptionId: userKeyID, verifyIds: [senderID, id2], fromAdr: nil)
+        cryptoObject = pgp.decrypt(data: data, attachedSignature: nil, decKeyIDs: [userKeyID], signatureIDs: [senderID, id2], fromAddr: senderAddress.mailbox)
         XCTAssert(cryptoObject.signatureState == .ValidSignature)
         XCTAssert(cryptoObject.signKey == senderID)
         XCTAssert(cryptoObject.signedAdrs.contains(senderAddress.mailbox) && cryptoObject.signedAdrs.count == 1)
 
         // 3. case: signed and check with wrong key
-        cryptoObject = pgp.decrypt(data: data, decryptionId: userKeyID, verifyIds: [id2], fromAdr: nil)
-        XCTAssert(cryptoObject.signatureState == .NoPublicKey)
+        cryptoObject = pgp.decrypt(data: data, decKeyIDs: [userKeyID], signatureIDs: [id2], fromAddr: senderAddress.mailbox)
+        XCTAssert(cryptoObject.signatureState != .ValidSignature)
 
         // 4. case: can not decrypt (wrong/missing decryption/encryption key)
-        cryptoObject = pgp.decrypt(data: data2, decryptionId: userKeyID, verifyIds: [senderID], fromAdr: nil)
+        cryptoObject = pgp.decrypt(data: data2, decKeyIDs: [userKeyID], signatureIDs: [senderID], fromAddr: senderAddress.mailbox)
         XCTAssert(cryptoObject.encryptionState == .UnableToDecrypt && cryptoObject.signatureState == .NoSignature)
 
         // 5. case: used old key to encrypt message
@@ -572,7 +574,7 @@ class CryptoTests: XCTestCase {
         XCTAssertEqual(keys.count, 1)
         _ = datahandler.newSecretKeys(keyIds: keys, addPKs: true)
         XCTAssertEqual(keys.first, datahandler.prefSecretKey().keyID)
-        cryptoObject = pgp.decrypt(data: data, decryptionId: userKeyID, verifyIds: [senderID], fromAdr: nil)
+        cryptoObject = pgp.decrypt(data: data, decKeyIDs: [userKeyID], signatureIDs: [senderID], fromAddr: senderAddress.mailbox)
         XCTAssertEqual(keys.first, datahandler.prefSecretKey().keyID)
         XCTAssert(cryptoObject.encryptionState == .ValidEncryptedWithOldKey && cryptoObject.signatureState == .ValidSignature)
         XCTAssert(cryptoObject.decryptedText == body)
diff --git a/enzevalos_iphoneTests/MailTest.swift b/enzevalos_iphoneTests/MailTest.swift
index 1a48d4a3..3b4f158b 100644
--- a/enzevalos_iphoneTests/MailTest.swift
+++ b/enzevalos_iphoneTests/MailTest.swift
@@ -82,9 +82,10 @@ class MailTest: XCTestCase {
         let subject = "subject"
         let body = "This is the body"
         let outMail = OutgoingMail(toEntrys: tos, ccEntrys: ccs, bccEntrys: bccs, subject: subject, textContent: body, htmlContent: nil)
-        if let parser = MCOMessageParser(data: outMail.plainData) {
+        if let data = outMail.plainData {
             // Test parsing!
-            if let mail = mailHandler.parseMail(parser: parser, record: nil, folderPath: "INBOX", uid: 0, flags: MCOMessageFlag.seen){
+            let incMail = IncomingMail(rawData: data, uID: 0, folderPath: "INBOX", flags: MCOMessageFlag.init(rawValue: 0))
+            if let mail = incMail.store(keyRecord: nil){
                 XCTAssertTrue(MailTest.compareAdrs(adrs1: tos, adrs2: mail.getReceivers()))
                 XCTAssertTrue(MailTest.compareAdrs(adrs1: ccs, adrs2: mail.getCCs()))
                 XCTAssertTrue(mail.getBCCs().count == 0)
@@ -120,9 +121,10 @@ class MailTest: XCTestCase {
         https certs will be valid – Microsoft signed.
         """
         let outMail = OutgoingMail(toEntrys: tos, ccEntrys: ccs, bccEntrys: bccs, subject: subject, textContent: body, htmlContent: nil)
-        if let parser = MCOMessageParser(data: outMail.plainData) {
+        if let data = outMail.plainData {
             // Test parsing!
-            if let mail = mailHandler.parseMail(parser: parser, record: nil, folderPath: "INBOX", uid: 0, flags: MCOMessageFlag.seen){
+            let incMail = IncomingMail(rawData: data, uID: 0, folderPath: "INBOX", flags: MCOMessageFlag.init(rawValue: 0))
+            if let mail = incMail.store(keyRecord: nil){
                 XCTAssertEqual(subject, mail.subject)
                 XCTAssertEqual(body, mail.body)
             }
@@ -143,8 +145,9 @@ class MailTest: XCTestCase {
         let body = "body"
         _ = createPGPUser(adr: encAdr, name: encAdr)
         let outMail = OutgoingMail(toEntrys: [encAdr], ccEntrys: [], bccEntrys: [], subject: subject, textContent: body, htmlContent: nil)
-        if let parser = MCOMessageParser(data: outMail.pgpData){
-            if let mail = mailHandler.parseMail(parser: parser, record: nil, folderPath: "INBOX", uid: 1, flags: MCOMessageFlag.seen) {
+        if let data = outMail.pgpData{
+            let incMail = IncomingMail(rawData: data, uID: 1, folderPath: "INBOX", flags: MCOMessageFlag.init(rawValue: 0))
+            if let mail = incMail.store(keyRecord: nil) {
                 XCTAssertEqual(body, mail.body)
                 XCTAssertTrue(mail.isSecure)
             }
@@ -164,8 +167,9 @@ class MailTest: XCTestCase {
         let body = "body"
         _ = createPGPUser(adr: encAdr, name: encAdr)
         let outMail = OutgoingMail(toEntrys: [plainAdr, encAdr], ccEntrys: [], bccEntrys: [], subject: subject, textContent: body, htmlContent: nil)
-        if let secureParser = MCOMessageParser(data: outMail.pgpData) {
-            if let mail = mailHandler.parseMail(parser: secureParser, record: nil, folderPath: "INBOX", uid: 2, flags: MCOMessageFlag.seen) {
+        if let data = outMail.pgpData {
+            let incMail = IncomingMail(rawData: data, uID: 2, folderPath: "INBOX", flags: MCOMessageFlag.init(rawValue: 0))
+            if let mail = incMail.store(keyRecord: nil){
                 XCTAssertEqual(body, mail.body)
                 XCTAssertTrue(mail.isSecure)
                 XCTAssertTrue(MailTest.compareAdrs(adrs1: [encAdr, plainAdr], adrs2: mail.getReceivers()))
@@ -177,8 +181,10 @@ class MailTest: XCTestCase {
         else {
             XCTFail()
         }
-        if let insecureParser = MCOMessageParser(data: outMail.plainData) {
-            if let mail = mailHandler.parseMail(parser: insecureParser, record: nil, folderPath: "INXBO", uid: 3, flags: MCOMessageFlag.seen) {
+        if let data = outMail.plainData {
+            let incMail = IncomingMail(rawData: data, uID: 3, folderPath: "INBOX", flags: MCOMessageFlag.init(rawValue: 0))
+
+            if let mail = incMail.store(keyRecord: nil) {
                 XCTAssertEqual(body, mail.body)
                 XCTAssertFalse(mail.isSecure)
                 XCTAssertTrue(MailTest.compareAdrs(adrs1: [plainAdr, encAdr], adrs2: mail.getReceivers()))
@@ -232,23 +238,22 @@ class MailTest: XCTestCase {
     func testMailAliceToBob(pkExists: Bool, name: String, isSecure: Bool, encState: EncryptionState? = nil, sigState: SignatureState? = nil) {
         let mailData = MailTest.loadMail(name: name )
         let (alice, _) = addAliceAndBob(addAlice: pkExists)
-        if let parser = MCOMessageParser(data: mailData) {
-            if let mail = mailHandler.parseMail(parser: parser, record: nil, folderPath: "INBOX", uid: 0, flags: MCOMessageFlag.seen) {
-                XCTAssertEqual(mail.isSecure, isSecure)
-                if mail.isSecure || mail.sigState == .ValidSignature{
-                    XCTAssertEqual(mail.signedKey?.keyID, alice)
-                    XCTAssertEqual(mail.keyID, alice)
-                }
-                if let encState = encState {
-                    XCTAssertEqual(mail.encState, encState)
-                }
-                if let sigState = sigState {
-                    XCTAssertEqual(mail.sigState, sigState)
-                }
-                let body = mail.body
-                XCTAssertEqual(body.removeNewLines(), MailTest.body.removeNewLines())
-                XCTAssertTrue(MailTest.compareAdrs(adrs1: ["bob@enzevalos.de"], adrs2: mail.getReceivers()))
+        let incMail = IncomingMail(rawData: mailData, uID: 4, folderPath: "INBOX", flags: MCOMessageFlag.init(rawValue: 0))
+        if let mail = incMail.store(keyRecord: nil) {
+            XCTAssertEqual(mail.isSecure, isSecure)
+            if mail.isSecure || mail.sigState == .ValidSignature{
+                XCTAssertEqual(mail.signedKey?.keyID, alice)
+                XCTAssertEqual(mail.keyID, alice)
+            }
+            if let encState = encState {
+                XCTAssertEqual(mail.encState, encState)
+            }
+            if let sigState = sigState {
+                XCTAssertEqual(mail.sigState, sigState)
             }
+            let body = mail.body
+            XCTAssertEqual(body.removeNewLines(), MailTest.body.removeNewLines())
+            XCTAssertTrue(MailTest.compareAdrs(adrs1: ["bob@enzevalos.de"], adrs2: mail.getReceivers()))
         }
         else {
             XCTFail()
@@ -258,7 +263,8 @@ class MailTest: XCTestCase {
     func addAliceAndBob(addAlice: Bool) -> (alice: String, bob: String){
         let aliceKeyId = importKey(file: "alicePublic", isSecretKey: false)
         if addAlice {
-            _ = datahandler.newPublicKey(keyID: aliceKeyId, cryptoType: .PGP, adr: "alice@enzevalos.de", autocrypt: true)
+            let b = datahandler.newPublicKey(keyID: aliceKeyId, cryptoType: .PGP, adr: "alice@enzevalos.de", autocrypt: true)
+            print(b.keyID)
         }
         let bobKeyId = importKey(file: "bobSecret", isSecretKey: true)
         _ = datahandler.newSecretKey(keyID: bobKeyId, addPk: true)
@@ -327,6 +333,7 @@ class MailTest: XCTestCase {
     func createPGPUser(adr: String = String.random().lowercased(), name: String = String.random()) -> (MCOAddress, String) {
         let user = createUser(adr: adr, name: name)
         let id = pgp.generateKey(adr: user.mailbox)
+        print(id)
         return (user, id)
     }
     
-- 
GitLab