diff --git a/enzevalos_iphone.xcodeproj/project.pbxproj b/enzevalos_iphone.xcodeproj/project.pbxproj
index 5bfacc2b5401ceb4d60b4be6b3c465a68f4e6970..dc98cc1030fdfbabfe5e36cb0aba5c9cef32761f 100644
--- a/enzevalos_iphone.xcodeproj/project.pbxproj
+++ b/enzevalos_iphone.xcodeproj/project.pbxproj
@@ -769,9 +769,9 @@
 		0ECEA101240EA905007DC71E /* SMIME */ = {
 			isa = PBXGroup;
 			children = (
-				0ECA5797240D496800B0F231 /* SMIME.swift */,
-				A5E303D524110F6400310264 /* c */,
 				0EF148042422543E00B3C198 /* Certificate.swift */,
+				A5E303D524110F6400310264 /* c */,
+				0ECA5797240D496800B0F231 /* SMIME.swift */,
 				0EF73F4224237E6500932FA0 /* SMIMEHelpers.swift */,
 			);
 			name = SMIME;
diff --git a/enzevalos_iphone/SMIME.swift b/enzevalos_iphone/SMIME.swift
index 6fb937aa549a7ef1573a22e8efac499d7bf4389a..84faaa522ca08cb543cff1f3d9cfbdef4e6c7f63 100644
--- a/enzevalos_iphone/SMIME.swift
+++ b/enzevalos_iphone/SMIME.swift
@@ -213,6 +213,95 @@ AYIHvW6qRLTsSR6BZZS3pqGXYue7fE0vj4HJ2IEpj05qQ5RXrD57Wg==
 -----END RSA PRIVATE KEY-----
 """
      
+    let att_sig_invalid = """
+MIME-Version: 1.0
+Content-Disposition: attachment; filename="smime.p7m"
+Content-Type: application/pkcs7-mime; smime-type=signed-data; name="smime.p7m"
+Content-Transfer-Encoding: base64
+
+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
+AAAA
+"""
+    
+    let det_sig_invalid = """
+------56F3BC21B2CE83EB9E02E24139D860BC
+Hello world whatever the fuckaaDadaDAd
+------56F3BC21B2CE83EB9E02E24139D860BC
+Content-Type: application/pkcs7-signature; name="smime.p7s"
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment; filename="smime.p7s"
+
+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
+N8GVQGtc+3uaNA==
+
+------56F3BC21B2CE83EB9E02E24139D860BC--
+"""
+    
     let enc_test_key =
 """
 -----BEGIN ENCRYPTED PRIVATE KEY-----
@@ -394,7 +483,7 @@ PkfA6mR7rtcyIbHi34tfkCv/qolV3QivMHov0IJpRyNO
         let fp = addPrivateKey(keyPlusCertPEM: test_key)
         let cert = certsKeychain[privateKeyKeychain["ownkey"]!]!
         let key = privateKeyKeychain[privateKeyKeychain["ownkey"]!]!
-        
+        /*
         let (enc, enc_errs) = encryptWithPem(message: test_string, certPems: [test_key_other, cert])
         if enc != nil {
             // the pointers point to memory allocatedi in c that needs to be manually dealocated
@@ -425,7 +514,7 @@ PkfA6mR7rtcyIbHi34tfkCv/qolV3QivMHov0IJpRyNO
         print("subject", certObj.subject ?? "")
         print("startDate", certObj.startDate ?? "")
         print("endDate", certObj.endDate ?? "")
-        
+        */
         let (sig, sigErr) = signWithPem(message: test_string, certAsPem: cert, keyAsPem: key, detached: false)
         if sig != nil{
             // the pointers point to memory allocatedi in c that needs to be manually dealocated
@@ -434,6 +523,15 @@ PkfA6mR7rtcyIbHi34tfkCv/qolV3QivMHov0IJpRyNO
         else{
             print("\n SWIFT SIGN1 failed")
         }
+        
+        if sigErr != nil
+        {
+            print("sig errors!")
+            for x in sigErr ?? [] {
+                print("errorstring: ",getErrorString(errCode: x))
+            }
+        }
+        
         let (sig2, sig2Err) = signWithPem(message: test_string, certAsPem: cert, keyAsPem: key, detached: true)
         if sig2 != nil{
             // the pointers point to memory allocatedi in c that needs to be manually dealocated
@@ -442,24 +540,40 @@ PkfA6mR7rtcyIbHi34tfkCv/qolV3QivMHov0IJpRyNO
         else{
             print("\n SWIFT SIGN2 failed")
         }
+        
+        if sig2Err != nil
+        {
+            print("sig errors!")
+            for x in sig2Err ?? [] {
+                print("errorstring: ",getErrorString(errCode: x))
+            }
+        }
 
         var CAs : [String] = []
         for k in CAKeychain.allKeys()
         {
             CAs.append(CAKeychain[k]!)
         }
-        let (vertest, certs,verErrs) = verifyWithCApem(message: sig!, pemCAArr: CAs )
+        
+        let (vertest, certs,verErrs) = verifyWithCApem(message: sig!, pemCAArr: [testEvilCA])
         if vertest != nil
         {
             print("In Verification", vertest!)
-            print(certs ?? "No certs")
-            for x in verErrs ?? [] {
-                 print("errorstring: ",getErrorString(errCode: x))
-             }
         }
         else{
             print("Vertest was nil")
         }
+        
+        print(certs ?? "No certs")
+        
+        if verErrs != nil
+        {
+            print("ver errors!")
+            for x in verErrs ?? [] {
+                print("error code: ", x)
+                print("error string: ",getErrorString(errCode: x))
+            }
+        }
         /*
         let (fpTestKey, _, _) = getFingerprintFromPem(pem: test_key)
         if (fpTestKey != nil) {
@@ -473,6 +587,56 @@ PkfA6mR7rtcyIbHi34tfkCv/qolV3QivMHov0IJpRyNO
          */
     }
     
+    func testVerification() {
+        var CAs : [String] = []
+        for k in CAKeychain.allKeys()
+        {
+            CAs.append(CAKeychain[k]!)
+        }
+        
+        let (vertest, certs,verErrs) = verifyWithCApem(message: att_sig_invalid, pemCAArr: CAs)
+        if vertest != nil
+        {
+            print("Verification attacthed sig", vertest!)
+        }
+        else{
+            print("Verification attacthed sig")
+        }
+        
+        print(certs ?? "No certs")
+        
+        if verErrs != nil
+        {
+            print("SWIFT errors!")
+            for x in verErrs ?? [] {
+                print("error code: ", x)
+                print("error string: ", getErrorString(errCode: x))
+                print("error reason: ", getErrorReasonString(errCode: x))
+            }
+        }
+        
+        let (vertestDet, certsDet, verErrsDet) = verifyWithCApem(message: det_sig_invalid, pemCAArr: CAs)
+        if vertestDet != nil
+        {
+            print("Verification dettached sig", vertestDet!)
+        }
+        else{
+            print("Verification dettached sig")
+        }
+        
+        print(certsDet ?? "No certs")
+        
+        if verErrsDet != nil
+        {
+            print("SWIFT errors")
+            for x in verErrsDet ?? [] {
+                print("error code: ", x)
+                print("error string: ", getErrorString(errCode: x))
+                print("error reason: ", getErrorReasonString(errCode: x))
+            }
+        }
+    }
+    
     func testCryptoObjectMethods() {
         
     }
@@ -505,35 +669,16 @@ PkfA6mR7rtcyIbHi34tfkCv/qolV3QivMHov0IJpRyNO
     }
     
     // Note: we ignore the Encryption interface because some things are built with PGP in mind and make no sense in the context of SMIME (signatureIDs for example)
-    func decrypt(data: Data, fromAddr: String, ownId:String, isMailNew: Bool) -> CryptoObject? {
-        // NOTE TO SELF: Implement verify with CryptoObject BEFORE decrypt
-        let (sigState, certsWithFps) = verify(data: data, email: fromAddr, isMailNew: isMailNew)!
-        
+    func decrypt(data: Data, fromAddr: String, ownId:String, isMailNew: Bool) throws -> CryptoObject {
         var outputData: Data = data
         let text = String(data: data, encoding: .utf8)!
-        let fp = getOwnKeyFP()
+        var fp = getOwnKeyFP()
         let cert = certsKeychain[fp!]!
         let key = privateKeyKeychain[fp!]!
-        
-        let certObjects = certsWithFps.map( { (arg) -> Certificate in
-            let (_, pem) = arg
-            return Certificate(pem: pem)
-        })
-        
-        var addrs : [String:Bool] = [:]
-        for c in certObjects
-        {
-            for e in c.eMails!
-            {
-                addrs[e] = true
-            }
-        }
-        
-        let addresses : [String] = Array(addrs.keys)
-        
+                
         var (decStr, errArr) = decryptWithPem(message: text, certAsPem: cert, keyAsPem: key)
-        var encState : EncryptionState = EncryptionState.UnableToDecrypt
-        if decStr != nil{
+        var encState = EncryptionState.UnableToDecrypt
+        if decStr != nil && (errArr == nil || errArr!.count == 0) {
             encState = EncryptionState.ValidedEncryptedWithCurrentKey
         }
         else
@@ -543,6 +688,7 @@ PkfA6mR7rtcyIbHi34tfkCv/qolV3QivMHov0IJpRyNO
                 if f != fp{
                     (decStr, errArr) = decryptWithPem(message: text, certAsPem: certsKeychain[f]!, keyAsPem: privateKeyKeychain[f]!)
                     if decStr != nil{
+                        fp = f
                         encState = EncryptionState.ValidEncryptedWithOldKey
                         break
                     }
@@ -554,11 +700,22 @@ PkfA6mR7rtcyIbHi34tfkCv/qolV3QivMHov0IJpRyNO
             outputData = decStr!.data(using: .utf8)!
         }
         
+        /**
+         we have tried to decrypt with our current key and with our older keys and if all of that failed then:
+            * the email wasn't meant for us and we shouldn't be able to decrypt it anyway
+            * there is something wrong with the e-mail
+        */
         if (errArr != nil && errArr!.count > 0) {
-            // TODO: Exception
-            return nil
+            throw SMIMEError(message: "Decryption failed!", errorArray: errArr, type: SMIMEError.ErrorType.decryption)
         }
         
+        let (sigState, certsWithFps, sigStr) = verify(data: outputData, email: fromAddr, isMailNew: isMailNew)
+        
+        let addresses = getAllEmailsFromPEMs(certs: certsWithFps.map( { (arg) -> String in
+            let (_, pem) = arg
+            return pem
+        }))
+        
         return CryptoObject(chiphertext: data, plaintext: String(data: outputData, encoding: .utf8), decryptedData: outputData, sigState: sigState, encState: encState, signKey: fp, encType: CryptoScheme.SMIME, signedAdrs: sigState == SignatureState.ValidSignature ? addresses : [])
     }
     
@@ -576,8 +733,15 @@ PkfA6mR7rtcyIbHi34tfkCv/qolV3QivMHov0IJpRyNO
         return CryptoObject(chiphertext: sigText!.data(using: .utf8), plaintext: text, decryptedData: plainData, sigState: SignatureState.ValidSignature, encState: EncryptionState.NoEncryption, signKey: fp, encType: CryptoScheme.SMIME, signedAdrs: [myEmail])
     }
     
-    // If multiple signatures are present, ALL need to be valid AND have a matching mail address, else the signature is invalid. 
-    func verify(data: Data, email: String, isMailNew: Bool) -> (SignatureState, [(String, String)])? {
+    /**
+     Verifies the signature of a signed message. If multiple signatures are present, ALL need to be valid AND have a matching mail address, else the signature is invalid. The exceptions are in part modelled after the way OpenSSL deals with verification
+    
+     - returns:
+        * SignatureState
+        * An array of (<fingerprint>, <pem>) tuples
+        * the verified string
+     */
+    func verify(data: Data, email: String, isMailNew: Bool) -> CryptoObject {
         var CAs : [String] = []
         CAKeychain.allKeys().forEach({ (key) in
             CAs.append(CAKeychain[key]!)
@@ -585,55 +749,74 @@ PkfA6mR7rtcyIbHi34tfkCv/qolV3QivMHov0IJpRyNO
         let text = String(data: data, encoding: .utf8)!
         
         let (verStr, certsFPArr, errArr) = verifyWithCApem(message: text, pemCAArr: CAs)
-        if certsFPArr != nil {
-            var newCerts: [String] = [] // all certs that came from the email and weren't available before
-            var mailMatch = true
-            if certsFPArr?.count == 0 {mailMatch = false}
-            for item in certsFPArr! {
-                var mailFound = false
-                let (fp, cert) = item
-                let certObj = Certificate(pem: cert)
-                // check if the email from the parameters matches with one of the emails in each of the certs used to sign the message
-                for addr in certObj.eMails ?? [] {
-                    if addr == email {
-                        mailFound = true
-                        break
-                    }
-                }
-                mailMatch = mailFound && mailMatch
-                // check if cert is already in the keychain
-                if let _ = try? certsKeychain.get(fp) {
-                    continue
+        
+        if certsFPArr == nil || certsFPArr!.count == 0 {
+            let errors = errArr!
+            
+            for error in errors {
+                let reason = getErrorReasonString(errCode: error)
+                print("reason:", reason)
+                // check reasons to identify different error causes
+                // string comaprison necessary because doesn't have fixed error codes...
+                if reason == "no content type" {
+                    return CryptoObject(chiphertext: data, plaintext: text, decryptedData: nil, sigState: .NoSignature, encState: EncryptionState.NoEncryption, signKey: nil, encType: .UNKNOWN, signedAdrs: [])
                 }
-                newCerts.append(cert)
             }
             
-            let fps = importCerts(certs: newCerts)
-            // check if the email has no certificate or the certificate is newer than the present one and update accordingly
-            for fp in fps{
-                let cert = Certificate(pem: certsKeychain[fp]!)
-                for email in cert.eMails ?? []
+            return CryptoObject(chiphertext: data, plaintext: text, decryptedData: nil, sigState: .InvalidSignature, encState: EncryptionState.NoEncryption, signKey: nil, encType: .UNKNOWN, signedAdrs: [])
+        }
+        
+        var newCerts: [String] = [] // all certs that came from the email and weren't available before
+        var mailMatch = true
+        if certsFPArr?.count == 0 {mailMatch = false}
+        
+        for item in certsFPArr! {
+            var mailFound = false
+            let (fp, cert) = item
+            let certObj = Certificate(pem: cert)
+            // check if the email from the parameters matches with one of the emails in each of the certs used to sign the message
+            for addr in certObj.eMails ?? [] {
+                if addr == email {
+                    mailFound = true
+                    break
+                }
+            }
+            mailMatch = mailFound && mailMatch
+            // check if cert is already in the keychain
+            if let _ = try? certsKeychain.get(fp) {
+                continue
+            }
+            newCerts.append(cert)
+        }
+        
+        let fps = importCerts(certs: newCerts)
+        // check if the email has no certificate or the certificate is newer than the present one and update accordingly
+        for fp in fps{
+            let cert = Certificate(pem: certsKeychain[fp]!)
+            for email in cert.eMails ?? []
+            {
+                if isMailNew || certsKeychain[email] == nil
                 {
-                    if isMailNew || certsKeychain[email] == nil
-                    {
-                        certsKeychain[email] = fp
-                    }
+                    certsKeychain[email] = fp
                 }
             }
-            
-            let sigState = mailMatch ? SignatureState.ValidSignature : SignatureState.InvalidSignature
-            
-            return (sigState, certsFPArr!)
         }
         
-        return nil
-        // TODO: Exception no valid signatures
+        let sigState = mailMatch ? SignatureState.ValidSignature : SignatureState.InvalidSignature
+        
+        let signedAddresses = getAllEmailsFromPEMs(certs: certsFPArr!.map( { (arg) -> String in
+            let (_, pem) = arg
+            return pem
+        }))
+        
+        return CryptoObject(chiphertext: data, plaintext: verStr!, decryptedData: nil, sigState: sigState, encState: EncryptionState.NoEncryption, signKey: nil, encType: .SMIME, signedAdrs: signedAddresses)
     }
     
     func encrypt(plainData: Data, ids: [String], ownId: String, encryptForMyId: Bool = true) throws -> CryptoObject {
-        let text = String(data: plainData, encoding: .utf8)
+        let plainText = String(data: plainData, encoding: .utf8)
+        var (sigText, sigErrArr): (String?, [UInt]?) = (nil, nil)
         var pems: [String] = []
-        var ownFp: String? = nil
+        let ownFp: String? = getOwnKeyFP()
         
         // retrieve the certs as pems for each ID (email), certsKeychain stores for each email a fingerprint of the cert of that user and under a fingerprint a cert is stored
         for id in ids {
@@ -641,41 +824,41 @@ PkfA6mR7rtcyIbHi34tfkCv/qolV3QivMHov0IJpRyNO
                 pems.append(certsKeychain[fp]!)
             }
             else{
-                throw SMIMEError(message: "No cert for email " + id + "!", errorArray: nil, type: SMIMEError.ErrorType.encryption)
+                throw SMIMEError(message: "No cert for email " + id + "!", errorArray: nil, type: SMIMEError.ErrorType.other)
             }
         }
         
         // if we want to encrypt with the user's own key, retrieve the key and handle errors
         if encryptForMyId {
-            if let fp = getOwnKeyFP() {
-                ownFp = fp
-                pems.append(certsKeychain[fp]!)
+            if ownFp != nil {
+                pems.append(certsKeychain[ownFp!]!)
             }
             else {
-                throw SMIMEError(message: "Tried to encrypt email with the user's key but no cert for own key present!", errorArray: nil, type: SMIMEError.ErrorType.encryption)
+                throw SMIMEError(message: "Tried to encrypt email with the user's key but no cert for own key present!", errorArray: nil, type: SMIMEError.ErrorType.other)
             }
         }
         
-        // do the actual encryption
-        let (encStr, errArr) = encryptWithPem(message: text!, certPems: pems)
-        if errArr != nil && errArr!.count > 0 {
-            throw SMIMEError(message: "Encryption failed!", errorArray: errArr, type: SMIMEError.ErrorType.encryption)
-        }
-        
         // check if the user has a certificate
         if ownFp != nil {
             let ownCert = certsKeychain[ownFp!]!
             let ownPk = privateKeyKeychain[ownFp!]!
-            let (sigText, sigErrArr) = signWithPem(message: encStr!, certAsPem: ownCert, keyAsPem: ownPk, detached: false)
+            (sigText, sigErrArr) = signWithPem(message: plainText!, certAsPem: ownCert, keyAsPem: ownPk, detached: false)
             
             if sigErrArr != nil && sigErrArr!.count > 0 {
-                throw SMIMEError(message: "Signing during encryption failed!", errorArray: sigErrArr, type: SMIMEError.ErrorType.encryption)
+                throw SMIMEError(message: "Signing during encryption failed!", errorArray: sigErrArr, type: SMIMEError.ErrorType.signing)
             }
-            
-            return CryptoObject(chiphertext: sigText!.data(using: .utf8), plaintext: text, decryptedData: plainData, sigState: SignatureState.ValidSignature, encState: EncryptionState.ValidedEncryptedWithCurrentKey, signKey: ownFp, encType: CryptoScheme.SMIME, signedAdrs: [ownId])
+        } else {
+            throw SMIMEError(message: "Tried to sign with user's certificate but none was present!", errorArray: nil, type: SMIMEError.ErrorType.other)
+        }
+        
+        // do the actual encryption
+        // NOTE: sigText can't be nil b/c we force signing so we either sign successfully or we throw an exception and never reach this code block
+        let (encStr, errArr) = encryptWithPem(message: sigText!, certPems: pems)
+        if errArr != nil && errArr!.count > 0 {
+            throw SMIMEError(message: "Encryption failed!", errorArray: errArr, type: SMIMEError.ErrorType.encryption)
         }
         
-        throw SMIMEError(message: "Tried to sign with user's certificate but none was present!", errorArray: errArr, type: SMIMEError.ErrorType.encryption)
+        return CryptoObject(chiphertext: encStr!.data(using: .utf8), plaintext: plainText, decryptedData: plainData, sigState: SignatureState.ValidSignature, encState: EncryptionState.ValidedEncryptedWithCurrentKey, signKey: ownFp, encType: CryptoScheme.SMIME, signedAdrs: [ownId])
     }
 }
 
diff --git a/enzevalos_iphone/SMIMEHelpers.swift b/enzevalos_iphone/SMIMEHelpers.swift
index 8c832258bd4e5c4fb35745f1fc840700ebb63622..03874305dbedc7ae74039603f2b57d96f9c8506a 100644
--- a/enzevalos_iphone/SMIMEHelpers.swift
+++ b/enzevalos_iphone/SMIMEHelpers.swift
@@ -8,17 +8,35 @@
 
 import Foundation
 
-struct SMIMEError : Error {
+class SMIMEError : Error {
     enum ErrorType {
         case fingerPrint
         case encryption
         case decryption
+        case verification
         case signing
+        case other
+    }
+    
+    func errorArrayToString() -> [String] {
+        var strArr: [String] = []
+        
+        for error in self.errorArray ?? [] {
+            strArr.append(getErrorString(errCode: error))
+        }
+        
+        return strArr
     }
     
     let message: String?
     let errorArray: [UInt]?
     let type: ErrorType
+    
+    init(message: String?, errorArray: [UInt]?, type: ErrorType) {
+        self.message = message
+        self.errorArray = errorArray
+        self.type = type
+    }
 }
 
 func encryptWithPem(message: String,certPems: [String]) -> (String?, [UInt]?) {
@@ -68,6 +86,11 @@ func signWithPem(message:String, certAsPem: String, keyAsPem:String, detached:Bo
     return (sigStr, errArr)
 }
 
+
+/**
+    when the signature can't be verified with the present certs: verStr = nil, numCerts = 0, error code: 772378724
+    when no signature present, there's error reason "no content type"
+ */
 func verifyWithCApem (message:String, pemCAArr: [String]) -> (String?, [(String, String)]?, [UInt]?) {
     let pemCAArrC = createCStrArr(sarr: pemCAArr)
     let ver = OpenSSL_verify(message, pemCAArrC, Int32(pemCAArr.count))
@@ -88,10 +111,12 @@ func verifyWithCApem (message:String, pemCAArr: [String]) -> (String?, [(String,
     let numCerts = Int((result?.num_certs)!)
     var certFPArr: [(String, String)] = []
     
-    for i in 0...(numCerts-1) {
-        certFPArr.append( ((fpArr?[i])!, (certArr?[i])!) )
+    if (numCerts > 0) {
+        for i in 0...(numCerts-1) {
+            certFPArr.append( ((fpArr?[i])!, (certArr?[i])!) )
+        }
     }
-        
+    
     return (verStr, certFPArr, errArr)
 }
 
@@ -172,6 +197,36 @@ func getErrorString(errCode: UInt) -> String {
     return "Invalid error code!"
 }
 
+func getErrorReasonString(errCode: UInt) -> String {
+    let cStr = get_err_reason_string(errCode);
+    defer {
+        cStr?.deallocate()
+    }
+    
+    if (cStr != nil) {
+        let str = String( cString: cStr!)
+        return str;
+    }
+    return "Invalid error code!"
+}
+
+func getAllEmailsFromPEMs(certs: [String]) -> [String] {
+    let certObjects = certs.map( { (arg) -> Certificate in
+        return Certificate(pem: arg)
+    })
+    
+    var addrs : [String:Bool] = [:]
+    for c in certObjects
+    {
+        for e in c.eMails!
+        {
+            addrs[e] = true
+        }
+    }
+    
+    return Array(addrs.keys)
+}
+
 func deallocateResult(res: UnsafeMutablePointer<result>?) {
     deallocate_result(res)
 }
diff --git a/enzevalos_iphone/SearchHelper.swift b/enzevalos_iphone/SearchHelper.swift
index 1c22010eaf79b606636d1aae2daa8d1876998760..95b93c98a0bad23c627c618ca5fa3d5c0fe7c47c 100644
--- a/enzevalos_iphone/SearchHelper.swift
+++ b/enzevalos_iphone/SearchHelper.swift
@@ -35,7 +35,8 @@ func containsSearchTerms ( content : String?, searchText: String) -> Bool
         smime.testSMIMEencrypt()
     // }
     // smime.testKeychain()
-    //smime.testKeyEnc()
+    // smime.testKeyEnc()
+    // smime.testVerification()
     
     var longterms : [String] = []
     var terms : [String] = []
diff --git a/enzevalos_iphone/c/general-helpers.c b/enzevalos_iphone/c/general-helpers.c
index 5ef36beefd70da443e6a609b9fa3a9050157cd0f..e537ba48d064af03aa2430eb138c075aad5944a9 100644
--- a/enzevalos_iphone/c/general-helpers.c
+++ b/enzevalos_iphone/c/general-helpers.c
@@ -23,11 +23,22 @@ int get_array_size(array_with_length *arr) {
 }
 
 char *get_err_string(unsigned long err) {
-    const char *error = ERR_func_error_string(err);
-    //printf("\nError: %s", error);
-    char * error_permanent = (char *) malloc(strlen(error)+1);
+    char * error_permanent = malloc(256);
+    ERR_error_string_n(err, error_permanent, 256);
+    // printf("\nError: %s", error_permanent);
+    /*char * error_permanent = (char *) malloc(strlen(error)+1);
     error_permanent[strlen(error)]=0; // To Nullterminate the string
-    memcpy(error_permanent,error,strlen(error));
+    memcpy(error_permanent,error,strlen(error));*/
+    
+    return error_permanent;
+}
+
+char *get_err_reason_string(unsigned long err) {
+    const char * reason_str = ERR_reason_error_string(err);
+    char * error_permanent = (char *) malloc(strlen(reason_str)+1);
+    error_permanent[strlen(reason_str)]=0; // To Nullterminate the string
+    memcpy(error_permanent,reason_str,strlen(reason_str));
+    // printf("\nError: %s", error_permanent);
     
     return error_permanent;
 }
diff --git a/enzevalos_iphone/c/generic-helpers.h b/enzevalos_iphone/c/generic-helpers.h
index 0cce3db5c8ef3db14c25e38cbf220d2d3d8bfc28..3288c0d8f0ba36412ec3b4b841832daac1d3d159 100644
--- a/enzevalos_iphone/c/generic-helpers.h
+++ b/enzevalos_iphone/c/generic-helpers.h
@@ -45,6 +45,7 @@ struct array_with_length {
 
 char * pop_error (result *res);
 char *get_err_string(unsigned long err);
+char *get_err_reason_string(unsigned long err);
 
 void bio_to_str(BIO *bio_in, char **out);
 int get_array_size(array_with_length *arr);
diff --git a/enzevalos_iphone/c/smime-helpers.c b/enzevalos_iphone/c/smime-helpers.c
index 0d5569e2a5df5b05e4b65e5de66977520d36bd36..62e528307be0a781713b74ac88838ff323e0f78d 100644
--- a/enzevalos_iphone/c/smime-helpers.c
+++ b/enzevalos_iphone/c/smime-helpers.c
@@ -39,6 +39,7 @@ void OpenSSL_print_ver(void) {
     printf("%s", OPENSSL_VERSION_TEXT);
 }
 
+// TODO: move this to general-helpers.c
 array_with_length *create_list_of_errors() {
     unsigned long err = 0;
     linked_list *head = NULL;
@@ -49,6 +50,8 @@ array_with_length *create_list_of_errors() {
     unsigned long * arr = NULL;
     
     while ((err = ERR_get_error()) != 0) {
+        char error[256];
+        printf("Error code from collection: %lu\nError string returned: %s\nError string from buf: %s\n", err, ERR_error_string(err, error), error);
         linked_list * newerr = malloc(sizeof(linked_list));
         newerr->content = malloc(sizeof(unsigned long));
         memcpy(newerr->content, &err, sizeof(unsigned long));