Commit a4205a29 authored by Oliver Wiese's avatar Oliver Wiese
Browse files

fix potential erros in smime

parent 3c5c72cc
......@@ -62,7 +62,9 @@ class SMIME {
var CAs : [String] = []
for k in CAKeychain.allKeys()
{
CAs.append(CAKeychain[k]!)
if let ca = CAKeychain[k] {
CAs.append(ca)
}
}
return CAs
......@@ -105,10 +107,10 @@ class SMIME {
for (cert, key) in certsAndKeys {
let (certFP, _, _) = getFingerprintFromPem(pem: cert)
if (certFP != nil) {
certsKeychain[certFP!] = cert
privateKeyKeychain[certFP!] = key
fingerprints.append(certFP!)
if let certFP = certFP {
certsKeychain[certFP] = cert
privateKeyKeychain[certFP] = key
fingerprints.append(certFP)
}
}
......@@ -182,22 +184,21 @@ class SMIME {
*/
func decrypt(data: Data, fromAddr: String, isMailNew: Bool) throws -> CryptoObject {
var outputData: Data = data
let text = String(data: data, encoding: .utf8)!
var fp = getOwnKeyFP()
let cert = certsKeychain[fp!]! // TODO ERROR!!!
let key = privateKeyKeychain[fp!]!
guard var fp = getOwnKeyFP() , let cert = certsKeychain[fp], let key = privateKeyKeychain[fp], let text = String(data: data, encoding: .utf8) else {
return CryptoObject(chiphertext: data, plaintext: nil, decryptedData: nil, sigState: .NoPublicKey, encState: .UnableToDecrypt, signKey: nil, encType: .SMIME, signedAdrs: [])
}
var (decStr, errArr) = decryptWithPem(message: text, certAsPem: cert, keyAsPem: key)
var encState = EncryptionState.UnableToDecrypt
if decStr != nil && (errArr == nil || errArr!.count == 0) {
if let errArr = errArr, errArr.count == 0 && decStr != nil {
encState = EncryptionState.ValidedEncryptedWithCurrentKey
}
else
{
let fps = privateKeyKeychain.allKeys()
for f in fps{
if f != fp{
(decStr, errArr) = decryptWithPem(message: text, certAsPem: certsKeychain[f]!, keyAsPem: privateKeyKeychain[f]!)
for f in fps {
if f != fp, let certAsPem = certsKeychain[f], let keyAsPem = privateKeyKeychain[f] {
(decStr, errArr) = decryptWithPem(message: text, certAsPem: certAsPem, keyAsPem: keyAsPem)
if decStr != nil{
fp = f
encState = EncryptionState.ValidEncryptedWithOldKey
......@@ -207,8 +208,8 @@ class SMIME {
}
}
if decStr != nil {
outputData = decStr!.data(using: .utf8)!
if let decStr = decStr, let decData = decStr.data(using: .utf8) {
outputData = decData
}
/**
......@@ -216,7 +217,7 @@ class SMIME {
* 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) {
if let errArr = errArr, errArr.count > 0 {
throw SMIMEError(message: "Decryption failed!", errorArray: errArr, type: SMIMEError.ErrorType.decryption)
}
......@@ -227,7 +228,8 @@ class SMIME {
let sigState = verifyCryptoObj.signatureState
let addresses = verifyCryptoObj.signedAdrs
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)
}
......@@ -252,15 +254,23 @@ class SMIME {
guard let cert = certsKeychain[fp], let key = privateKeyKeychain[fp] else {
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)
}
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 {
func verify(data: Data?, string: String? = nil, email: String, isMailNew: Bool) -> CryptoObject {
var CAs : [String] = []
CAKeychain.allKeys().forEach({ (key) in
CAs.append(CAKeychain[key]!)
if let ca = CAKeychain[key] {
CAs.append(ca)
}
})
guard data != nil || string != nil else {
return CryptoObject(chiphertext: nil, plaintext: nil, decryptedData: nil, sigState: .NoSignature, encState: .UnableToDecrypt, signKey: nil, encType: .UNKNOWN, signedAdrs: [])
......@@ -292,17 +304,16 @@ class SMIME {
let (verStr, certsFPArrWithNil, errArr) = verifyWithCApem(message: text, pemCAArr: CAs)
guard let certsFPArr = certsFPArrWithNil, certsFPArr.count > 0 else {
let errors = errArr!
for error in errors {
let reason = getErrorReasonString(errCode: error)
// 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: [])
if let errors = errArr {
for error in errors {
let reason = getErrorReasonString(errCode: error)
// 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: [])
}
}
}
return CryptoObject(chiphertext: data, plaintext: text, decryptedData: nil, sigState: .InvalidSignature, encState: EncryptionState.NoEncryption, signKey: nil, encType: .UNKNOWN, signedAdrs: [])
}
......@@ -356,8 +367,11 @@ class SMIME {
let (fp, _) = arg
return fp
})
return CryptoObject(chiphertext: data, plaintext: verStr!, decryptedData: nil, sigState: sigState, encState: EncryptionState.NoEncryption, signKey: nil, encType: .SMIME, signedAdrs: signedAddresses, signedKeys: signKeyFps)
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)
} 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 {
// if we want to encrypt with the user's own key, retrieve the key and handle errors
if encryptForMyId {
if ownFp != nil {
pems.append(certsKeychain[ownFp!]!)
if let ownFp = ownFp, let cert = certsKeychain[ownFp] {
pems.append(cert)
}
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)
......@@ -421,11 +435,14 @@ class SMIME {
// 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 {
if let errArr = errArr, errArr.count > 0 {
throw SMIMEError(message: "Encryption failed!", 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: [ownAddr])
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])
}
throw SMIMEError(message: "Encryption failed! No data...", errorArray: errArr, type: SMIMEError.ErrorType.encryption)
}
/**
......@@ -504,12 +521,18 @@ class SMIME {
let certArr: [String]? = result?.extractField(field: ResultAttribute.certificates)
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)] = []
if (numCerts > 0) {
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 {
case signing
case other
case missingKey
case noData
}
func errorArrayToString() -> [String] {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment