...
 
Commits (15)
This diff is collapsed.
......@@ -47,11 +47,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}
resetApp()
StudySettings.setupStudy()
//StudySettings.firstMail()
if (!UserDefaults.standard.bool(forKey: "launchedBefore")) {
// Logger.queue.async(flags: .barrier) {
// Logger.log(startApp: true)
// }
// Remove Google Auth token from keychain
GTMKeychain.removePasswordFromKeychain(forName: "googleOAuthCodingKey")
......@@ -60,14 +56,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
UserDefaults.standard.register(defaults: ["Signature.Text": "Verfasst mit Letterbox. Mehr Informationen: http://letterbox.imp.fu-berlin.de?invitation=0"])
self.window = UIWindow(frame: UIScreen.main.bounds)
//self.window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("onboarding")
self.window?.rootViewController = Onboarding.onboarding()
self.window?.makeKeyAndVisible()
} else {
AddressHandler.updateCNContacts()
// Logger.log(startApp: false)
presentInboxViewController()
}
NotificationCenter.default.addObserver(
......
......@@ -80,7 +80,15 @@ class Autocrypt {
self.init(addr: addr, type: type, prefer_encryption: pref, key: key)
}
private func addArmor() -> Bool{
let header = "-----BEGIN PGP PUBLIC KEY BLOCK-----"
guard !key.isEmpty && !key.starts(with: header), let data = key.toBase64() else {
return false
}
key = Armor.armored(data, as: .publicKey)
return true
}
func setPrefer_encryption(_ input: String){
let pref = input.lowercased()
if pref == "yes" || pref == "mutual" || pref == EncState.MUTUAL.name {
......
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Amm-QN-vA7">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Amm-QN-vA7">
<device id="retina4_0" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="Stack View standard spacing" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
......@@ -158,7 +158,7 @@
<rect key="frame" x="16" y="0.0" width="288" height="44"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="I7i-jf-aSX">
<rect key="frame" x="0.0" y="0.0" width="147" height="44"/>
<rect key="frame" x="0.0" y="5.5" width="147" height="33"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="81H-Ed-3bH"/>
</constraints>
......@@ -182,7 +182,7 @@
</constraints>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qTi-rO-CH3">
<rect key="frame" x="148" y="0.0" width="140" height="44"/>
<rect key="frame" x="148" y="5.5" width="140" height="33"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="voC-CF-ncN"/>
</constraints>
......@@ -1011,11 +1011,11 @@
<rect key="frame" x="0.0" y="545.5" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="dM9-jb-EcN" id="tvN-re-z1Z">
<rect key="frame" x="0.0" y="0.0" width="286" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="294" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="VTZ-4w-fot">
<rect key="frame" x="16" y="0.0" width="269" height="43.5"/>
<rect key="frame" x="15" y="0.0" width="270" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
......@@ -1488,7 +1488,7 @@ Um deine sicheren E-Mails auch auf einem anderen Gerät lesen zu können, muss d
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="3456-7890-1234-" textAlignment="center" lineBreakMode="characterWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QaR-WZ-20E">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="3456-7890-1234-" textAlignment="center" lineBreakMode="characterWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QaR-WZ-20E">
<rect key="frame" x="85.5" y="173.5" width="153" height="17.5"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<nil key="textColor"/>
......@@ -1865,6 +1865,6 @@ Um deine sicheren E-Mails auch auf einem anderen Gerät lesen zu können, muss d
<segue reference="hSn-Um-hji"/>
<segue reference="btx-4o-o0r"/>
<segue reference="TgN-rB-esa"/>
<segue reference="ecN-Wn-7S0"/>
<segue reference="6Ug-AV-lba"/>
</inferredMetricsTieBreakers>
</document>
......@@ -8,9 +8,9 @@
import Foundation
enum SignatureState: Int16 {
case NoSignature = 0
case NoPublicKey = 1
case InvalidSignature = -1
case NoSignature = 0 // -> no authenticity -> no actions possible
case NoPublicKey = 1 // -> no authenticity -> Possible actions: Ask sender to send keys, import key, Would be nice to verify mails later.
case InvalidSignature = -1 // -> ERROR -> context is manipulated (either attack or MTA...)
case ValidSignature = 2
var name: String {
......
......@@ -840,9 +840,13 @@ class DataHandler {
// -------- End handle to, cc, from addresses --------
func createMail(_ uid: UInt64, sender: MCOAddress?, receivers: [MCOAddress], cc: [MCOAddress], time: Date, received: Bool, subject: String, body: String?, readableAttachments: Set<TempAttachment> = Set<TempAttachment>(), flags: MCOMessageFlag, record: KeyRecord?, autocrypt: Autocrypt?, decryptedData: CryptoObject?, folderPath: String, secretKey: String?, references: [String] = [], mailagent: String? = nil, messageID: String? = nil, encryptedBody: String?, storeEncrypted: Bool = false) -> PersistentMail? {
guard let sender = sender else {
return nil
}
let myfolder = findFolder(with: folderPath) as Folder
let finding = findNum("PersistentMail", type: "uid", search: uid)
let mail: PersistentMail
var mails: [PersistentMail] = []
......@@ -886,9 +890,8 @@ class DataHandler {
mail.received = received
if sender != nil {
handleFromAddress(sender!, fromMail: mail, autocrypt: autocrypt)
}
handleFromAddress(sender, fromMail: mail, autocrypt: autocrypt)
handleToAddresses(receivers, mail: mail)
handleCCAddresses(cc, mail: mail)
......@@ -980,10 +983,12 @@ class DataHandler {
}
record.addToPersistentMails(mail)
mail.folder.addToKeyRecords(record)
if record.newestDate == nil {
let isInbox = mail.folder.path == Folder.inbox.path
if record.newestDate == nil, isInbox {
record.newestDate = mail.date
}
if let date = record.newestDate, date.timeIntervalSince(mail.date) < 0 {
if let date = record.newestDate, date.timeIntervalSince(mail.date) < 0, isInbox {
// We should update our records...
record.newestDate = mail.date
}
......
......@@ -11,6 +11,11 @@ import CoreData
@objc(Folder)
public class Folder: NSManagedObject {
static var inbox: Folder {
get {
return DataHandler.handler.findFolder(with: UserManager.backendInboxFolderPath)
}
}
var name: String {
get {
......@@ -52,7 +57,8 @@ public class Folder: NSManagedObject {
guard keyRecords != nil && keyRecords?.count ?? 0 > 0 else {
return []
}
return DataHandler.handler.getAllKeyRecords()
let rs = DataHandler.handler.getAllKeyRecords()
return rs
}
}
......
......@@ -71,7 +71,7 @@ class IntroPageViewController: UIPageViewController, IntroInfoButton {
}
override func setViewControllers(_ viewControllers: [UIViewController]?, direction: UIPageViewController.NavigationDirection, animated: Bool, completion: ((Bool) -> Void)? = nil) {
if let viewControllers = viewControllers, let controller = viewControllers.first, let index = orderedViewControllers.index(of: controller) {
if let viewControllers = viewControllers, let controller = viewControllers.first, let index = orderedViewControllers.firstIndex(of: controller) {
self.pageControl.currentPage = index
}
super.setViewControllers(viewControllers, direction: direction, animated: animated, completion: completion)
......@@ -81,14 +81,14 @@ class IntroPageViewController: UIPageViewController, IntroInfoButton {
extension IntroPageViewController: UIPageViewControllerDataSource {
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
if let index = orderedViewControllers.index(of: viewController), index > 0 {
if let index = orderedViewControllers.firstIndex(of: viewController), index > 0 {
return orderedViewControllers[index-1]
}
return nil
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
if let index = orderedViewControllers.index(of: viewController), index < orderedViewControllers.count-1 {
if let index = orderedViewControllers.firstIndex(of: viewController), index < orderedViewControllers.count-1 {
return orderedViewControllers[index+1]
}
return nil
......@@ -99,7 +99,7 @@ extension IntroPageViewController: UIPageViewControllerDataSource {
extension IntroPageViewController: UIPageViewControllerDelegate {
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
pendingIndex = orderedViewControllers.index(of: pendingViewControllers.first!)
pendingIndex = orderedViewControllers.firstIndex(of: pendingViewControllers.first!)
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
......
......@@ -52,7 +52,7 @@ class MailHandler {
var delegate: MailHandlerDelegator?
static var INBOX: String {
return "INBOX"
return UserManager.backendInboxFolderPath
}
private var IMAPSes: MCOIMAPSession?
var IMAPSession: MCOIMAPSession? {
......
......@@ -328,7 +328,6 @@ class MailServer: Comparable {
private func findIMAPHost() -> Bool{
if let session = createIMAPSession(logging: true, credentials: false, withAuthType: true) {
if let op = session.connectOperation(){
op.start({(error: Error?) -> () in
guard error == nil else {
......@@ -398,7 +397,7 @@ class MailServer: Comparable {
self.sendCallback = true
self.callback(nil, self)
}
print("SMTP works!")
print("SMTP works for \(self.username)!")
})
self.startWaiting()
return true
......@@ -448,9 +447,13 @@ class MailServer: Comparable {
session.checkAccountOperation().start({(error: Error?) -> () in
if let error = error {
let conError = MailServerConnectionError.findErrorCode(error: error)
if !self.receivedAuthTypes || !self.toTestConnType.isEmpty {
// Just downgrade authencation type and try again...
self.testAuthTypes()
if !self.receivedAuthTypes && !self.possibleAuthTypes.isEmpty {
self.authType = self.possibleAuthTypes.removeLast()
self.testUsernameAndPW()
}
else if conError != MailServerConnectionError.AuthenticationError && (!self.receivedAuthTypes || !self.possibleAuthTypes.isEmpty) && !self.possibleAuthTypes.isEmpty{
self.authType = self.possibleAuthTypes.removeLast()
self.testUsernameAndPW()
}
else if !self.sendCallback {
self.sendCallback = true
......@@ -463,7 +466,7 @@ class MailServer: Comparable {
self.sendCallback = true
self.callback(nil, self)
}
print("IMAP works!")
print("IMAP works for \(self.username)")
}
})
}
......@@ -625,6 +628,7 @@ class MailSession {
return searchForServerConfig(hostFromAdr: hostFromAdr)
}
private func searchForServerConfig(hostFromAdr: Bool) -> Bool {
var search = false
let (_, host) = MailSession.splitAddr(userAddr: self.mailAddr)
......
......@@ -55,8 +55,6 @@ open class Mail_Address: NSManagedObject, MailAddress {
return CNLabeledValue.init(label: CNLabelOther, value: address as NSString)
}
open var hasKey: Bool {
if publicKeys.count > 0 {
return true
......
......@@ -427,7 +427,7 @@ class Onboarding: NSObject {
imapTransportEncryption.reloadAllComponents()
imapTransDataDelegate.pickedValue = transportRows[imapConnRow]!
imapConnRow = imapTransDataDelegate.rows.index(of: transportRows[imapConnRow]!)!
imapConnRow = imapTransDataDelegate.rows.firstIndex(of: transportRows[imapConnRow]!)!
imapTransportEncryption.selectRow(imapConnRow, inComponent: 0, animated: false)
let imapAuthLabel = UILabel.init()
......@@ -449,7 +449,7 @@ class Onboarding: NSObject {
imapAuthentication.reloadInputViews()
imapAuthentication.tintColor = textColor
imapAuthDataDelegate.pickedValue = authenticationRows[imapAuthTypeRow]!
imapAuthTypeRow = Array(authenticationRows.values).index(of: authenticationRows[imapAuthTypeRow]!)!
imapAuthTypeRow = Array(authenticationRows.values).firstIndex(of: authenticationRows[imapAuthTypeRow]!)!
imapAuthentication.selectRow(imapAuthTypeRow, inComponent: 0, animated: false)
}
......@@ -512,7 +512,7 @@ class Onboarding: NSObject {
smtpTransportEncryption.reloadAllComponents()
smtpTransDataDelegate.pickedValue = transportRows[smtpConnTypeRow]!
smtpConnTypeRow = smtpTransDataDelegate.rows.index(of: transportRows[smtpConnTypeRow]!)!
smtpConnTypeRow = smtpTransDataDelegate.rows.firstIndex(of: transportRows[smtpConnTypeRow]!)!
smtpTransportEncryption.selectRow(smtpConnTypeRow, inComponent: 0, animated: false)
let smtpAuthLabel = UILabel.init()
......@@ -533,7 +533,7 @@ class Onboarding: NSObject {
smtpAuthentication.reloadInputViews()
smtpAuthentication.tintColor = textColor
smtpAuthDataDelegate.pickedValue = authenticationRows[smtpAuthTypeRow]!
smtpAuthTypeRow = Array(authenticationRows.values).index(of: authenticationRows[smtpAuthTypeRow]!)!
smtpAuthTypeRow = Array(authenticationRows.values).firstIndex(of: authenticationRows[smtpAuthTypeRow]!)!
smtpAuthentication.selectRow(smtpAuthTypeRow, inComponent: 0, animated: false)
let smtpAuth = UIView.init(frame: CGRect.init(x: 0, y: 0, width: 50, height: smtpTransportEncryption.frame.height + padding + smtpAuthLabel.frame.height + smtpAuthentication.frame.height))
......
......@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.8.22</string>
<string>0.8.24</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
......@@ -32,7 +32,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>0.8.22</string>
<string>0.8.24</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
......
......@@ -65,6 +65,17 @@ open class PersistentMail: NSManagedObject, Mail {
}
}
var isNewPubKey: Bool {
guard let signedKey = self.signedKey else {
return false
}
if signedKey.counterSignedMails < 2 && self.from.publicKeys.count > 1 && signedKey.fingerprint != self.from.primaryKey?.fingerprint {
return true
}
return false
}
var isRead: Bool {
get {
......
......@@ -61,16 +61,7 @@ class ReadViewController: UITableViewController {
var secretKeyPasswordField: UITextField? = nil
var infoState = LogData.WarningType.none
var isNewPubKey: Bool? {
guard let mail = mail, let signedKey = mail.signedKey else {
return nil
}
if signedKey.counterSignedMails < 2 && mail.from.publicKeys.count > 1 {
return true
}
return false
}
var deletedWhileTravel: Bool {
guard let mail = mail else {
......@@ -217,7 +208,7 @@ class ReadViewController: UITableViewController {
/// Bool indicating whether a info section is shown with the exception of trouble mails where the message is not shown (because we need only 2 sections in that case)
func showInfoSection(mail: PersistentMail) -> Bool {
return (mail.trouble && mail.showMessage) || (!mail.trouble && !mail.isSecure && mail.from.hasKey && mail.date > keyDiscoveryDate ?? Date() && !isDraft && !isInSentFolder) || (!mail.trouble && mail.isEncrypted && mail.unableToDecrypt) || isNewPubKey ?? false && !StudySettings.hideWarning || deletedWhileTravel
return (mail.trouble && mail.showMessage) || (!mail.trouble && !mail.isSecure && mail.from.hasKey && mail.date > keyDiscoveryDate ?? Date() && !isDraft && !isInSentFolder) || (!mail.trouble && mail.isEncrypted && mail.unableToDecrypt) || mail.isNewPubKey && !StudySettings.hideWarning || deletedWhileTravel
}
func showInfoButton(mail: PersistentMail) -> Bool {
......@@ -526,7 +517,7 @@ class ReadViewController: UITableViewController {
infoText.text = NSLocalizedString("couldNotDecryptText", comment: "Message could not be decrypted")
}
} else if (isNewPubKey ?? false) && !deletedWhileTravel {
} else if (mail.isNewPubKey) && !deletedWhileTravel {
infoState = .newKey
infoSymbol.text = "!"
infoSymbol.textColor = ThemeManager.orange
......@@ -537,7 +528,7 @@ class ReadViewController: UITableViewController {
//TODO: add travel hook here
infoState = .notConfidential
infoSymbol.text = "?"
infoSymbol.textColor = ThemeManager.unencryptedMessageColor()
infoSymbol.textColor = ThemeManager.orange
infoHeadline.text = NSLocalizedString("encryptedBeforeHeadline", comment: "The sender has encrypted before")
infoHeadline.textColor = UIColor.gray
infoText.text = NSLocalizedString("encryptedBeforeText", comment: "The sender has encrypted before")
......
......@@ -14,7 +14,7 @@ class ReplaceSegue: UIStoryboardSegue {
if let navigationController = source.navigationController {
var controllerStack = navigationController.viewControllers
let index = controllerStack.index(of: source)
let index = controllerStack.firstIndex(of: source)
controllerStack[index!] = destination
navigationController.setViewControllers(controllerStack, animated: true)
......
......@@ -45,6 +45,12 @@ extension String {
return components.filter { !$0.isEmpty }.joined(separator: " ")
}
func toBase64() -> Data? {
let components = self.components(separatedBy: .whitespacesAndNewlines)
let res = components.filter { !$0.isEmpty }.joined(separator: "")
return Data(base64Encoded: res)
}
func remove(seperatedBy: CharacterSet) -> String {
let components = self.components(separatedBy: seperatedBy)
return components.filter { !$0.isEmpty }.joined(separator: " ")
......
......@@ -92,7 +92,7 @@ class SwiftPGP: Encryption {
private var allSecretKeys: [Key]{
get{
var myKeys = Set<Key>()
if let keys = try? keychain.getString("secretKeys"){
if let keys = ((try? keychain.getString("secretKeys")) as String??){
if let keyIDs = keys{
for id in keyIDs.split(separator: ";"){
if let key = loadKey(id: String(id)){
......@@ -111,7 +111,7 @@ class SwiftPGP: Encryption {
let keyring = Keyring()
keyring.import(keys: [key])
let id = key.keyID.longIdentifier
if let testData = try? keychain.getData(id), testData != nil{
if let testData = ((try? keychain.getData(id)) as Data??), testData != nil{
// merge keys. i.e. secret key stored and key is public key.
if let keys = try? ObjectivePGP.readKeys(from: testData!){
keyring.import(keys: keys)
......@@ -123,7 +123,7 @@ class SwiftPGP: Encryption {
}
}
if key.isSecret{
if let keys = try? keychain.getString("secretKeys"){
if let keys = ((try? keychain.getString("secretKeys")) as String??){
if var ids = keys{
ids = ids + ";"+id
keychain["secretKeys"] = ids
......@@ -251,10 +251,11 @@ class SwiftPGP: Encryption {
var keys = [Key]()
var keyData: [Data] = []
if autocrypt{
var key = key
key = key.trimmed()
key = key.replacingOccurrences(of: " ", with: "")
keyData.append(ObjectivePGP.transformKey(key))
if let keyD = try? Armor.readArmored(key) {
keyData.append(keyD)
} else if let keyD = key.toBase64() {
keyData.append(keyD)
}
}
else {
var keyStrings = PGPPart.PUBLICKEY.findPGPPartInString(content: key)
......@@ -336,7 +337,7 @@ class SwiftPGP: Encryption {
func exportKey(id: String, isSecretkey isSecretKey: Bool, autocrypt: Bool, newPasscode: Bool = false) -> String?{
if let key = exportKeyData(id: id, isSecretkey: isSecretKey){
if !isSecretKey && autocrypt{
return key.base64EncodedString(options: .lineLength64Characters)
return key.base64EncodedString(options: .init(arrayLiteral: .lineLength76Characters, .endLineWithLineFeed))
}
else{
var armoredKey : String
......@@ -472,7 +473,8 @@ class SwiftPGP: Encryption {
}
}
if !signedAdr.contains(fromAdr) && sigState == SignatureState.ValidSignature {
sigState = .InvalidSignature
//sigState = .MissingFromAddr
// TODO: Have we
}
return CryptoObject(chiphertext: data, plaintext: nil, decryptedData: nil, sigState: sigState, encState: encState, signKey: sigKeyID, encType: .PGP, signedAdrs: signedAdr)
}
......@@ -488,6 +490,7 @@ class SwiftPGP: Encryption {
}
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
......@@ -535,7 +538,7 @@ class SwiftPGP: Encryption {
/*
VERIFICATION
*/
// test if message ist signed
// test if message is signed
sigState = verifySignature(data: data, attachedSignature: attachedSignature, keys: [])
for id in validDecryptionIDs {
if let key = loadKey(id: id) {
......@@ -586,16 +589,12 @@ class SwiftPGP: Encryption {
if let dataString = String(data: data, encoding: .utf8) {
do {
let unarmored = try Armor.readArmored(dataString)
if let plain = try? ObjectivePGP.decrypt(unarmored, andVerifySignature: true, using: keys, passphraseForKey: loadPassword){
if encForCurrentSK{
return (plain, EncryptionState.ValidedEncryptedWithCurrentKey)
}
else{
return(plain, EncryptionState.ValidEncryptedWithOldKey)
}
let plain = try ObjectivePGP.decrypt(unarmored, andVerifySignature: true, using: keys, passphraseForKey: loadPassword)
if encForCurrentSK{
return (plain, EncryptionState.ValidedEncryptedWithCurrentKey)
}
else{
return (nil, EncryptionState.UnableToDecrypt)
return(plain, EncryptionState.ValidEncryptedWithOldKey)
}
} catch {
let nsError = error as NSError
......@@ -631,6 +630,7 @@ class SwiftPGP: Encryption {
sigData = unarmored
}
let pubKeys = keys.filter{$0.isPublic}
do{
try ObjectivePGP.verify(sigData, withSignature: attachedSignature, using: pubKeys, passphraseForKey: loadPassword)
sigState = SignatureState.ValidSignature
......@@ -714,7 +714,7 @@ class SwiftPGP: Encryption {
pwKeyChain[key.keyID.longIdentifier] = pw
}
if let data = String("Test").data(using: .utf8) {
if let pw = try? pwKeyChain.get(key.keyID.longIdentifier), let _ = try? ObjectivePGP.sign(data, detached: false, using: [key], passphraseForKey: {(key) -> String? in return pw}) {
if let pw = ((try? pwKeyChain.get(key.keyID.longIdentifier)) as String??), let _ = try? ObjectivePGP.sign(data, detached: false, using: [key], passphraseForKey: {(key) -> String? in return pw}) {
return true
}
}
......@@ -737,7 +737,7 @@ class SwiftPGP: Encryption {
chiphers.append(Armor.armored(chipher, as: PGPArmorType.message))
}
else{
chiphers.append(chipher.base64EncodedString())
chiphers.append(chipher.base64EncodedString(options: .init(arrayLiteral: .lineLength76Characters, .endLineWithLineFeed)))
}
}
}
......
......@@ -88,7 +88,7 @@ public class TravelHandler {
public fileprivate(set) var mode: Mode {
get {
if let mode = try? travelKeyChain.getString("mode") {
if let mode = ((try? travelKeyChain.getString("mode")) as String??) {
if mode == "borderCrossing" {
return .borderCrossing
} else if mode == "traveling" {
......@@ -112,7 +112,7 @@ public class TravelHandler {
fileprivate var canSecurelyBackup: Bool {
get {
if let str = try? travelKeyChain.get("canSecurelyBackup"), let result = Bool(str ?? "true") {
if let str = ((try? travelKeyChain.get("canSecurelyBackup")) as String??), let result = Bool(str ?? "true") {
return result
}
return true
......@@ -124,7 +124,7 @@ public class TravelHandler {
fileprivate var backupKeyID: String? {
get {
if let result = try? travelKeyChain.get("backupKeyID") {
if let result = ((try? travelKeyChain.get("backupKeyID")) as String??) {
return result
}
return nil
......@@ -138,7 +138,7 @@ public class TravelHandler {
fileprivate var backupAddress: String? {
get {
if let result = try? travelKeyChain.get("backupAddress") {
if let result = ((try? travelKeyChain.get("backupAddress")) as String??) {
return result
}
return nil
......@@ -152,7 +152,7 @@ public class TravelHandler {
private var travelerStored: Data? {
get {
if let data = try? travelKeyChain.getData("travelerStored") {
if let data = ((try? travelKeyChain.getData("travelerStored")) as Data??) {
return data
}
return nil
......
......@@ -176,7 +176,6 @@ class IncomingMail {
private var misstrustNewKey = false
private var repealsKey: PersistentKey? = nil
// Crypto info
private var storeEncrypted = false
......@@ -349,7 +348,7 @@ class IncomingMail {
}
else if isSigned {
var inlineSigned = false
var signedStrings = extractSignedParts(data: msgParser.data())
var signedStrings = extractSignedParts(text: msgParser.plainTextBodyRendering())
if signedStrings.isEmpty {
signedStrings = IncomingMail.extractSignedMessage(text: body)
inlineSigned = true
......@@ -362,7 +361,7 @@ class IncomingMail {
else if signedStrings.count > 1 {
text = signedStrings.joined(separator: "\r\n")
}
if let signedData = text?.data(using: .utf8){
if let signedData = text?.data(using: .utf8){ // No Signed Data!
for sig in signaturesRaw {
if let signature = try? Armor.readArmored(sig), let adr = from?.mailbox {
for id in fromKeyIds {
......@@ -557,12 +556,17 @@ class IncomingMail {
}
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")
if let data = msgParser.data(), let text = String(data: data, encoding: .utf8) {
body = text
}
else {
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() {
......@@ -652,24 +656,21 @@ class IncomingMail {
private func parseUserReadableAttachments(parser: MCOMessageParser, sentEncrypted: Bool = false) -> Set<TempAttachment> {
var attachments = Set<TempAttachment>()
for at in parser.attachments() {
if let attachment = at as? MCOAttachment, let mimetype = MIMETYPE.findMIMETYPE(attachment: attachment) {
if let attachment = at as? MCOAttachment, let mimetype = MIMETYPE.findMIMETYPE(attachment: attachment), attachment.data.count > 0 {
if (mimetype == .travelUse || mimetype == .travelRepeal) && !sentEncrypted {
continue
}
attachments.insert(TempAttachment(name: attachment.filename, data: attachment.data, mimeType: mimetype))
var name = "untitled"
if let n = attachment.filename {
name = n
}
attachments.insert(TempAttachment(name: name, data: attachment.data, mimeType: mimetype))
}
}
return attachments
}
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)
......@@ -744,9 +745,9 @@ class IncomingMail {
// TODO: What about more signatures?
}
}
return (extractSignedParts(text: parser.plainTextBodyRendering()), sig)
}
return (extractSignedParts(data: data), sig)
return ([], sig)
}
private static func importPublicKeys(attachment: MCOAttachment) -> [String] {
......@@ -765,7 +766,8 @@ class IncomingMail {
private static func findKeys(attachment: MCOAttachment, type: PGPPart) -> [String]{
var keys: [String] = []
if let content = String(data: attachment.data, encoding: .utf8) {
// Maybe String(data: attachment.data, encoding: .utf8) ?
if let content = attachment.decodedString() {
keys.append(contentsOf: type.findPGPPartInString(content: content))
}
else if let content = attachment.decodedString() {
......@@ -799,7 +801,10 @@ class IncomingMail {
}
private static func extractPGPSignature(attachment: MCOAttachment) -> [String] {
if let content = String(data: attachment.data, encoding: .utf8) {
if let content = attachment.decodedString() {
return PGPPart.SIGNATURE.findPGPPartInString(content: content)
}
else if let content = String(data: attachment.data, encoding: .ascii){
return PGPPart.SIGNATURE.findPGPPartInString(content: content)
}
return []
......
......@@ -85,7 +85,7 @@
"port":587,
"hostname":"mail.zedat.fu-berlin.de",
"starttls":true,
"auth":"saslPlain"
"auth":"none"
}
]
},
......
......@@ -76,12 +76,32 @@ class AutocryptTest: XCTestCase {
super.tearDown()
}
func testMultiID() {
let key = importKey(file: "AliceMultiIDs (439EE43C) – Public")
do {
let x = try pgp.importKeys(key: key, pw: nil, isSecretKey: false, autocrypt: false)
XCTAssertEqual(x.count, 1)
if let newKey = x.first, let pgpKey = pgp.loadKey(id: newKey)?.publicKey {
XCTAssertEqual(pgpKey.users.count, 3)
XCTAssertTrue(pgpKey.users[0].userID.contains("alice@letterbox-app.org"))
XCTAssertTrue(pgpKey.users[1].userID.contains("alice2@letterbox-app.org"))
XCTAssertTrue(pgpKey.users[2].userID.contains("alice3@letterbox-app.org"))
}
else {
XCTFail("Key is missing.")
}
} catch {
XCTFail("No errors should arise when handling ecdsa keys!")
print(error)
}
}
func testAutocryptHeader(){
let outmail = OutgoingMail(toEntrys: ["alice@example.com"], ccEntrys: [], bccEntrys: [], subject: "subject", textContent: "Body", htmlContent: nil)
if let parser = MCOMessageParser(data: outmail.plainData), let key = pgp.exportKey(id: userKeyID, isSecretkey: false, autocrypt: true) {
if let parser = MCOMessageParser(data: outmail.plainData), let _ = pgp.exportKey(id: userKeyID, isSecretkey: false, autocrypt: false) {
let autocrypt = Autocrypt.init(header: parser.header)
XCTAssertEqual(autocrypt.addr, userAdr)
XCTAssertEqual(autocrypt.key.remove(seperatedBy: .whitespacesAndNewlines), key.remove(seperatedBy: .whitespacesAndNewlines))
XCTAssertEqual(autocrypt.prefer_encryption, EncState.MUTUAL)
do {
let autoKeyIds = try pgp.importKeys(key: autocrypt.key, pw: nil, isSecretKey: false, autocrypt: true)
......@@ -107,7 +127,6 @@ class AutocryptTest: XCTestCase {
let autocrypt = Autocrypt.init(header: parser.header)
XCTAssertEqual(autocrypt.addr, "alice@autocrypt.example")
XCTAssertEqual(autocrypt.prefer_encryption, EncState.MUTUAL)
XCTAssertEqual(autocrypt.key.remove(seperatedBy: .whitespacesAndNewlines), simpleAutocryptExample.remove(seperatedBy: .whitespacesAndNewlines))
do {
let autoKeyIds = try pgp.importKeys(key: autocrypt.key, pw: nil, isSecretKey: false, autocrypt: true)
XCTAssertEqual(autoKeyIds.first, "71DBC5657FDE65A7")
......@@ -135,4 +154,16 @@ class AutocryptTest: XCTestCase {
UserManager.storeUserValue(userid as AnyObject, attribute: Attribute.prefSecretKeyID)
return (user, userid)
}
func importKey(file: String, isSecretKey: Bool = false) -> String{
let bundle = Bundle(for: type(of: self))
do {
let plainKey = try String(contentsOf: bundle.url(forResource: file, withExtension: "asc")!)
return plainKey
} catch {
XCTFail()
}
XCTFail()
return ""
}
}
......@@ -591,6 +591,27 @@ class CryptoTests: XCTestCase {
return ""
}
func testImportMultiIDs(){
let key = importKey(file: "AliceMultiIDs (439EE43C) – Public")
do {
let x = try pgp.importKeys(key: key, pw: nil, isSecretKey: false, autocrypt: false)
XCTAssertEqual(x.count, 1)
if let newKey = x.first, let pgpKey = pgp.loadKey(id: newKey)?.publicKey {
XCTAssertEqual(pgpKey.users.count, 3)
XCTAssertTrue(pgpKey.users[0].userID.contains("alice@letterbox-app.org"))
XCTAssertTrue(pgpKey.users[1].userID.contains("alice2@letterbox-app.org"))
XCTAssertTrue(pgpKey.users[2].userID.contains("alice3@letterbox-app.org"))
}
else {
XCTFail("Key is missing.")
}
} catch {
XCTFail("No errors should arise when handling ecdsa keys!")
print(error)
}
}
func testImportEcDSAKey(){
let key = importKey(file: "EccAlice(777879D4)–Public")
do {
......@@ -601,6 +622,4 @@ class CryptoTests: XCTestCase {
print(error)
}
}
}
......@@ -294,7 +294,7 @@ class MailTest: XCTestCase {
testMailAliceToBob(name: "PlainMailFromMac", isSecure: false, encState: EncryptionState.NoEncryption, sigState: SignatureState.NoSignature)
}
func testMacSecureMail(){
testSecureMail(name: "SignedEncMailFromMac")
testSecureMail(name: "signedEncMailFromApple", letterboxAccounts: true)
}
func testMacEncMail(){
testMailAliceToBob(name: "EncMailFromMac", isSecure: false, encState: EncryptionState.ValidedEncryptedWithCurrentKey, sigState: SignatureState.NoSignature)
......@@ -305,20 +305,25 @@ class MailTest: XCTestCase {
func testSecureMail(name: String) {
testMailAliceToBob(name: name, isSecure: true)
func testSecureMail(name: String, letterboxAccounts: Bool = false) {
testMailAliceToBob(name: name, isSecure: true, encState: nil, sigState: nil, letterboxAccounts: letterboxAccounts)
}
func testMailAliceToBob(name: String, isSecure: Bool, encState: EncryptionState? = nil, sigState: SignatureState? = nil) {
testMailAliceToBob(pkExists: true, name: name, isSecure: isSecure, encState: encState, sigState: sigState)
tearDown()
setUp()
testMailAliceToBob(pkExists: false, name: name, isSecure: isSecure, encState: encState, sigState: sigState)
func testMailAliceToBob(name: String, isSecure: Bool, encState: EncryptionState? = nil, sigState: SignatureState? = nil, letterboxAccounts: Bool = false) {
testMailAliceToBob(pkExists: true, name: name, isSecure: isSecure, encState: encState, sigState: sigState, letterboxAccounts: letterboxAccounts)
if !letterboxAccounts {
//tearDown()
//setUp()
//testMailAliceToBob(pkExists: false, name: name, isSecure: isSecure, encState: encState, sigState: sigState, letterboxAccounts: letterboxAccounts)
}
}
func testMailAliceToBob(pkExists: Bool, name: String, isSecure: Bool, encState: EncryptionState? = nil, sigState: SignatureState? = nil) {
func testMailAliceToBob(pkExists: Bool, name: String, isSecure: Bool, encState: EncryptionState? = nil, sigState: SignatureState? = nil, letterboxAccounts: Bool = false) {
let mailData = MailTest.loadMail(name: name )
let (alice, _) = addAliceAndBob(addAlice: pkExists)
var (alice, _) = addAliceAndBob(addAlice: pkExists)
if letterboxAccounts {
(alice, _) = addAliceAndBobLetterbox(addAlice: pkExists)
}
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)
......@@ -342,7 +347,6 @@ class MailTest: XCTestCase {
else {
XCTFail("No body!")
}
XCTAssertTrue(MailTest.compareAdrs(adrs1: ["bob@enzevalos.de"], adrs2: mail.getReceivers()))
}
else {
XCTFail()
......@@ -359,6 +363,16 @@ class MailTest: XCTestCase {
return (aliceKeyId, bobKeyId)
}
func addAliceAndBobLetterbox(addAlice: Bool) -> (alice: String, bob: String){
let aliceKeyId = importKey(file: "Alice Letterbox (439EE43C) – Public", isSecretKey: false)
if addAlice {
_ = datahandler.newPublicKey(keyID: aliceKeyId, cryptoType: .PGP, adr: "alice@letterbox-app.org", autocrypt: false)
}
let bobKeyId = importKey(file: "Bob Letterbox (0B6CD0A0) – Secret", isSecretKey: true)
_ = datahandler.newSecretKey(keyID: bobKeyId, addPk: true)
return (aliceKeyId, bobKeyId)
}
static func compareAdrs(adrs1: [String], adrs2: [Mail_Address]) -> Bool{
for adr in adrs1 {
......
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
+GGOAsR8
=VbLb
-----END PGP PUBLIC KEY BLOCK-----
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
+GGOAsR8
=VbLb
-----END PGP PUBLIC KEY BLOCK-----
This diff is collapsed.
To: alice@letterbox-app.org
From: bob2@letterbox-app.org
Subject: Just a test with multiple IDs
Openpgp: preference=signencrypt
Autocrypt: addr=bob2@letterbox-app.org; prefer-encrypt=mutual; keydata=
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
Message-ID: <c3d22783-9412-51cf-8e9f-8e7e1b9f95ae@fu-berlin.de>
Date: Mon, 8 Jul 2019 15:04:39 -0700
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:60.0)
Gecko/20100101 Thunderbird/60.7.2
MIME-Version: 1.0
Content-Type: multipart/encrypted;
protocol="application/pgp-encrypted";
boundary="MxGECkkeaFzqHNQokdvc33gD14tyRz8UM"
This is an OpenPGP/MIME encrypted message (RFC 4880 and 3156)
--MxGECkkeaFzqHNQokdvc33gD14tyRz8UM
Content-Type: application/pgp-encrypted
Content-Description: PGP/MIME version identification
Version: 1
--MxGECkkeaFzqHNQokdvc33gD14tyRz8UM
Content-Type: application/octet-stream; name="encrypted.asc"
Content-Description: OpenPGP encrypted message
Content-Disposition: inline; filename="encrypted.asc"
-----BEGIN PGP MESSAGE-----
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
F5DaTh+djiKBxFuOWbAVZA==
=FOvv
-----END PGP MESSAGE-----
--MxGECkkeaFzqHNQokdvc33gD14tyRz8UM--
Return-path: <alice@letterbox-app.org>
Delivery-date: Tue, 09 Jul 2019 00:54:44 +0200
From: Alice <alice@letterbox-app.org>
Content-Type: multipart/encrypted;
boundary="Apple-Mail=_EB25342D-955E-4D47-B80A-ECDD442080C9";
protocol="application/pgp-encrypted"
Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\))
Subject: Just a signed and enc mail from AppleMail
Message-Id: <63D835DE-72FF-4C72-9D9A-BE68E833D2D8@letterbox-app.org>
Date: Mon, 8 Jul 2019 15:54:39 -0700
To: bob@letterbox-app.org
X-Mailer: Apple Mail (2.3445.104.11)
X-Originating-IP: 206.87.152.212
X-purgate: clean
X-purgate-type: clean
X-purgate-ID: 151147::1562626482-000A053C-0511A2D3/0/0
X-Bogosity: Ham, tests=bogofilter, spamicity=0.357558, version=1.2.4
X-Spam-Flag: NO
X-Spam-Status: No, score=-51.0 required=8.0 tests=ALL_TRUSTED,ENCRYPTED_MESSAGE
X-Spam-Checker-Version: SpamAssassin 3.4.2 on Palau.ZEDAT.FU-Berlin.DE
X-ZEDAT-Hint: AV
This is an OpenPGP/MIME encrypted message (RFC 2440 and 3156)
--Apple-Mail=_EB25342D-955E-4D47-B80A-ECDD442080C9
Content-Transfer-Encoding: 7bit
Content-Type: application/pgp-encrypted
Content-Description: PGP/MIME Versions Identification
Version: 1
--Apple-Mail=_EB25342D-955E-4D47-B80A-ECDD442080C9
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename=encrypted.asc
Content-Type: application/octet-stream;
name=encrypted.asc
Content-Description: OpenPGP encrypted message
-----BEGIN PGP MESSAGE-----
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
3tWLMA==
=fyCj
-----END PGP MESSAGE-----
--Apple-Mail=_EB25342D-955E-4D47-B80A-ECDD442080C9--
......@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
......@@ -16,8 +16,6 @@
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
......
......@@ -2,19 +2,8 @@
// enzevalos_iphoneUITests.swift
// enzevalos_iphoneUITests
//
// Created by jakobsbode on 23.09.16.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// Created by Oliver Wiese on 05.06.19.
// Copyright © 2019 fu-berlin. All rights reserved.
//
import XCTest
......@@ -22,12 +11,11 @@ import XCTest
class enzevalos_iphoneUITests: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
// In UI tests it is usually best to stop immediately when a failure occurs.
continueAfterFailure = false
// UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
XCUIApplication().launch()
......@@ -36,7 +24,6 @@ class enzevalos_iphoneUITests: XCTestCase {
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
......