From 7223abcf0cfa99a866a10483b017555fb768738f Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 2 Jan 2015 00:07:05 +0100 Subject: [PATCH] extend canonicalize to strip local certificates on export --- .../operations/ImportExportOperation.java | 27 +++++++--- .../operations/results/OperationResult.java | 14 ++--- .../keychain/pgp/UncachedKeyRing.java | 53 ++++++++++++++++--- .../src/main/res/values-de/strings.xml | 10 ++-- .../src/main/res/values-es/strings.xml | 12 ++--- .../src/main/res/values-fr/strings.xml | 12 ++--- .../src/main/res/values-it/strings.xml | 10 ++-- .../src/main/res/values-ja/strings.xml | 12 ++--- .../src/main/res/values-sl/strings.xml | 10 ++-- .../src/main/res/values-sr/strings.xml | 12 ++--- .../src/main/res/values-sv/strings.xml | 8 +-- OpenKeychain/src/main/res/values/strings.xml | 14 ++--- 12 files changed, 123 insertions(+), 71 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java index da532d2dc..6ca28142f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java @@ -31,6 +31,7 @@ import org.sufficientlysecure.keychain.keyimport.Keyserver; import org.sufficientlysecure.keychain.keyimport.Keyserver.AddKeyException; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.results.ExportResult; +import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.Progressable; @@ -399,7 +400,7 @@ public class ImportExportOperation extends BaseOperation { } - private ExportResult exportKeyRings(OperationLog log, long[] masterKeyIds, boolean exportSecret, + ExportResult exportKeyRings(OperationLog log, long[] masterKeyIds, boolean exportSecret, OutputStream outStream) { /* TODO isn't this checked above, with the isStorageMounted call? @@ -469,12 +470,16 @@ public class ImportExportOperation extends BaseOperation { log.add(LogType.MSG_EXPORT_PUBLIC, 1, KeyFormattingUtils.beautifyKeyId(keyId)); - { // export public key part - byte[] data = cursor.getBlob(1); - arOutStream.write(data); + byte[] data = cursor.getBlob(1); + CanonicalizedKeyRing ring = + UncachedKeyRing.decodeFromData(data).canonicalize(log, 2, true); + ring.encode(arOutStream); - okPublic += 1; - } + okPublic += 1; + } catch (PgpGeneralException e) { + log.add(LogType.MSG_EXPORT_ERROR_KEY, 2); + updateProgress(progress++, numKeys); + continue; } finally { // make sure this is closed if (arOutStream != null) { @@ -491,12 +496,18 @@ public class ImportExportOperation extends BaseOperation { arOutStream.setHeader("Version", version); } - // export secret key part + // export secret key part log.add(LogType.MSG_EXPORT_SECRET, 2, KeyFormattingUtils.beautifyKeyId(keyId)); byte[] data = cursor.getBlob(2); - arOutStream.write(data); + CanonicalizedKeyRing ring = + UncachedKeyRing.decodeFromData(data).canonicalize(log, 2, true); + ring.encode(arOutStream); okSecret += 1; + } catch (PgpGeneralException e) { + log.add(LogType.MSG_EXPORT_ERROR_KEY, 2); + updateProgress(progress++, numKeys); + continue; } finally { // make sure this is closed if (arOutStream != null) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java index 426b0827e..bd73a9609 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java @@ -371,12 +371,13 @@ public abstract class OperationResult implements Parcelable { MSG_KC_ERROR_MASTER_ALGO (LogLevel.ERROR, R.string.msg_kc_error_master_algo), MSG_KC_ERROR_DUP_KEY (LogLevel.ERROR, R.string.msg_kc_error_dup_key), MSG_KC_MASTER (LogLevel.DEBUG, R.string.msg_kc_master), - MSG_KC_BAD_TYPE(LogLevel.WARN, R.string.msg_kc_bad_type), - MSG_KC_REVOKE_BAD_ERR (LogLevel.WARN, R.string.msg_kc_revoke_bad_err), - MSG_KC_REVOKE_BAD_LOCAL (LogLevel.WARN, R.string.msg_kc_revoke_bad_local), - MSG_KC_REVOKE_BAD_TIME (LogLevel.WARN, R.string.msg_kc_revoke_bad_time), - MSG_KC_REVOKE_BAD_TYPE_UID (LogLevel.WARN, R.string.msg_kc_revoke_bad_type_uid), - MSG_KC_REVOKE_BAD (LogLevel.WARN, R.string.msg_kc_revoke_bad), + MSG_KC_MASTER_BAD_TYPE(LogLevel.WARN, R.string.msg_kc_master_bad_type), + MSG_KC_MASTER_BAD_LOCAL(LogLevel.WARN, R.string.msg_kc_master_bad_local), + MSG_KC_MASTER_BAD_ERR(LogLevel.WARN, R.string.msg_kc_master_bad_err), + MSG_KC_MASTER_BAD_TIME(LogLevel.WARN, R.string.msg_kc_master_bad_time), + MSG_KC_MASTER_BAD_TYPE_UID(LogLevel.WARN, R.string.msg_kc_master_bad_type_uid), + MSG_KC_MASTER_BAD(LogLevel.WARN, R.string.msg_kc_master_bad), + MSG_KC_MASTER_LOCAL(LogLevel.WARN, R.string.msg_kc_master_local), MSG_KC_REVOKE_DUP (LogLevel.DEBUG, R.string.msg_kc_revoke_dup), MSG_KC_NOTATION_DUP (LogLevel.DEBUG, R.string.msg_kc_notation_dup), MSG_KC_NOTATION_EMPTY (LogLevel.DEBUG, R.string.msg_kc_notation_empty), @@ -618,6 +619,7 @@ public abstract class OperationResult implements Parcelable { MSG_EXPORT_ERROR_STORAGE (LogLevel.ERROR, R.string.msg_export_error_storage), MSG_EXPORT_ERROR_DB (LogLevel.ERROR, R.string.msg_export_error_db), MSG_EXPORT_ERROR_IO (LogLevel.ERROR, R.string.msg_export_error_io), + MSG_EXPORT_ERROR_KEY (LogLevel.ERROR, R.string.msg_export_error_key), MSG_EXPORT_SUCCESS (LogLevel.OK, R.string.msg_export_success), MSG_CRT_UPLOAD_SUCCESS (LogLevel.OK, R.string.msg_crt_upload_success), diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index 5e5a28e83..c4cd0b3e5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -266,6 +266,35 @@ public class UncachedKeyRing { */ @SuppressWarnings("ConstantConditions") public CanonicalizedKeyRing canonicalize(OperationLog log, int indent) { + return canonicalize(log, indent, false); + } + + + /** "Canonicalizes" a public key, removing inconsistencies in the process. + * + * More specifically: + * - Remove all non-verifying self-certificates + * - Remove all "future" self-certificates + * - Remove all certificates flagged as "local" + * - Remove all certificates which are superseded by a newer one on the same target, + * including revocations with later re-certifications. + * - Remove all certificates in other positions if not of known type: + * - key revocation signatures on the master key + * - subkey binding signatures for subkeys + * - certifications and certification revocations for user ids + * - If a subkey retains no valid subkey binding certificate, remove it + * - If a user id retains no valid self certificate, remove it + * - If the key is a secret key, remove all certificates by foreign keys + * - If no valid user id remains, log an error and return null + * + * This operation writes an OperationLog which can be used as part of an OperationResultParcel. + * + * @param forExport if this is true, non-exportable signatures will be removed + * @return A canonicalized key, or null on fatal error (log will include a message in this case) + * + */ + @SuppressWarnings("ConstantConditions") + public CanonicalizedKeyRing canonicalize(OperationLog log, int indent, boolean forExport) { log.add(isSecret() ? LogType.MSG_KC_SECRET : LogType.MSG_KC_PUBLIC, indent, KeyFormattingUtils.convertKeyIdToHex(getMasterKeyId())); @@ -311,7 +340,7 @@ public class UncachedKeyRing { || type == PGPSignature.CASUAL_CERTIFICATION || type == PGPSignature.POSITIVE_CERTIFICATION || type == PGPSignature.CERTIFICATION_REVOCATION) { - log.add(LogType.MSG_KC_REVOKE_BAD_TYPE_UID, indent); + log.add(LogType.MSG_KC_MASTER_BAD_TYPE_UID, indent); modified = PGPPublicKey.removeCertification(modified, zert); badCerts += 1; continue; @@ -320,7 +349,7 @@ public class UncachedKeyRing { if (type != PGPSignature.KEY_REVOCATION && type != PGPSignature.DIRECT_KEY) { // Unknown type, just remove - log.add(LogType.MSG_KC_BAD_TYPE, indent, "0x" + Integer.toString(type, 16)); + log.add(LogType.MSG_KC_MASTER_BAD_TYPE, indent, "0x" + Integer.toString(type, 16)); modified = PGPPublicKey.removeCertification(modified, zert); badCerts += 1; continue; @@ -328,7 +357,7 @@ public class UncachedKeyRing { if (cert.getCreationTime().after(nowPlusOneDay)) { // Creation date in the future? No way! - log.add(LogType.MSG_KC_REVOKE_BAD_TIME, indent); + log.add(LogType.MSG_KC_MASTER_BAD_TIME, indent); modified = PGPPublicKey.removeCertification(modified, zert); badCerts += 1; continue; @@ -337,23 +366,31 @@ public class UncachedKeyRing { try { cert.init(masterKey); if (!cert.verifySignature(masterKey)) { - log.add(LogType.MSG_KC_REVOKE_BAD, indent); + log.add(LogType.MSG_KC_MASTER_BAD, indent); modified = PGPPublicKey.removeCertification(modified, zert); badCerts += 1; continue; } } catch (PgpGeneralException e) { - log.add(LogType.MSG_KC_REVOKE_BAD_ERR, indent); + log.add(LogType.MSG_KC_MASTER_BAD_ERR, indent); modified = PGPPublicKey.removeCertification(modified, zert); badCerts += 1; continue; } - // special case: direct key signatures! + // if this is for export, we always remove any non-exportable certs + if (forExport && cert.isLocal()) { + // Remove revocation certs with "local" flag + log.add(LogType.MSG_KC_MASTER_LOCAL, indent); + modified = PGPPublicKey.removeCertification(modified, zert); + continue; + } + + // special case: non-exportable, direct key signatures for notations! if (cert.getSignatureType() == PGPSignature.DIRECT_KEY) { // must be local, otherwise strip! if (!cert.isLocal()) { - log.add(LogType.MSG_KC_BAD_TYPE, indent); + log.add(LogType.MSG_KC_MASTER_BAD_TYPE, indent); modified = PGPPublicKey.removeCertification(modified, zert); badCerts += 1; continue; @@ -376,7 +413,7 @@ public class UncachedKeyRing { continue; } else if (cert.isLocal()) { // Remove revocation certs with "local" flag - log.add(LogType.MSG_KC_REVOKE_BAD_LOCAL, indent); + log.add(LogType.MSG_KC_MASTER_BAD_LOCAL, indent); modified = PGPPublicKey.removeCertification(modified, zert); badCerts += 1; continue; diff --git a/OpenKeychain/src/main/res/values-de/strings.xml b/OpenKeychain/src/main/res/values-de/strings.xml index fa74b287b..52d979983 100644 --- a/OpenKeychain/src/main/res/values-de/strings.xml +++ b/OpenKeychain/src/main/res/values-de/strings.xml @@ -604,11 +604,11 @@ Schlüsselbund hat keine gültigen Benutzerkennungen! Der Hauptschlüssel verwendet einen unbekannten (%s) Algorithmus! Verarbeite Hauptschlüssel - Entferne fehlerhaftes Schlüsselbund Widerrufszertifikat - Entferne Schlüsselbund Widerrufszertifikat mit \"Lokal\" Attribut - Entferne Schlüsselbund Widerrufszertifikat mit zukünftigem Zeitstempel - Entferne Hauptschlüsselbeglaubigung unbekannter Art (%s) - Entferne fehlerhaftes Schlüsselbund Widerrufszertifikat + Entferne fehlerhaftes Schlüsselbund Widerrufszertifikat + Entferne Schlüsselbund Widerrufszertifikat mit \"Lokal\" Attribut + Entferne Schlüsselbund Widerrufszertifikat mit zukünftigem Zeitstempel + Entferne Hauptschlüsselbeglaubigung unbekannter Art (%s) + Entferne fehlerhaftes Schlüsselbund Widerrufszertifikat Entferne redundantes Schlüsselbund Widerrufszertifikat Verarbeite Unterschlüssel %s Entferne ungültige Unterschlüssel Zwischenbeglaubigung diff --git a/OpenKeychain/src/main/res/values-es/strings.xml b/OpenKeychain/src/main/res/values-es/strings.xml index afae20592..bf532a2aa 100644 --- a/OpenKeychain/src/main/res/values-es/strings.xml +++ b/OpenKeychain/src/main/res/values-es/strings.xml @@ -649,12 +649,12 @@ ¡La clave maestra usa un algoritmo (%s) desconocido! La subclave %s aparece dos veces en el juego de claves (keyring). El juego de claves está mal formado, ¡no se va a importar! Procesando clave maestra - Eliminando certificado defectuoso de revocación de juego de claves - Eliminando certificado de revocación de juego de claves, con distintivo \"local\" - Eliminando certificado de revocación de juego de claves, con marca de tiempo futura - Eliminando certificado de clave maestra, de tipo desconocido (%s) - Eliminando certificado de identificación de usuario en posición incorrecta - Eliminando certificado defectuoso de revocación de juego de claves + Eliminando certificado defectuoso de revocación de juego de claves + Eliminando certificado de revocación de juego de claves, con distintivo \"local\" + Eliminando certificado de revocación de juego de claves, con marca de tiempo futura + Eliminando certificado de clave maestra, de tipo desconocido (%s) + Eliminando certificado de identificación de usuario en posición incorrecta + Eliminando certificado defectuoso de revocación de juego de claves Eliminando certificado redundante de revocación de juego de claves Procesando subclave %s Eliminando certificado no válido de vinculación de subclave diff --git a/OpenKeychain/src/main/res/values-fr/strings.xml b/OpenKeychain/src/main/res/values-fr/strings.xml index 60b7a3bcf..b252dc9e0 100644 --- a/OpenKeychain/src/main/res/values-fr/strings.xml +++ b/OpenKeychain/src/main/res/values-fr/strings.xml @@ -649,12 +649,12 @@ La clef maîtresse utilise un algorithme (%s) inconnu ! La sous-clef %s se présente deux fois dans le trousseau. Le trousseau est mal formé, pas d\'importation ! Traitement de la clef maîtresse - Suppression du mauvais certificat de révocation du trousseau - Suppression du certificat de révocation du trousseau ayant le drapeau « local » - Suppression du certificat de révocation du trousseau ayant une estampille temporelle dans le futur - Suppression du certificat de clef maîtresse de type inconnu (%s) - Suppression du certificat de l\'ID d\'utilisateur en mauvaise position - Suppression du mauvais certificat de révocation du trousseau + Suppression du mauvais certificat de révocation du trousseau + Suppression du certificat de révocation du trousseau ayant le drapeau « local » + Suppression du certificat de révocation du trousseau ayant une estampille temporelle dans le futur + Suppression du certificat de clef maîtresse de type inconnu (%s) + Suppression du certificat de l\'ID d\'utilisateur en mauvaise position + Suppression du mauvais certificat de révocation du trousseau Suppression du certificat redondant de révocation du trousseau Traitement de la sous-clef %s Suppression du certificat invalide de liaison de la sous-clef diff --git a/OpenKeychain/src/main/res/values-it/strings.xml b/OpenKeychain/src/main/res/values-it/strings.xml index 6a33e25f1..f5a6696ae 100644 --- a/OpenKeychain/src/main/res/values-it/strings.xml +++ b/OpenKeychain/src/main/res/values-it/strings.xml @@ -599,11 +599,11 @@ Permetti accesso?\n\nATTENZIONE: Se non sai perche\' questo schermata e\' appars Canonicalizzazione portachiavi segreto %s Questa è una chiave OpenPGP versione 3, è deprecata e non più supportata! Elaborazione chiave principale - Rimozione di certificato di revoca del portachiavi corrotto - Rimozione certificato di revoca del portachiavi con caratteristica \"locale\" - Rimozione certificato di revoca del portachiavi con marca temporale futura - Rimozione certificato della chiave principale di tipo sconosciuto (%s) - Rimozione certificato di revoca del portachiavi corrotto + Rimozione di certificato di revoca del portachiavi corrotto + Rimozione certificato di revoca del portachiavi con caratteristica \"locale\" + Rimozione certificato di revoca del portachiavi con marca temporale futura + Rimozione certificato della chiave principale di tipo sconosciuto (%s) + Rimozione certificato di revoca del portachiavi corrotto Rimozione certificato di revoca del portachiavi ridondante Elaborazione sottochiave %s Rimozione certificato vincolante di sottochiave non valido diff --git a/OpenKeychain/src/main/res/values-ja/strings.xml b/OpenKeychain/src/main/res/values-ja/strings.xml index 5ed93c931..815a77431 100644 --- a/OpenKeychain/src/main/res/values-ja/strings.xml +++ b/OpenKeychain/src/main/res/values-ja/strings.xml @@ -615,12 +615,12 @@ 主鍵で不明なアルゴリズム(%s)を利用しています! 鍵輪の中に副鍵 %s が2度出現しました。鍵輪が不整形となっており、インポートできあせん! 主鍵処理中 - 問題のある鍵輪の破棄証明を破棄中 - 鍵輪のローカルフラグ付き破棄証明を破棄中 - 鍵輪の未来にタイムスタンプがある破棄証明を破棄中 - 問題のある主鍵の不明な型 (%s) の証明を破棄中 - 不正な位置のユーザID検証を破棄中 - 問題のある鍵輪の破棄証明を破棄中 + 問題のある鍵輪の破棄証明を破棄中 + 鍵輪のローカルフラグ付き破棄証明を破棄中 + 鍵輪の未来にタイムスタンプがある破棄証明を破棄中 + 問題のある主鍵の不明な型 (%s) の証明を破棄中 + 不正な位置のユーザID検証を破棄中 + 問題のある鍵輪の破棄証明を破棄中 重複している鍵輪の破棄証明を破棄中 副鍵 %s の処理中 証明が付随する不正な副鍵を破棄中 diff --git a/OpenKeychain/src/main/res/values-sl/strings.xml b/OpenKeychain/src/main/res/values-sl/strings.xml index 1841ee46b..6eeb7bd72 100644 --- a/OpenKeychain/src/main/res/values-sl/strings.xml +++ b/OpenKeychain/src/main/res/values-sl/strings.xml @@ -447,11 +447,11 @@ Zasebna zbirka ključev uspešno uvožena Obdelujem glavni ključ... - Umikam slab certifikat za preklic zbirk ključev - Umikam certifikat za preklic zbirk ključev z oznako \"lokalno\" - Umikam certifikat za preklic zbirk ključev s časovno znamko v prihodnosti - Umikam certifikat glavnega ključa neznanega tipa (%s) - Umikam slab certifikat za preklic zbirk ključev + Umikam slab certifikat za preklic zbirk ključev + Umikam certifikat za preklic zbirk ključev z oznako \"lokalno\" + Umikam certifikat za preklic zbirk ključev s časovno znamko v prihodnosti + Umikam certifikat glavnega ključa neznanega tipa (%s) + Umikam slab certifikat za preklic zbirk ključev Umikam odvečen certifikat za preklic zbirk ključev Obdelujem podključ %s Umikam neveljaven certifikat za povezovanje podključev diff --git a/OpenKeychain/src/main/res/values-sr/strings.xml b/OpenKeychain/src/main/res/values-sr/strings.xml index 5ba833972..b4955b9eb 100644 --- a/OpenKeychain/src/main/res/values-sr/strings.xml +++ b/OpenKeychain/src/main/res/values-sr/strings.xml @@ -669,12 +669,12 @@ Главни кључ користи непознат алгоритам (%s)! Поткључ %s се појављује два пута у привеску. Привезак је деформисан, не увозим! Обрађујем главни кључ - Уклањам лош сертификат опозива привеска - Уклањам сертификат опозива привеска са заставицом „локални“ - Уклањам сертификат опозива привеска са временском ознаком у будућности - Уклањам сертификат главног кључа непознатог типа (%s) - Уклањам сертификат корисничког ИД-а са погрешног места - Уклањам лош сертификат опозива привеска + Уклањам лош сертификат опозива привеска + Уклањам сертификат опозива привеска са заставицом „локални“ + Уклањам сертификат опозива привеска са временском ознаком у будућности + Уклањам сертификат главног кључа непознатог типа (%s) + Уклањам сертификат корисничког ИД-а са погрешног места + Уклањам лош сертификат опозива привеска Уклањам сувишни сертификат опозива привеска Обрађујем поткључ %s Уклањам неисправан повезујући сертификат поткључа diff --git a/OpenKeychain/src/main/res/values-sv/strings.xml b/OpenKeychain/src/main/res/values-sv/strings.xml index fda0ace11..7d414d3f0 100644 --- a/OpenKeychain/src/main/res/values-sv/strings.xml +++ b/OpenKeychain/src/main/res/values-sv/strings.xml @@ -571,10 +571,10 @@ Den här nyckeln är skapad med OpenPGP version 3, vilken är en föråldrad version som inte längre stöds! Den här huvudnyckeln använder en okänd (%s) algoritm! Bearbetar huvudnyckel - Tar bort dåligt återkallelsecertifikat för nyckelring - Tar bort återkallelsecertifikat för nyckelring med framtida tidstämpel - Tar bort huvudnyckelcertifikat av okänd typ (%s) - Tar bort dåligt återkallelsecertifikat för nyckelring + Tar bort dåligt återkallelsecertifikat för nyckelring + Tar bort återkallelsecertifikat för nyckelring med framtida tidstämpel + Tar bort huvudnyckelcertifikat av okänd typ (%s) + Tar bort dåligt återkallelsecertifikat för nyckelring Tar bort överflödigt återkallelsecertifikat för nyckelring Bearbetar undernyckel %s Inget giltigt certifikat hittades för %s, tar bort från nyckelring diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index be409078a..8788038aa 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -711,12 +711,13 @@ "The master key uses an unknown (%s) algorithm!" "Subkey %s occurs twice in keyring. Keyring is malformed, not importing!" "Processing master key" - "Removing master key certificate of unknown type (%s)" - "Removing bad keyring revocation certificate" - "Removing keyring revocation certificate with "local" flag" - "Removing keyring revocation certificate with future timestamp" - "Removing user ID certificate in bad position" - "Removing bad keyring revocation certificate" + "Removing master key certificate of unknown type (%s)" + "Removing master key certificate with "local" flag" + "Removing bad master key certificate" + "Removing keyring revocation certificate with future timestamp" + "Removing user ID certificate in bad position" + "Removing bad master key certificate" + "Removing master key certificate with "local" flag" "Removing redundant keyring revocation certificate" "Removing redundant notation certificate" "Removing empty notation certificate" @@ -980,6 +981,7 @@ "Storage is not ready for writing!" "Database error!" "Input/output error!" + "Error preprocessing key data!" "Export operation successful" "Nothing to delete!"