Polish logics about PGP passphrase

- Ask passphrase only when users want to save them for later usage
- Provide a second change to enter passphrase during the decryption
This commit is contained in:
Yishi Lin 2017-06-07 21:11:01 +08:00
parent 0542733f86
commit 2388edccfb
5 changed files with 104 additions and 105 deletions

View file

@ -107,20 +107,6 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
scanPrivateKeyCell?.accessoryType = .disclosureIndicator scanPrivateKeyCell?.accessoryType = .disclosureIndicator
} }
private func createSavePassphraseAndSegueAlert() -> UIAlertController {
let savePassphraseAlert = UIAlertController(title: "Passphrase", message: "Do you want to save the passphrase for later decryption?", preferredStyle: UIAlertControllerStyle.alert)
savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in
Defaults[.isRememberPassphraseOn] = false
self.pgpPassphrase = nil
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
})
savePassphraseAlert.addAction(UIAlertAction(title: "Save", style: UIAlertActionStyle.destructive) {_ in
Defaults[.isRememberPassphraseOn] = true
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
})
return savePassphraseAlert
}
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
if identifier == "savePGPKeySegue" { if identifier == "savePGPKeySegue" {
if armorPublicKeyTextView.text.isEmpty { if armorPublicKeyTextView.text.isEmpty {
@ -136,17 +122,29 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
} }
@IBAction func save(_ sender: Any) { @IBAction func save(_ sender: Any) {
let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert) let savePassphraseAlert = UIAlertController(title: "Passphrase", message: "Do you want to save the passphrase for later decryption?", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in // no
self.pgpPassphrase = alert.textFields?.first?.text savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in
let savePassphraseAndSegueAlert = self.createSavePassphraseAndSegueAlert() self.pgpPassphrase = nil
self.present(savePassphraseAndSegueAlert, animated: true, completion: nil) Defaults[.isRememberPassphraseOn] = false
})) self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
alert.addTextField(configurationHandler: {(textField: UITextField!) in
textField.text = self.pgpPassphrase
textField.isSecureTextEntry = true
}) })
self.present(alert, animated: true, completion: nil) // yes
savePassphraseAlert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.destructive) {_ in
// ask for the passphrase
let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
self.pgpPassphrase = alert.textFields?.first?.text
Defaults[.isRememberPassphraseOn] = true
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
}))
alert.addTextField(configurationHandler: {(textField: UITextField!) in
textField.text = self.pgpPassphrase
textField.isSecureTextEntry = true
})
self.present(alert, animated: true, completion: nil)
})
self.present(savePassphraseAlert, animated: true, completion: nil)
} }
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {

View file

@ -24,19 +24,6 @@ class PGPKeySettingTableViewController: UITableViewController {
pgpPassphrase = passwordStore.pgpKeyPassphrase pgpPassphrase = passwordStore.pgpKeyPassphrase
} }
private func createSavePassphraseAndSegueAlert() -> UIAlertController {
let savePassphraseAlert = UIAlertController(title: "Passphrase", message: "Do you want to save the passphrase for later decryption?", preferredStyle: UIAlertControllerStyle.alert)
savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in
Defaults[.isRememberPassphraseOn] = false
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
})
savePassphraseAlert.addAction(UIAlertAction(title: "Save", style: UIAlertActionStyle.destructive) {_ in
Defaults[.isRememberPassphraseOn] = true
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
})
return savePassphraseAlert
}
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
if identifier == "savePGPKeySegue" { if identifier == "savePGPKeySegue" {
guard validatePGPKeyURL(input: pgpPublicKeyURLTextField.text) == true, guard validatePGPKeyURL(input: pgpPublicKeyURLTextField.text) == true,
@ -60,16 +47,28 @@ class PGPKeySettingTableViewController: UITableViewController {
} }
@IBAction func save(_ sender: Any) { @IBAction func save(_ sender: Any) {
let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert) let savePassphraseAlert = UIAlertController(title: "Passphrase", message: "Do you want to save the passphrase for later decryption?", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in // no
self.pgpPassphrase = alert.textFields?.first?.text savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in
let savePassphraseAndSegueAlert = self.createSavePassphraseAndSegueAlert() self.pgpPassphrase = nil
self.present(savePassphraseAndSegueAlert, animated: true, completion: nil) Defaults[.isRememberPassphraseOn] = false
})) self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
alert.addTextField(configurationHandler: {(textField: UITextField!) in
textField.text = self.pgpPassphrase
textField.isSecureTextEntry = true
}) })
self.present(alert, animated: true, completion: nil) // yes
savePassphraseAlert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.destructive) {_ in
// ask for the passphrase
let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
self.pgpPassphrase = alert.textFields?.first?.text
Defaults[.isRememberPassphraseOn] = true
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
}))
alert.addTextField(configurationHandler: {(textField: UITextField!) in
textField.text = self.pgpPassphrase
textField.isSecureTextEntry = true
})
self.present(alert, animated: true, completion: nil)
})
self.present(savePassphraseAlert, animated: true, completion: nil)
} }
} }

View file

@ -155,9 +155,15 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
DispatchQueue.main.async { DispatchQueue.main.async {
// remove the wrong passphrase so that users could enter it next time // remove the wrong passphrase so that users could enter it next time
self.passwordStore.pgpKeyPassphrase = nil self.passwordStore.pgpKeyPassphrase = nil
Utils.alert(title: "Cannot Show Password", message: error.localizedDescription, controller: self, handler: {(UIAlertAction) -> Void in // alert: cancel or try again
let alert = UIAlertController(title: "Cannot Show Password", message: error.localizedDescription, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.default) { _ in
self.navigationController!.popViewController(animated: true) self.navigationController!.popViewController(animated: true)
}) })
alert.addAction(UIAlertAction(title: "Try again", style: UIAlertActionStyle.destructive) {_ in
self.decryptThenShowPassword()
})
self.present(alert, animated: true, completion: nil)
} }
return return
} }

View file

@ -92,6 +92,30 @@ class SettingsTableViewController: UITableViewController {
} }
} }
private func saveImportedPGPKey() {
// load keys
Defaults[.pgpKeySource] = "file"
SVProgressHUD.setDefaultMaskType(.black)
SVProgressHUD.setDefaultStyle(.light)
SVProgressHUD.show(withStatus: "Fetching PGP Key")
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
do {
try self.passwordStore.initPGPKeys()
DispatchQueue.main.async {
self.pgpKeyTableViewCell.detailTextLabel?.text = self.passwordStore.pgpKeyID
SVProgressHUD.showSuccess(withStatus: "Success")
SVProgressHUD.dismiss(withDelay: 1)
}
} catch {
DispatchQueue.main.async {
self.pgpKeyTableViewCell.detailTextLabel?.text = "Not Set"
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
}
}
}
}
@IBAction func cancelGitServerSetting(segue: UIStoryboardSegue) { @IBAction func cancelGitServerSetting(segue: UIStoryboardSegue) {
} }
@ -233,55 +257,31 @@ class SettingsTableViewController: UITableViewController {
if passwordStore.pgpKeyExists() { if passwordStore.pgpKeyExists() {
let fileAction = UIAlertAction(title: fileActionTitle, style: .default) { _ in let fileAction = UIAlertAction(title: fileActionTitle, style: .default) { _ in
// passphrase related
SVProgressHUD.setDefaultMaskType(.black) let savePassphraseAlert = UIAlertController(title: "Passphrase", message: "Do you want to save the passphrase for later decryption?", preferredStyle: UIAlertControllerStyle.alert)
SVProgressHUD.setDefaultStyle(.light) // no
SVProgressHUD.show(withStatus: "Reading PGP key") savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in
self.passwordStore.pgpKeyPassphrase = nil
let alert = UIAlertController( Defaults[.isRememberPassphraseOn] = false
title: "PGP Passphrase", self.saveImportedPGPKey()
message: "Please fill in the passphrase for your PGP key.", })
preferredStyle: UIAlertControllerStyle.alert // yes
) savePassphraseAlert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.destructive) {_ in
// ask for the passphrase
alert.addAction( let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert)
UIAlertAction( alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
title: "OK", self.passwordStore.pgpKeyPassphrase = alert.textFields?.first?.text
style: UIAlertActionStyle.default, Defaults[.isRememberPassphraseOn] = true
handler: {_ in self.saveImportedPGPKey()
Utils.addPasswordToKeychain( }))
name: "pgpKeyPassphrase", alert.addTextField(configurationHandler: {(textField: UITextField!) in
password: alert.textFields!.first!.text! textField.text = ""
) textField.isSecureTextEntry = true
} })
) self.present(alert, animated: true, completion: nil)
) })
self.present(savePassphraseAlert, animated: true, completion: nil)
alert.addTextField(
configurationHandler: {(textField: UITextField!) in
textField.text = Utils.getPasswordFromKeychain(name: "pgpKeyPassphrase") ?? ""
textField.isSecureTextEntry = true
}
)
DispatchQueue.main.async {
self.passwordStore.initPGPKeys()
let key: PGPKey = self.passwordStore.getPgpPrivateKey()
Defaults[.pgpKeySource] = "file"
if (key.isEncrypted) {
SVProgressHUD.dismiss()
self.present(alert, animated: true, completion: nil)
}
SVProgressHUD.dismiss()
self.pgpKeyTableViewCell.detailTextLabel?.text = self.passwordStore.pgpKeyID
}
} }
optionMenu.addAction(fileAction) optionMenu.addAction(fileAction)
} else { } else {
let fileAction = UIAlertAction(title: "iTunes File Sharing", style: .default) { _ in let fileAction = UIAlertAction(title: "iTunes File Sharing", style: .default) { _ in

View file

@ -93,10 +93,10 @@ class PasswordStore {
if FileManager.default.fileExists(atPath: storeURL.path) { if FileManager.default.fileExists(atPath: storeURL.path) {
try storeRepository = GTRepository.init(url: storeURL) try storeRepository = GTRepository.init(url: storeURL)
} }
try initPGPKeys()
} catch { } catch {
print(error) print(error)
} }
initPGPKeys()
} }
enum SSHKeyType { enum SSHKeyType {
@ -111,13 +111,9 @@ class PasswordStore {
try armorKey.write(toFile: keyPath, atomically: true, encoding: .ascii) try armorKey.write(toFile: keyPath, atomically: true, encoding: .ascii)
} }
public func initPGPKeys() { public func initPGPKeys() throws {
do { try initPGPKey(.public)
try initPGPKey(.public) try initPGPKey(.secret)
try initPGPKey(.secret)
} catch {
print(error)
}
} }
public func initPGPKey(_ keyType: PGPKeyType) throws { public func initPGPKey(_ keyType: PGPKeyType) throws {
@ -139,7 +135,7 @@ class PasswordStore {
} }
} }
public func initPGPKey(from url: URL, keyType: PGPKeyType) throws{ public func initPGPKey(from url: URL, keyType: PGPKeyType) throws {
var pgpKeyLocalPath = "" var pgpKeyLocalPath = ""
if keyType == .public { if keyType == .public {
pgpKeyLocalPath = Globals.pgpPublicKeyPath pgpKeyLocalPath = Globals.pgpPublicKeyPath