Add ability to import PGP keys from the Files app

This commit is contained in:
Danny Moesch 2020-02-09 14:13:51 +01:00 committed by Mingshen Sun
parent 5f6723246b
commit e0c9ceb4fd
9 changed files with 285 additions and 12 deletions

View file

@ -13,6 +13,7 @@
301F6463216162550071A4CE /* AdditionField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301F6462216162550071A4CE /* AdditionField.swift */; };
301F6468216165290071A4CE /* ConstantsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301F6467216165290071A4CE /* ConstantsTest.swift */; };
301F646D216166AA0071A4CE /* AdditionFieldTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301F646C216166AA0071A4CE /* AdditionFieldTest.swift */; };
302269B323E634B000F843A3 /* PGPKeyFileSettingTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302269B223E634B000F843A3 /* PGPKeyFileSettingTableViewController.swift */; };
302B2C9822C2BDE700D831EE /* AppKeychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302B2C9722C2BDE700D831EE /* AppKeychain.swift */; };
302E85612125ECC70031BA64 /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302E85602125ECC70031BA64 /* Parser.swift */; };
302E85632125EE550031BA64 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302E85622125EE550031BA64 /* Constants.swift */; };
@ -233,6 +234,7 @@
301F6467216165290071A4CE /* ConstantsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConstantsTest.swift; sourceTree = "<group>"; };
301F646C216166AA0071A4CE /* AdditionFieldTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdditionFieldTest.swift; sourceTree = "<group>"; };
302202EE222F14E400555236 /* SearchBarScope.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchBarScope.swift; sourceTree = "<group>"; };
302269B223E634B000F843A3 /* PGPKeyFileSettingTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PGPKeyFileSettingTableViewController.swift; sourceTree = "<group>"; };
302B2C9722C2BDE700D831EE /* AppKeychain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppKeychain.swift; sourceTree = "<group>"; };
302E85602125ECC70031BA64 /* Parser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Parser.swift; sourceTree = "<group>"; };
302E85622125EE550031BA64 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
@ -717,6 +719,7 @@
DCFB77A81E502FF6008DE471 /* PasswordEditorTableViewController.swift */,
DC5734AD1E439AD400D09270 /* PasswordsViewController.swift */,
DC5F385A1E56AADB00C69ACA /* PGPKeyArmorSettingTableViewController.swift */,
302269B223E634B000F843A3 /* PGPKeyFileSettingTableViewController.swift */,
3066AD6723EE0D6500F65535 /* PGPKeyImporter.swift */,
DCA0499B1E3362F400522E8F /* PGPKeyUrlTableViewController.swift */,
A2A7813E1E97DBD9001311F5 /* QRScannerController.swift */,
@ -1401,6 +1404,7 @@
30C25DD721F4834D00BB27BB /* UILocalizedLabel.swift in Sources */,
DC5734AE1E439AD400D09270 /* PasswordsViewController.swift in Sources */,
300713C52219D54100F553AC /* AutoCellHeightUITableViewController.swift in Sources */,
302269B323E634B000F843A3 /* PGPKeyFileSettingTableViewController.swift in Sources */,
DCD3C65E1EFB9BB400CBE842 /* SettingsSplitViewController.swift in Sources */,
A20691F41F2A3D0E0096483D /* SecurePasteboard.swift in Sources */,
DC3E64E61E656F11009A83DE /* CommitLogsTableViewController.swift in Sources */,

View file

@ -241,6 +241,7 @@
<outlet property="pgpKeyTableViewCell" destination="1ze-MS-Xbj" id="hXe-eD-0R4"/>
<segue destination="ZUt-x1-TJu" kind="showDetail" identifier="setPGPKeyByURLSegue" id="qRF-S1-bqF"/>
<segue destination="ffY-rC-jhq" kind="showDetail" identifier="setPGPKeyByASCIISegue" id="mgi-Oe-i2X"/>
<segue destination="Ap7-WQ-eEv" kind="showDetail" identifier="setPGPKeyByFileSegue" id="mnn-a5-KNj"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="leR-cc-QPW" userLabel="First Responder" sceneMemberID="firstResponder"/>
@ -500,7 +501,7 @@
<placeholder placeholderIdentifier="IBFirstResponder" id="7c1-c7-Qyp" userLabel="First Responder" sceneMemberID="firstResponder"/>
<exit id="7K9-cE-9qq" userLabel="Exit" sceneMemberID="exit"/>
</objects>
<point key="canvasLocation" x="4954" y="2499"/>
<point key="canvasLocation" x="6083" y="2239"/>
</scene>
<!--PGP Key-->
<scene sceneID="8Hi-tl-elT">
@ -630,7 +631,7 @@
<placeholder placeholderIdentifier="IBFirstResponder" id="hbx-RC-qg1" userLabel="First Responder" sceneMemberID="firstResponder"/>
<exit id="jjl-Xi-fkn" userLabel="Exit" sceneMemberID="exit"/>
</objects>
<point key="canvasLocation" x="4954" y="3510"/>
<point key="canvasLocation" x="4954" y="3668"/>
</scene>
<!--Add Password-->
<scene sceneID="738-Zk-wRb">
@ -940,7 +941,7 @@ Secret Question 1: What is your childhood best friend's most bizarre superhero f
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="kr5-iH-doj" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="3845" y="2499"/>
<point key="canvasLocation" x="3845" y="2240"/>
</scene>
<!--SSH Key-->
<scene sceneID="7pC-mh-aE6">
@ -1034,7 +1035,7 @@ Secret Question 1: What is your childhood best friend's most bizarre superhero f
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="eY3-aM-BJB" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="6083" y="2187"/>
<point key="canvasLocation" x="6990" y="2239"/>
</scene>
<!--General-->
<scene sceneID="fho-xr-1Ah">
@ -1075,7 +1076,7 @@ Secret Question 1: What is your childhood best friend's most bizarre superhero f
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="bVY-G2-9Ud" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="3845" y="3510"/>
<point key="canvasLocation" x="3845" y="3668"/>
</scene>
<!--Advanced-->
<scene sceneID="ipZ-fd-H8e">
@ -1431,7 +1432,7 @@ Secret Question 1: What is your childhood best friend's most bizarre superhero f
<placeholder placeholderIdentifier="IBFirstResponder" id="2Wn-7D-LLj" userLabel="First Responder" sceneMemberID="firstResponder"/>
<exit id="Ul9-vk-jhw" userLabel="Exit" sceneMemberID="exit"/>
</objects>
<point key="canvasLocation" x="4954" y="4304"/>
<point key="canvasLocation" x="4954" y="4427"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="m18-ch-m92">
@ -1449,7 +1450,7 @@ Secret Question 1: What is your childhood best friend's most bizarre superhero f
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="511-eg-7fa" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="3845" y="4304"/>
<point key="canvasLocation" x="3845" y="4428"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="Ps2-MC-JQX">
@ -1561,7 +1562,7 @@ Secret Question 1: What is your childhood best friend's most bizarre superhero f
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="qJO-AN-K9p" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="6083" y="2895"/>
<point key="canvasLocation" x="6083" y="3668"/>
</scene>
<!--Git Signature-->
<scene sceneID="eTh-B3-0rv">
@ -1676,7 +1677,7 @@ Secret Question 1: What is your childhood best friend's most bizarre superhero f
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="scanner output" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="U8O-Md-w8e">
<rect key="frame" x="57" y="562" width="300" height="45"/>
<rect key="frame" x="57" y="513" width="300" height="45"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.5" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="300" id="JcM-Sy-Hw8"/>
@ -1700,7 +1701,7 @@ Secret Question 1: What is your childhood best friend's most bizarre superhero f
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="I2W-rx-CxX" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="6083" y="4304"/>
<point key="canvasLocation" x="6083" y="4427"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="Hf2-tj-DSK">
@ -1756,6 +1757,123 @@ Secret Question 1: What is your childhood best friend's most bizarre superhero f
</objects>
<point key="canvasLocation" x="3844.9275362318845" y="5331.521739130435"/>
</scene>
<!--PGP Key-->
<scene sceneID="KZQ-sz-cea">
<objects>
<tableViewController id="zh0-O0-5kJ" customClass="PGPKeyFileSettingTableViewController" customModule="pass" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="1Zw-MV-6BD">
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<sections>
<tableViewSection id="SX5-yS-bhP">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="pgpKeysFromFilesDescription" textLabel="XU8-Io-n0h" detailTextLabel="TZc-n7-f0y" style="IBUITableViewCellStyleSubtitle" id="RiO-JR-Xax">
<rect key="frame" x="0.0" y="18" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="RiO-JR-Xax" id="NYK-IE-MDP">
<rect key="frame" x="0.0" y="0.0" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Import Keys From Files" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="XU8-Io-n0h">
<rect key="frame" x="20" y="6" width="155" height="17"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="14"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="GpgAsciiArmorFileExplanation." lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="TZc-n7-f0y" customClass="UICodeHighlightingLabel" customModule="pass" customModuleProvider="target">
<rect key="frame" x="20" y="23" width="180.33333333333334" height="15.333333333333334"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" name="HelveticaNeue" family="Helvetica Neue" pointSize="13"/>
<color key="textColor" red="0.29804000000000003" green="0.29804000000000003" blue="0.29804000000000003" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</cells>
</tableViewSection>
<tableViewSection headerTitle="PUBLIC KEY" id="Y8H-cb-G2j">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="pgpPublicKeyFile" textLabel="XVY-Dj-6Mx" rowHeight="61" style="IBUITableViewCellStyleDefault" id="2TD-Vi-g4T">
<rect key="frame" x="0.0" y="118" width="414" height="61"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="2TD-Vi-g4T" id="RLf-Tg-LcS">
<rect key="frame" x="0.0" y="0.0" width="383" height="61"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Select file ..." textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="XVY-Dj-6Mx">
<rect key="frame" x="20" y="0.0" width="355" height="61"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</cells>
</tableViewSection>
<tableViewSection headerTitle="PRIVATE KEY" id="RFc-J6-hAe">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="pgpPrivateKeyFile" textLabel="Ka2-8Z-fwx" rowHeight="61" style="IBUITableViewCellStyleDefault" id="tT1-V9-E5r">
<rect key="frame" x="0.0" y="235" width="414" height="61"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="tT1-V9-E5r" id="cpU-gf-Vk0">
<rect key="frame" x="0.0" y="0.0" width="383" height="61"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Select file ..." textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Ka2-8Z-fwx">
<rect key="frame" x="20" y="0.0" width="355" height="61"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</cells>
</tableViewSection>
</sections>
</tableView>
<navigationItem key="navigationItem" title="PGP Key" largeTitleDisplayMode="never" id="waZ-gh-rQt">
<barButtonItem key="rightBarButtonItem" style="done" systemItem="save" id="Kdo-Af-80m">
<connections>
<action selector="save:" destination="zh0-O0-5kJ" id="4x2-eq-c6q"/>
</connections>
</barButtonItem>
</navigationItem>
<connections>
<outlet property="pgpPrivateKeyFile" destination="tT1-V9-E5r" id="i4n-ZH-UrB"/>
<outlet property="pgpPublicKeyFile" destination="2TD-Vi-g4T" id="66Q-mv-BfN"/>
<segue destination="fAK-1W-69n" kind="unwind" identifier="savePGPKeySegue" unwindAction="savePGPKeyWithSegue:" id="sdz-aM-0Pc"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="91Z-PM-MEr" userLabel="First Responder" sceneMemberID="firstResponder"/>
<exit id="fAK-1W-69n" userLabel="Exit" sceneMemberID="exit"/>
</objects>
<point key="canvasLocation" x="4954" y="2968"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="2mO-L4-uGj">
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="Ap7-WQ-eEv" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="uY3-dJ-5Pj">
<rect key="frame" x="0.0" y="0.0" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
<connections>
<segue destination="zh0-O0-5kJ" kind="relationship" relationship="rootViewController" id="nZf-qO-e37"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="G3o-et-5l9" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="3845" y="2969"/>
</scene>
</scenes>
<resources>
<image name="Lock" width="25" height="25"/>
@ -1763,7 +1881,7 @@ Secret Question 1: What is your childhood best friend's most bizarre superhero f
</resources>
<inferredMetricsTieBreakers>
<segue reference="wCk-aN-a4J"/>
<segue reference="5iZ-y9-FCH"/>
<segue reference="oxP-I1-Mke"/>
<segue reference="yyD-4H-pLE"/>
</inferredMetricsTieBreakers>
</document>

View file

@ -0,0 +1,106 @@
//
// PGPKeyFileSettingTableViewController.swift
// pass
//
// Created by Danny Moesch on 01.02.20.
// Copyright © 2020 Bob Sun. All rights reserved.
//
import passKit
class PGPKeyFileSettingTableViewController: AutoCellHeightUITableViewController {
@IBOutlet weak var pgpPublicKeyFile: UITableViewCell!
@IBOutlet weak var pgpPrivateKeyFile: UITableViewCell!
private let passwordStore = PasswordStore.shared
private let keychain = AppKeychain.shared
private var publicKey: String? = nil
private var privateKey: String? = nil
private enum KeyType { case none, `private`, `public` }
private var currentlyPicking = KeyType.none
@IBAction func save(_ sender: Any) {
savePassphraseDialog()
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
let picker = UIDocumentPickerViewController(documentTypes: ["public.data"], in: .import)
if cell == pgpPublicKeyFile {
currentlyPicking = .public
} else if cell == pgpPrivateKeyFile {
currentlyPicking = .private
} else {
return
}
picker.delegate = self
if #available(iOS 13.0, *) {
picker.shouldShowFileExtensions = true
}
present(picker, animated: true, completion: nil)
}
}
extension PGPKeyFileSettingTableViewController: UIDocumentPickerDelegate {
func documentPicker(_: UIDocumentPickerViewController, didPickDocumentsAt url: [URL]) {
guard let url = url.first else {
return
}
let fileName = url.lastPathComponent
do {
let fileContent = try String(contentsOf: url, encoding: .ascii)
switch currentlyPicking {
case .none:
return
case .public:
publicKey = fileContent
pgpPublicKeyFile.textLabel?.text = fileName
case .private:
privateKey = fileContent
pgpPrivateKeyFile.textLabel?.text = fileName
}
} catch {
Utils.alert(title: "CannotImportFile".localize(), message: "FileCannotBeImported.".localize(fileName), controller: self)
}
}
}
extension PGPKeyFileSettingTableViewController: PGPKeyImporter {
static let keySource = PGPKeySource.files
static let label = "LoadFromFiles".localize()
func isReadyToUse() -> Bool {
return validate(key: publicKey) && validate(key: privateKey)
}
func importKeys() throws {
guard let publicKey = publicKey, let privateKey = privateKey else {
return
}
Defaults.pgpKeySource = Self.keySource
try KeyFileManager.PublicPgp.importKey(from: publicKey)
try KeyFileManager.PrivatePgp.importKey(from: privateKey)
}
func doAfterImport() {
Utils.alert(title: "RememberToRemoveKey".localize(), message: "RememberToRemoveKeyFromLocation.".localize(), controller: self)
}
func saveImportedKeys() {
self.performSegue(withIdentifier: "savePGPKeySegue", sender: self)
}
private func validate(key: String?) -> Bool {
guard key != nil else {
Utils.alert(title: "CannotSavePgpKey".localize(), message: "KeyFileNotSet.".localize(), controller: self)
return false
}
return true
}
}

View file

@ -138,6 +138,9 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
optionMenu.addAction(UIAlertAction(title: PGPKeyArmorSettingTableViewController.menuLabel, style: .default) { _ in
self.performSegue(withIdentifier: "setPGPKeyByASCIISegue", sender: self)
})
optionMenu.addAction(UIAlertAction(title: PGPKeyFileSettingTableViewController.menuLabel, style: .default) { _ in
self.performSegue(withIdentifier: "setPGPKeyByFileSegue", sender: self)
})
if isReadyToUse() {
optionMenu.addAction(UIAlertAction(title: "\(Self.menuLabel) (\("Import".localize()))", style: .default) { _ in

View file

@ -134,6 +134,11 @@
"PgpCopyPublicAndPrivateKeyToPass." = "Kopiere den öffentlichen und den privaten Schlüssel im ASCII-Format verschlüsselt mit den Namen \"gpg_key.pub\" bzw. \"gpg_key\" über iTunes zu Pass. Danach können die Schlüssel über \"Datenaustausch über iTunes\" importiert werden.";
"KeyExpiredOrIncompatibleError." = "Der öffentliche PGP-Schlüssel ist eventuell abgelaufen oder inkompatibel mit dem privaten Schlüssel.";
"WrongPassphraseError." = "Das Passwort für den privaten PGP-Schlüssel ist falsch.";
"CannotImportFile" = "Fehler beim Importieren";
"LoadFromFiles" = "Aus Datei laden";
"FileCannotBeImported." = "Beim Importieren der Datei '%@' trat ein Fehler auf. Stelle bitte sicher, dass ihr Speicherort lesbar ist.";
"RememberToRemoveKeyFromLocation." = "Vergiss nicht, die Schlüsseldateien wieder von ihrem externen Speicherort zu entfernen.";
"KeyFileNotSet." = "Es wurde nicht für beide Schlüsseltypen eine Datei angegeben.";
// App passcode
"RemovePasscode" = "Passcode entfernen";
@ -286,3 +291,10 @@ geben den öffentlichen und den privaten Schlüssel in diesem speziellen Format
$ gpg --export-secret-keys -a KEY_ID
geben den öffentlichen und den privaten Schlüssel in diesem speziellen Format aus. Kopiere sie so zu einem Key-Server.";
"GpgAsciiArmorFileExplanation." = "GnuPG unterstützt die Kommandozeilenoption \"-a\", welche die Schlüssel im Format \"ASCII-Armor\" ausgibt. Es ist anders als das Binärformat eine einfache Zeichenkette. Die Befehle
$ gpg --export -a KEY_ID
$ gpg --export-secret-keys -a KEY_ID
geben den öffentlichen und den privaten Schlüssel in diesem speziellen Format aus. Kopiere sie so zu einem Speicherort, der für die Dateien-App zugänglich ist.";

View file

@ -74,6 +74,9 @@
/* Class = "UINavigationItem"; title = "Add Password"; ObjectID = "KOg-Gn-Buk"; */
"KOg-Gn-Buk.title" = "Passwort hinzufügen";
/* Class = "UILabel"; text = "Select file ..."; ObjectID = "Ka2-8Z-fwx"; */
"Ka2-8Z-fwx.text" = "Datei auswählen ...";
/* Class = "UILabel"; text = "Edit password for baidu.com using Pass for iOS."; ObjectID = "L1p-Dm-Mnh"; */
"L1p-Dm-Mnh.text" = "Passwort für baidu.com wurde in Pass for iOS hinzugefügt.";
@ -101,6 +104,9 @@
/* Class = "UILabel"; text = "Private Key URL"; ObjectID = "Qht-RC-Yeg"; */
"Qht-RC-Yeg.text" = "URL des privaten Schlüssels";
/* Class = "UITableViewSection"; headerTitle = "PRIVATE KEY"; ObjectID = "RFc-J6-hAe"; */
"RFc-J6-hAe.headerTitle" = "PRIVATER SCHLÜSSEL";
/* Class = "UILabel"; text = "PGP Key"; ObjectID = "RR9-xr-9ko"; */
"RR9-xr-9ko.text" = "PGP-Schlüssel";
@ -131,6 +137,15 @@
/* Class = "UINavigationItem"; title = "Settings"; ObjectID = "WH4-7R-4TQ"; */
"WH4-7R-4TQ.title" = "Einstellungen";
/* Class = "UILabel"; text = "Import Keys From Files"; ObjectID = "XU8-Io-n0h"; */
"XU8-Io-n0h.text" = "Schlüssel aus Dateien importieren";
/* Class = "UILabel"; text = "Select file ..."; ObjectID = "XVY-Dj-6Mx"; */
"XVY-Dj-6Mx.text" = "Datei auswählen ...";
/* Class = "UITableViewSection"; headerTitle = "PUBLIC KEY"; ObjectID = "Y8H-cb-G2j"; */
"Y8H-cb-G2j.headerTitle" = "ÖFFENTLICHER SCHLÜSSEL";
/* Class = "UITabBarItem"; title = "Settings"; ObjectID = "YLZ-cr-akY"; */
"YLZ-cr-akY.title" = "Einstellungen";
@ -233,6 +248,9 @@
/* Class = "UITableViewSection"; headerTitle = "GPG Configuration"; ObjectID = "ugP-R2-9M7"; */
"ugP-R2-9M7.headerTitle" = "GPG-Konfiguration";
/* Class = "UINavigationItem"; title = "PGP Key"; ObjectID = "waZ-gh-rQt"; */
"waZ-gh-rQt.title" = "PGP-Schlüssel";
/* Class = "UILabel"; text = "✓"; ObjectID = "wbx-rk-i8H"; */
"wbx-rk-i8H.text" = "✓";

View file

@ -134,6 +134,11 @@
"PgpCopyPublicAndPrivateKeyToPass." = "Copy your ASCII-armored public and private keys to Pass with names \"gpg_key.pub\" and \"gpg_key\" (without quotes) via iTunes. Then come back and click \"iTunes File Sharing\" to finish.";
"KeyExpiredOrIncompatibleError." = "PGP public key may be expired or incompatible with the private key.";
"WrongPassphraseError." = "Passphrase of your PGP secret key is wrong.";
"CannotImportFile" = "Cannot Import File";
"LoadFromFiles" = "Load From File";
"FileCannotBeImported." = "An error occurred importing the file '%@'. Please make sure its location is readable.";
"RememberToRemoveKeyFromLocation." = "Remember to remove the key files from their external locations.";
"KeyFileNotSet." = "At least for one key type there is no file specified.";
// App passcode
"RemovePasscode" = "Remove Passcode";
@ -286,3 +291,10 @@ to get the public and the private key in this specific format. The clipboard wil
$ gpg --export-secret-keys -a KEY_ID
to get the public and the private key in this specific format. Subsequently, copy them to your secured key server.";
"GpgAsciiArmorFileExplanation." = "GnuPG supports the command-line option \"-a\" that causes output to be generated in an ASCII-armored format similar to unencoded documents rather than the binary format. Use
$ gpg --export -a KEY_ID
$ gpg --export-secret-keys -a KEY_ID
to get the public and the private key in this specific format. Subsequently, copy them to a location accessible by the Files app.";

Binary file not shown.

View file

@ -12,7 +12,7 @@ import SwiftyUserDefaults
public var Defaults = DefaultsAdapter(defaults: UserDefaults(suiteName: Globals.groupIdentifier)!, keyStore: DefaultsKeys())
public enum PGPKeySource: String, DefaultsSerializable {
case url, armor, itunes
case url, armor, files, itunes
}
public enum GitAuthenticationMethod: String, DefaultsSerializable {