Skip to content
Snippets Groups Projects
Commit a4205a29 authored by Oliver Wiese's avatar Oliver Wiese
Browse files

fix potential erros in smime

parent 3c5c72cc
Branches
No related tags found
No related merge requests found
...@@ -62,7 +62,9 @@ class SMIME { ...@@ -62,7 +62,9 @@ class SMIME {
var CAs : [String] = [] var CAs : [String] = []
for k in CAKeychain.allKeys() for k in CAKeychain.allKeys()
{ {
CAs.append(CAKeychain[k]!) if let ca = CAKeychain[k] {
CAs.append(ca)
}
} }
return CAs return CAs
...@@ -105,10 +107,10 @@ class SMIME { ...@@ -105,10 +107,10 @@ class SMIME {
for (cert, key) in certsAndKeys { for (cert, key) in certsAndKeys {
let (certFP, _, _) = getFingerprintFromPem(pem: cert) let (certFP, _, _) = getFingerprintFromPem(pem: cert)
if (certFP != nil) { if let certFP = certFP {
certsKeychain[certFP!] = cert certsKeychain[certFP] = cert
privateKeyKeychain[certFP!] = key privateKeyKeychain[certFP] = key
fingerprints.append(certFP!) fingerprints.append(certFP)
} }
} }
...@@ -182,22 +184,21 @@ class SMIME { ...@@ -182,22 +184,21 @@ class SMIME {
*/ */
func decrypt(data: Data, fromAddr: String, isMailNew: Bool) throws -> CryptoObject { func decrypt(data: Data, fromAddr: String, isMailNew: Bool) throws -> CryptoObject {
var outputData: Data = data var outputData: Data = data
let text = String(data: data, encoding: .utf8)! guard var fp = getOwnKeyFP() , let cert = certsKeychain[fp], let key = privateKeyKeychain[fp], let text = String(data: data, encoding: .utf8) else {
var fp = getOwnKeyFP() return CryptoObject(chiphertext: data, plaintext: nil, decryptedData: nil, sigState: .NoPublicKey, encState: .UnableToDecrypt, signKey: nil, encType: .SMIME, signedAdrs: [])
let cert = certsKeychain[fp!]! // TODO ERROR!!! }
let key = privateKeyKeychain[fp!]!
var (decStr, errArr) = decryptWithPem(message: text, certAsPem: cert, keyAsPem: key) var (decStr, errArr) = decryptWithPem(message: text, certAsPem: cert, keyAsPem: key)
var encState = EncryptionState.UnableToDecrypt var encState = EncryptionState.UnableToDecrypt
if decStr != nil && (errArr == nil || errArr!.count == 0) { if let errArr = errArr, errArr.count == 0 && decStr != nil {
encState = EncryptionState.ValidedEncryptedWithCurrentKey encState = EncryptionState.ValidedEncryptedWithCurrentKey
} }
else else
{ {
let fps = privateKeyKeychain.allKeys() let fps = privateKeyKeychain.allKeys()
for f in fps{ for f in fps {
if f != fp{ if f != fp, let certAsPem = certsKeychain[f], let keyAsPem = privateKeyKeychain[f] {
(decStr, errArr) = decryptWithPem(message: text, certAsPem: certsKeychain[f]!, keyAsPem: privateKeyKeychain[f]!) (decStr, errArr) = decryptWithPem(message: text, certAsPem: certAsPem, keyAsPem: keyAsPem)
if decStr != nil{ if decStr != nil{
fp = f fp = f
encState = EncryptionState.ValidEncryptedWithOldKey encState = EncryptionState.ValidEncryptedWithOldKey
...@@ -207,8 +208,8 @@ class SMIME { ...@@ -207,8 +208,8 @@ class SMIME {
} }
} }
if decStr != nil { if let decStr = decStr, let decData = decStr.data(using: .utf8) {
outputData = decStr!.data(using: .utf8)! outputData = decData
} }
/** /**
...@@ -216,7 +217,7 @@ class SMIME { ...@@ -216,7 +217,7 @@ class SMIME {
* the email wasn't meant for us and we shouldn't be able to decrypt it anyway * 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 * there is something wrong with the e-mail
*/ */
if (errArr != nil && errArr!.count > 0) { if let errArr = errArr, errArr.count > 0 {
throw SMIMEError(message: "Decryption failed!", errorArray: errArr, type: SMIMEError.ErrorType.decryption) throw SMIMEError(message: "Decryption failed!", errorArray: errArr, type: SMIMEError.ErrorType.decryption)
} }
...@@ -227,7 +228,8 @@ class SMIME { ...@@ -227,7 +228,8 @@ class SMIME {
let sigState = verifyCryptoObj.signatureState let sigState = verifyCryptoObj.signatureState
let addresses = verifyCryptoObj.signedAdrs let addresses = verifyCryptoObj.signedAdrs
let plainText = verifyCryptoObj.plaintext let plainText = verifyCryptoObj.plaintext
let decryptedData = plainText!.data(using: .utf8)! let decryptedData = plainText?.data(using: .utf8)
return CryptoObject(chiphertext: data, plaintext: plainText, decryptedData: decryptedData, sigState: sigState, encState: encState, signKey: signKey, encType: CryptoScheme.SMIME, signedAdrs: addresses, signedKeys: signedKeys) return CryptoObject(chiphertext: data, plaintext: plainText, decryptedData: decryptedData, sigState: sigState, encState: encState, signKey: signKey, encType: CryptoScheme.SMIME, signedAdrs: addresses, signedKeys: signedKeys)
} }
...@@ -252,15 +254,23 @@ class SMIME { ...@@ -252,15 +254,23 @@ class SMIME {
guard let cert = certsKeychain[fp], let key = privateKeyKeychain[fp] else { guard let cert = certsKeychain[fp], let key = privateKeyKeychain[fp] else {
throw SMIMEError(message: "No signing key....", errorArray: nil, type: SMIMEError.ErrorType.missingKey) throw SMIMEError(message: "No signing key....", errorArray: nil, type: SMIMEError.ErrorType.missingKey)
} }
let text = String(data: plainData, encoding: .utf8) guard let text = String(data: plainData, encoding: .utf8) else {
throw SMIMEError(message: "No data...", errorArray: nil, type: SMIMEError.ErrorType.noData)
}
let (sigText, errArr) = signWithPem(message: text!, certAsPem: cert, keyAsPem: key, detached: detached) let (sigText, errArr) = signWithPem(message: text, certAsPem: cert, keyAsPem: key, detached: detached)
if (errArr != nil && errArr!.count > 0) { if let errArr = errArr, errArr.count > 0 {
throw SMIMEError(message: "Signing failed!", errorArray: errArr, type: SMIMEError.ErrorType.signing) throw SMIMEError(message: "Signing failed!", errorArray: errArr, type: SMIMEError.ErrorType.signing)
} }
if let sigText = sigText {
return CryptoObject(chiphertext: sigText.data(using: .utf8), plaintext: text, decryptedData: plainData, sigState: SignatureState.ValidSignature, encState: EncryptionState.NoEncryption, signKey: fp, encType: CryptoScheme.SMIME, signedAdrs: [myEmail])
} else {
throw SMIMEError(message: "Signing failed! No signed data...", errorArray: errArr, type: SMIMEError.ErrorType.signing)
}
return CryptoObject(chiphertext: sigText!.data(using: .utf8), plaintext: text, decryptedData: plainData, sigState: SignatureState.ValidSignature, encState: EncryptionState.NoEncryption, signKey: fp, encType: CryptoScheme.SMIME, signedAdrs: [myEmail])
} }
/** /**
...@@ -276,7 +286,9 @@ class SMIME { ...@@ -276,7 +286,9 @@ class SMIME {
func verify(data: Data?, string: String? = nil, email: String, isMailNew: Bool) -> CryptoObject { func verify(data: Data?, string: String? = nil, email: String, isMailNew: Bool) -> CryptoObject {
var CAs : [String] = [] var CAs : [String] = []
CAKeychain.allKeys().forEach({ (key) in CAKeychain.allKeys().forEach({ (key) in
CAs.append(CAKeychain[key]!) if let ca = CAKeychain[key] {
CAs.append(ca)
}
}) })
guard data != nil || string != nil else { guard data != nil || string != nil else {
return CryptoObject(chiphertext: nil, plaintext: nil, decryptedData: nil, sigState: .NoSignature, encState: .UnableToDecrypt, signKey: nil, encType: .UNKNOWN, signedAdrs: []) return CryptoObject(chiphertext: nil, plaintext: nil, decryptedData: nil, sigState: .NoSignature, encState: .UnableToDecrypt, signKey: nil, encType: .UNKNOWN, signedAdrs: [])
...@@ -292,17 +304,16 @@ class SMIME { ...@@ -292,17 +304,16 @@ class SMIME {
let (verStr, certsFPArrWithNil, errArr) = verifyWithCApem(message: text, pemCAArr: CAs) let (verStr, certsFPArrWithNil, errArr) = verifyWithCApem(message: text, pemCAArr: CAs)
guard let certsFPArr = certsFPArrWithNil, certsFPArr.count > 0 else { guard let certsFPArr = certsFPArrWithNil, certsFPArr.count > 0 else {
let errors = errArr! if let errors = errArr {
for error in errors {
for error in errors { let reason = getErrorReasonString(errCode: error)
let reason = getErrorReasonString(errCode: error) // check reasons to identify different error causes
// check reasons to identify different error causes // string comaprison necessary because doesn't have fixed error codes...
// string comaprison necessary because doesn't have fixed error codes... if reason == "no content type" {
if reason == "no content type" { return CryptoObject(chiphertext: data, plaintext: text, decryptedData: nil, sigState: .NoSignature, encState: EncryptionState.NoEncryption, signKey: nil, encType: .UNKNOWN, signedAdrs: [])
return CryptoObject(chiphertext: data, plaintext: text, decryptedData: nil, sigState: .NoSignature, encState: EncryptionState.NoEncryption, signKey: nil, encType: .UNKNOWN, signedAdrs: []) }
} }
} }
return CryptoObject(chiphertext: data, plaintext: text, decryptedData: nil, sigState: .InvalidSignature, encState: EncryptionState.NoEncryption, signKey: nil, encType: .UNKNOWN, signedAdrs: []) return CryptoObject(chiphertext: data, plaintext: text, decryptedData: nil, sigState: .InvalidSignature, encState: EncryptionState.NoEncryption, signKey: nil, encType: .UNKNOWN, signedAdrs: [])
} }
...@@ -356,8 +367,11 @@ class SMIME { ...@@ -356,8 +367,11 @@ class SMIME {
let (fp, _) = arg let (fp, _) = arg
return fp return fp
}) })
if let verStr = verStr {
return CryptoObject(chiphertext: data, plaintext: verStr!, decryptedData: nil, sigState: sigState, encState: EncryptionState.NoEncryption, signKey: nil, encType: .SMIME, signedAdrs: signedAddresses, signedKeys: signKeyFps) return CryptoObject(chiphertext: data, plaintext: verStr, decryptedData: nil, sigState: sigState, encState: EncryptionState.NoEncryption, signKey: nil, encType: .SMIME, signedAdrs: signedAddresses, signedKeys: signKeyFps)
} else {
return CryptoObject(chiphertext: data, plaintext: text, decryptedData: nil, sigState: .NoSignature, encState: EncryptionState.NoEncryption, signKey: nil, encType: .UNKNOWN, signedAdrs: [])
}
} }
/** /**
...@@ -395,8 +409,8 @@ class SMIME { ...@@ -395,8 +409,8 @@ class SMIME {
// if we want to encrypt with the user's own key, retrieve the key and handle errors // if we want to encrypt with the user's own key, retrieve the key and handle errors
if encryptForMyId { if encryptForMyId {
if ownFp != nil { if let ownFp = ownFp, let cert = certsKeychain[ownFp] {
pems.append(certsKeychain[ownFp!]!) pems.append(cert)
} }
else { 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.other) 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)
...@@ -421,11 +435,14 @@ class SMIME { ...@@ -421,11 +435,14 @@ class SMIME {
// do the actual encryption // 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 // 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) let (encStr, errArr) = encryptWithPem(message: sigText!, certPems: pems)
if errArr != nil && errArr!.count > 0 { if let errArr = errArr, errArr.count > 0 {
throw SMIMEError(message: "Encryption failed!", errorArray: errArr, type: SMIMEError.ErrorType.encryption) throw SMIMEError(message: "Encryption failed!", errorArray: errArr, type: SMIMEError.ErrorType.encryption)
} }
if let encStr = encStr {
return CryptoObject(chiphertext: encStr!.data(using: .utf8), plaintext: plainText, decryptedData: plainData, sigState: SignatureState.ValidSignature, encState: EncryptionState.ValidedEncryptedWithCurrentKey, signKey: ownFp, encType: CryptoScheme.SMIME, signedAdrs: [ownAddr]) return CryptoObject(chiphertext: encStr.data(using: .utf8), plaintext: plainText, decryptedData: plainData, sigState: SignatureState.ValidSignature, encState: EncryptionState.ValidedEncryptedWithCurrentKey, signKey: ownFp, encType: CryptoScheme.SMIME, signedAdrs: [ownAddr])
}
throw SMIMEError(message: "Encryption failed! No data...", errorArray: errArr, type: SMIMEError.ErrorType.encryption)
} }
/** /**
...@@ -504,12 +521,18 @@ class SMIME { ...@@ -504,12 +521,18 @@ class SMIME {
let certArr: [String]? = result?.extractField(field: ResultAttribute.certificates) let certArr: [String]? = result?.extractField(field: ResultAttribute.certificates)
let fpArr: [String]? = result?.extractField(field: ResultAttribute.fingerprints) let fpArr: [String]? = result?.extractField(field: ResultAttribute.fingerprints)
let numCerts = Int((result?.num_certs)!)
var numCerts = 0
if let n = result?.num_certs {
numCerts = Int(n)
}
var certFPArr: [(String, String)] = [] var certFPArr: [(String, String)] = []
if (numCerts > 0) { if (numCerts > 0) {
for i in 0...(numCerts-1) { for i in 0...(numCerts-1) {
certFPArr.append( ((fpArr?[i])!, (certArr?[i])!) ) if let fp = fpArr?[i], let cert = certArr?[i] {
certFPArr.append((fp, cert))
}
} }
} }
......
...@@ -19,6 +19,7 @@ class SMIMEError : Error { ...@@ -19,6 +19,7 @@ class SMIMEError : Error {
case signing case signing
case other case other
case missingKey case missingKey
case noData
} }
func errorArrayToString() -> [String] { func errorArrayToString() -> [String] {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment