Scan QR codes to insert PGP ascii-armor keys
This commit is contained in:
parent
d1393c6d36
commit
750532850a
2 changed files with 276 additions and 79 deletions
|
|
@ -9,19 +9,102 @@
|
|||
import UIKit
|
||||
import SwiftyUserDefaults
|
||||
|
||||
class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDelegate {
|
||||
class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDelegate, QRScannerControllerDelegate {
|
||||
@IBOutlet weak var armorPublicKeyTextView: UITextView!
|
||||
@IBOutlet weak var armorPrivateKeyTextView: UITextView!
|
||||
@IBOutlet weak var scanPublicKeyCell: UITableViewCell!
|
||||
@IBOutlet weak var scanPrivateKeyCell: UITableViewCell!
|
||||
|
||||
var pgpPassphrase: String?
|
||||
let passwordStore = PasswordStore.shared
|
||||
|
||||
private var recentPastedText = ""
|
||||
|
||||
class ScannedPGPKey {
|
||||
static let maxNumberOfGif = 100
|
||||
enum KeyType {
|
||||
case publicKey, privateKey
|
||||
}
|
||||
var keyType = KeyType.publicKey
|
||||
var numberOfSegments = 0
|
||||
var previousSegment = ""
|
||||
var key = ""
|
||||
var message = ""
|
||||
var hasStarted = false
|
||||
var isDone = false
|
||||
|
||||
func reset(keytype: KeyType) {
|
||||
self.keyType = keytype
|
||||
numberOfSegments = 0
|
||||
previousSegment = ""
|
||||
key = ""
|
||||
message = "Looking for the starting frame."
|
||||
hasStarted = false
|
||||
isDone = false
|
||||
}
|
||||
|
||||
func addSegment(segment: String) {
|
||||
// skip duplicated segments
|
||||
guard segment != previousSegment else {
|
||||
return
|
||||
}
|
||||
previousSegment = segment
|
||||
|
||||
// check whether we have found the first block
|
||||
if hasStarted == false {
|
||||
let findPublic = segment.contains("-----BEGIN PGP PUBLIC KEY BLOCK-----")
|
||||
let findPrivate = segment.contains("-----BEGIN PGP PRIVATE KEY BLOCK-----")
|
||||
switch keyType {
|
||||
case .publicKey:
|
||||
if findPrivate {
|
||||
message = "Please scan public key."
|
||||
}
|
||||
hasStarted = findPublic
|
||||
case .privateKey:
|
||||
if findPublic {
|
||||
message = "Please scan private key."
|
||||
}
|
||||
hasStarted = findPrivate
|
||||
}
|
||||
}
|
||||
guard hasStarted == true else {
|
||||
return
|
||||
}
|
||||
|
||||
// check the number of segments
|
||||
numberOfSegments = numberOfSegments + 1
|
||||
guard numberOfSegments <= ScannedPGPKey.maxNumberOfGif else {
|
||||
key = "Too many QR codes"
|
||||
return
|
||||
}
|
||||
|
||||
// update full text and check whether we are done
|
||||
key.append(segment)
|
||||
if key.contains("-----END PGP PUBLIC KEY BLOCK-----") || key.contains("-----END PGP PRIVATE KEY BLOCK-----") {
|
||||
isDone = true
|
||||
}
|
||||
|
||||
// update message
|
||||
message = "\(numberOfSegments) scanned QR codes."
|
||||
}
|
||||
}
|
||||
var scanned = ScannedPGPKey()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
armorPublicKeyTextView.text = Defaults[.pgpPublicKeyArmor]
|
||||
armorPrivateKeyTextView.text = Defaults[.pgpPrivateKeyArmor]
|
||||
pgpPassphrase = passwordStore.pgpKeyPassphrase
|
||||
|
||||
scanPublicKeyCell?.textLabel?.text = "Scan Public Key QR Codes"
|
||||
scanPublicKeyCell?.textLabel?.textColor = Globals.blue
|
||||
scanPublicKeyCell?.selectionStyle = .default
|
||||
scanPublicKeyCell?.accessoryType = .disclosureIndicator
|
||||
|
||||
scanPrivateKeyCell?.textLabel?.text = "Scan Private Key QR Codes"
|
||||
scanPrivateKeyCell?.textLabel?.textColor = Globals.blue
|
||||
scanPrivateKeyCell?.selectionStyle = .default
|
||||
scanPrivateKeyCell?.accessoryType = .disclosureIndicator
|
||||
}
|
||||
|
||||
private func createSavePassphraseAndSegueAlert() -> UIAlertController {
|
||||
|
|
@ -79,4 +162,53 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
|
|||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
let selectedCell = tableView.cellForRow(at: indexPath)
|
||||
if selectedCell == scanPublicKeyCell {
|
||||
scanned.reset(keytype: ScannedPGPKey.KeyType.publicKey)
|
||||
self.performSegue(withIdentifier: "showPGPScannerSegue", sender: self)
|
||||
} else if selectedCell == scanPrivateKeyCell {
|
||||
scanned.reset(keytype: ScannedPGPKey.KeyType.privateKey)
|
||||
self.performSegue(withIdentifier: "showPGPScannerSegue", sender: self)
|
||||
}
|
||||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
}
|
||||
|
||||
// MARK: - QRScannerControllerDelegate Methods
|
||||
func checkScannedOutput(line: String) -> (accept: Bool, message: String) {
|
||||
scanned.addSegment(segment: line)
|
||||
if scanned.isDone {
|
||||
return (accept: true, message: "Done")
|
||||
} else {
|
||||
return (accept: false, message: scanned.message)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - QRScannerControllerDelegate Methods
|
||||
func handleScannedOutput(line: String) {
|
||||
switch scanned.keyType {
|
||||
case .publicKey:
|
||||
armorPublicKeyTextView.text = scanned.key
|
||||
case .privateKey:
|
||||
armorPrivateKeyTextView.text = scanned.key
|
||||
}
|
||||
}
|
||||
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
if segue.identifier == "showPGPScannerSegue" {
|
||||
if let navController = segue.destination as? UINavigationController {
|
||||
if let viewController = navController.topViewController as? QRScannerController {
|
||||
viewController.delegate = self
|
||||
}
|
||||
} else if let viewController = segue.destination as? QRScannerController {
|
||||
viewController.delegate = self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction private func cancelPGPScanner(segue: UIStoryboardSegue) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue