From eff59b46452e4f9b577ea8bc755cc96c3d76a760 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 4 Oct 2015 16:57:28 +0200 Subject: Show dialog before sharing log --- .../keychain/ui/LogDisplayFragment.java | 9 ++- .../keychain/ui/dialog/ShareLogDialogFragment.java | 79 ++++++++++++++++++++++ OpenKeychain/src/main/res/values/strings.xml | 5 ++ 3 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareLogDialogFragment.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java index 43c8d2643..e29cd0204 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java @@ -44,6 +44,7 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult.LogEnt import org.sufficientlysecure.keychain.operations.results.OperationResult.LogLevel; import org.sufficientlysecure.keychain.operations.results.OperationResult.SubLogEntryParcel; import org.sufficientlysecure.keychain.provider.TemporaryStorageProvider; +import org.sufficientlysecure.keychain.ui.dialog.ShareLogDialogFragment; import org.sufficientlysecure.keychain.ui.util.FormattingUtils; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.Notify.Style; @@ -149,11 +150,9 @@ public class LogDisplayFragment extends ListFragment implements OnItemClickListe } } - Intent intent = new Intent(Intent.ACTION_SEND); - intent.putExtra(Intent.EXTRA_STREAM, mLogTempFile); - intent.setType("text/plain"); - intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - startActivity(intent); + + ShareLogDialogFragment shareLogDialog = ShareLogDialogFragment.newInstance(mLogTempFile); + shareLogDialog.show(getActivity().getSupportFragmentManager(), "shareLogDialog"); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareLogDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareLogDialogFragment.java new file mode 100644 index 000000000..d4783fad2 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareLogDialogFragment.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2015 Dominik Schürmann + * + * 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 . + */ + +package org.sufficientlysecure.keychain.ui.dialog; + +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v4.app.DialogFragment; +import android.view.ContextThemeWrapper; + +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.ui.util.ThemeChanger; + +public class ShareLogDialogFragment extends DialogFragment { + private static final String ARG_STREAM = "stream"; + + public static ShareLogDialogFragment newInstance(Uri stream) { + Bundle args = new Bundle(); + args.putParcelable(ARG_STREAM, stream); + + ShareLogDialogFragment fragment = new ShareLogDialogFragment(); + fragment.setArguments(args); + + return fragment; + } + + @NonNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + + final Uri stream = getArguments().getParcelable(ARG_STREAM); + + ContextThemeWrapper theme = ThemeChanger.getDialogThemeWrapper(getActivity()); + + CustomAlertDialogBuilder builder = new CustomAlertDialogBuilder(theme); + builder.setTitle(R.string.share_log_dialog_title) + .setMessage(R.string.share_log_dialog_message) + .setNegativeButton(R.string.share_log_dialog_cancel_button, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dismiss(); + } + }) + .setPositiveButton(R.string.share_log_dialog_share_button, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dismiss(); + Intent intent = new Intent(Intent.ACTION_SEND); + intent.putExtra(Intent.EXTRA_STREAM, stream); + intent.setType("text/plain"); + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + startActivity(intent); + } + }); + + return builder.show(); + } + +} diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index e3359cdd9..171561625 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -1650,4 +1650,9 @@ "GitHub Authorization" "OpenKeychain API Tests" + "Share log?" + "While logs can be super helpful for developers to find bugs in OpenKeychain, they can contain potential sensitive information such as data about the updated keys. Please make sure you are okay with sharing this information." + "Share" + "Cancel" + -- cgit v1.2.3 From dfce5449c2e8029039533c26ba15e5ac468eb8e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 4 Oct 2015 22:46:21 +0200 Subject: Raise min asymmetric key length for all ciphers to 2048 bit --- .../operations/results/OperationResult.java | 2 +- .../keychain/pgp/PgpKeyOperation.java | 4 +-- .../ui/dialog/AddSubkeyDialogFragment.java | 38 +++++++++++++--------- OpenKeychain/src/main/res/values-de/strings.xml | 2 +- OpenKeychain/src/main/res/values-es/strings.xml | 2 +- OpenKeychain/src/main/res/values-eu/strings.xml | 2 +- OpenKeychain/src/main/res/values-fr/strings.xml | 2 +- OpenKeychain/src/main/res/values-it/strings.xml | 2 +- OpenKeychain/src/main/res/values-ja/strings.xml | 2 +- OpenKeychain/src/main/res/values-nl/strings.xml | 2 +- OpenKeychain/src/main/res/values-ru/strings.xml | 2 +- OpenKeychain/src/main/res/values-sr/strings.xml | 2 +- OpenKeychain/src/main/res/values-sv/strings.xml | 2 +- OpenKeychain/src/main/res/values-uk/strings.xml | 2 +- OpenKeychain/src/main/res/values/arrays.xml | 8 ++--- OpenKeychain/src/main/res/values/strings.xml | 6 +--- .../keychain/operations/ExportTest.java | 12 +++---- .../operations/PromoteKeyOperationTest.java | 6 ++-- .../keychain/pgp/PgpEncryptDecryptTest.java | 6 ++-- .../keychain/pgp/PgpKeyOperationTest.java | 12 +++---- .../pgp/UncachedKeyringCanonicalizeTest.java | 4 +-- .../keychain/pgp/UncachedKeyringMergeTest.java | 4 +-- 22 files changed, 63 insertions(+), 61 deletions(-) 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 65816e5f2..00c88089a 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 @@ -514,7 +514,7 @@ public abstract class OperationResult implements Parcelable { MSG_CR_ERROR_NO_USER_ID (LogLevel.ERROR, R.string.msg_cr_error_no_user_id), MSG_CR_ERROR_NO_CERTIFY (LogLevel.ERROR, R.string.msg_cr_error_no_certify), MSG_CR_ERROR_NULL_EXPIRY(LogLevel.ERROR, R.string.msg_cr_error_null_expiry), - MSG_CR_ERROR_KEYSIZE_512 (LogLevel.ERROR, R.string.msg_cr_error_keysize_512), + MSG_CR_ERROR_KEYSIZE_2048(LogLevel.ERROR, R.string.msg_cr_error_keysize_2048), MSG_CR_ERROR_NO_KEYSIZE (LogLevel.ERROR, R.string.msg_cr_error_no_keysize), MSG_CR_ERROR_NO_CURVE (LogLevel.ERROR, R.string.msg_cr_error_no_curve), MSG_CR_ERROR_UNKNOWN_ALGO (LogLevel.ERROR, R.string.msg_cr_error_unknown_algo), diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 6f156c201..59b840054 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -171,8 +171,8 @@ public class PgpKeyOperation { log.add(LogType.MSG_CR_ERROR_NO_KEYSIZE, indent); return null; } - if (add.mKeySize < 512) { - log.add(LogType.MSG_CR_ERROR_KEYSIZE_512, indent); + if (add.mKeySize < 2048) { + log.add(LogType.MSG_CR_ERROR_KEYSIZE_2048, indent); return null; } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddSubkeyDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddSubkeyDialogFragment.java index b51d081e1..cd5281c7c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddSubkeyDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddSubkeyDialogFragment.java @@ -348,30 +348,30 @@ public class AddSubkeyDialogFragment extends DialogFragment { /** *

RSA

- *

for RSA algorithm, key length must be greater than 1024 (according to - * #102). Possibility to generate keys bigger + *

for RSA algorithm, key length must be greater than 2048. Possibility to generate keys bigger * than 8192 bits is currently disabled, because it's almost impossible to generate them on a mobile device (check * RSA key length plot and * Cryptographic Key Length Recommendation). Also, key length must be a * multiplicity of 8.

*

ElGamal

- *

For ElGamal algorithm, supported key lengths are 1536, 2048, 3072, 4096 or 8192 bits.

+ *

For ElGamal algorithm, supported key lengths are 2048, 3072, 4096 or 8192 bits.

*

DSA

- *

For DSA algorithm key length must be between 512 and 1024. Also, it must me dividable by 64.

+ *

For DSA algorithm key length must be between 2048 and 3072. Also, it must me dividable by 64.

* * @return correct key length, according to SpongyCastle specification. Returns -1, if key length is * inappropriate. */ private int getProperKeyLength(Algorithm algorithm, int currentKeyLength) { - final int[] elGamalSupportedLengths = {1536, 2048, 3072, 4096, 8192}; + final int[] elGamalSupportedLengths = {2048, 3072, 4096, 8192}; int properKeyLength = -1; switch (algorithm) { - case RSA: - if (currentKeyLength > 1024 && currentKeyLength <= 16384) { + case RSA: { + if (currentKeyLength >= 2048 && currentKeyLength <= 16384) { properKeyLength = currentKeyLength + ((8 - (currentKeyLength % 8)) % 8); } break; - case ELGAMAL: + } + case ELGAMAL: { int[] elGammalKeyDiff = new int[elGamalSupportedLengths.length]; for (int i = 0; i < elGamalSupportedLengths.length; i++) { elGammalKeyDiff[i] = Math.abs(elGamalSupportedLengths[i] - currentKeyLength); @@ -386,11 +386,14 @@ public class AddSubkeyDialogFragment extends DialogFragment { } properKeyLength = elGamalSupportedLengths[minimalIndex]; break; - case DSA: - if (currentKeyLength >= 512 && currentKeyLength <= 1024) { + } + case DSA: { + // Bouncy Castle supports 4096 maximum + if (currentKeyLength >= 2048 && currentKeyLength <= 4096) { properKeyLength = currentKeyLength + ((64 - (currentKeyLength % 64)) % 64); } break; + } } return properKeyLength; } @@ -424,7 +427,7 @@ public class AddSubkeyDialogFragment extends DialogFragment { final ArrayAdapter keySizeAdapter = (ArrayAdapter) mKeySizeSpinner.getAdapter(); keySizeAdapter.clear(); switch (algorithm) { - case RSA: + case RSA: { replaceArrayAdapterContent(keySizeAdapter, R.array.rsa_key_size_spinner_values); mKeySizeSpinner.setSelection(1); mKeySizeRow.setVisibility(View.VISIBLE); @@ -450,7 +453,8 @@ public class AddSubkeyDialogFragment extends DialogFragment { } mFlagAuthenticate.setChecked(false); break; - case ELGAMAL: + } + case ELGAMAL: { replaceArrayAdapterContent(keySizeAdapter, R.array.elgamal_key_size_spinner_values); mKeySizeSpinner.setSelection(3); mKeySizeRow.setVisibility(View.VISIBLE); @@ -466,7 +470,8 @@ public class AddSubkeyDialogFragment extends DialogFragment { mFlagAuthenticate.setChecked(false); mFlagAuthenticate.setEnabled(false); break; - case DSA: + } + case DSA: { replaceArrayAdapterContent(keySizeAdapter, R.array.dsa_key_size_spinner_values); mKeySizeSpinner.setSelection(2); mKeySizeRow.setVisibility(View.VISIBLE); @@ -482,7 +487,8 @@ public class AddSubkeyDialogFragment extends DialogFragment { mFlagAuthenticate.setChecked(false); mFlagAuthenticate.setEnabled(false); break; - case ECDSA: + } + case ECDSA: { mKeySizeRow.setVisibility(View.GONE); mCurveRow.setVisibility(View.VISIBLE); mCustomKeyInfoTextView.setText(""); @@ -496,7 +502,8 @@ public class AddSubkeyDialogFragment extends DialogFragment { mFlagAuthenticate.setEnabled(true); mFlagAuthenticate.setChecked(false); break; - case ECDH: + } + case ECDH: { mKeySizeRow.setVisibility(View.GONE); mCurveRow.setVisibility(View.VISIBLE); mCustomKeyInfoTextView.setText(""); @@ -510,6 +517,7 @@ public class AddSubkeyDialogFragment extends DialogFragment { mFlagAuthenticate.setChecked(false); mFlagAuthenticate.setEnabled(false); break; + } } keySizeAdapter.notifyDataSetChanged(); diff --git a/OpenKeychain/src/main/res/values-de/strings.xml b/OpenKeychain/src/main/res/values-de/strings.xml index 0e4a43c6f..7de834eea 100644 --- a/OpenKeychain/src/main/res/values-de/strings.xml +++ b/OpenKeychain/src/main/res/values-de/strings.xml @@ -922,7 +922,7 @@ Schlüsselbünde müssen mindestens eine User-ID enthalten! Hauptschlüssel benötigt das Attribut beglaubigen! Ablaufdatum kann bei Schlüsselerstellung nicht \'gleiche wie vorher\' sein. Dies ist ein Programmierfehler, bitte reiche einen Fehlerbericht ein! - Schlüssellänge muss größer/gleich 512 sein! + Schlüssellänge muss größer/gleich 512 sein! Keine Schlüssellänge spezifiziert! Dies ist ein Progammierfehler, bitte reiche einen Fehlerbericht ein! Keine Elliptische Kurve spezifiziert! Dies ist ein Progammierfehler, bitte reiche einen Fehlerbericht ein! Interner OpenPGP Fehler! diff --git a/OpenKeychain/src/main/res/values-es/strings.xml b/OpenKeychain/src/main/res/values-es/strings.xml index a6849c542..fa0a53b88 100644 --- a/OpenKeychain/src/main/res/values-es/strings.xml +++ b/OpenKeychain/src/main/res/values-es/strings.xml @@ -921,7 +921,7 @@ ¡Los juegos de claves tienen que crearse con al menos una identificación de usuario! ¡La clave maestra debe tener el indicador de certificado! El periodo hasta la expiración no puede ser \'el mismo que antes\' al crear clave. Esto es un error de programación, ¡por favor consigne un informe de error! - ¡El tamaño de la clave debe ser mayor o igual de 512! + ¡El tamaño de la clave debe ser mayor o igual de 512! ¡No se especificó tamaño de clave! ¡Esto es un error de programación, por favor consigne un informe de fallo! ¡No se especificó curva elíptica! ¡Esto es un error de programación, por favor consigne un informe de fallo! ¡Error OpenPGP interno! diff --git a/OpenKeychain/src/main/res/values-eu/strings.xml b/OpenKeychain/src/main/res/values-eu/strings.xml index f57297498..81daa67ef 100644 --- a/OpenKeychain/src/main/res/values-eu/strings.xml +++ b/OpenKeychain/src/main/res/values-eu/strings.xml @@ -850,7 +850,7 @@ Giltza-uztaiak gutxienez erabiltzaile ID batekin sortu behar dira! Maisu giltzak egiaztagiri ikurra izan behar du! Epemuga ezin daiteke giltza sortzea baino \'lehenago\' izan. Hau programazio akats bat da, mesedez agiritu akats jakinarazpen bat! - Giltza neurria 512 edo handiagoa izan behar da! + Giltza neurria 512 edo handiagoa izan behar da! Ez da giltzaren neurria adierazi! Hau programazio akats bat da, mesedez agiritu akats jakinarazpen bat! Barneko OpenPGP akatsa! Algoritmo ezezaguna hautatu da! Hau programazio akats bat da, mesedez agiritu akats jakinarazpen bat! diff --git a/OpenKeychain/src/main/res/values-fr/strings.xml b/OpenKeychain/src/main/res/values-fr/strings.xml index b5e5f3d53..d67a9560f 100644 --- a/OpenKeychain/src/main/res/values-fr/strings.xml +++ b/OpenKeychain/src/main/res/values-fr/strings.xml @@ -921,7 +921,7 @@ Les trousseaux doivent être créés avec au moins un ID utilisateur ! La clef maîtresse doit avoir le drapeau « certifié » ! L\'expiration ne peut pas être « pareille qu\'avant » à la création de la clef. C\'est une erreur du programme, veuillez remplir un rapport de bogue ! - La taille de la clef doit être supérieure ou égale à 512 ! + La taille de la clef doit être supérieure ou égale à 512 ! Aucune taille de clef n\'a été spécifiée ! C\'est une erreur de programmation, veuillez remplir un rapport de bogue ! Aucune courbe elliptique n\'a été spécifiée ! C\'est une erreur de programmation, veuillez remplir un rapport de bogue ! Erreur interne OpenPGP ! diff --git a/OpenKeychain/src/main/res/values-it/strings.xml b/OpenKeychain/src/main/res/values-it/strings.xml index 5b87c6ced..c158e341c 100644 --- a/OpenKeychain/src/main/res/values-it/strings.xml +++ b/OpenKeychain/src/main/res/values-it/strings.xml @@ -658,7 +658,7 @@ Permetti accesso?\n\nATTENZIONE: Se non sai perche\' questo schermata e\' appars Nessuna opzione della chiave principale specificata! La chiave principale deve avere la caratteristica di certificazione! La data di scadenza non può essere \'come prima\' sulla creazione di chiavi. Questo è un errore di programmazione, si prega di inviare una segnalazione di bug! - La grandezza della chiave deve essere di 512bit o maggiore + La grandezza della chiave deve essere di 512bit o maggiore Nessuna curva ellittica specificata! Questo è un errore di programmazione, per favore invia una segnalazione! Modifica del portachiavi %s diff --git a/OpenKeychain/src/main/res/values-ja/strings.xml b/OpenKeychain/src/main/res/values-ja/strings.xml index 789a35e75..3abf085c6 100644 --- a/OpenKeychain/src/main/res/values-ja/strings.xml +++ b/OpenKeychain/src/main/res/values-ja/strings.xml @@ -898,7 +898,7 @@ 鍵輪は最低でも1つのユーザIDの生成が必要です! 主鍵は検証フラグが必須です! 鍵の生成時に期限を\'過去\'とすることはできません。これはプログラムエラーで、バグレポートでファイルを送ってください! - 鍵サイズは512かそれ以上が必須です! + 鍵サイズは512かそれ以上が必須です! 鍵サイズが不明です! これはプログラムエラーで、バグレポートでファイルの提出をお願いします! 楕円暗号が不明です! これはプログラムエラーで、バグレポートでファイルの提出をお願いします! PGP内部エラー! diff --git a/OpenKeychain/src/main/res/values-nl/strings.xml b/OpenKeychain/src/main/res/values-nl/strings.xml index 812376026..29d0cd57d 100644 --- a/OpenKeychain/src/main/res/values-nl/strings.xml +++ b/OpenKeychain/src/main/res/values-nl/strings.xml @@ -877,7 +877,7 @@ Sleutelbossen moeten met minstens een gebruikers-ID aangemaakt worden! Hoofdsleutel moet certificeer-vlag hebben! Verloopdatum kan niet hetzelfde als voordien zijn bij aanmaken van een sleutel. Dit is een bug, gelieve een verslag in te dienen! - Sleutelgrootte moet groter dan of gelijk zijn aan 512! + Sleutelgrootte moet groter dan of gelijk zijn aan 512! Geen sleutelgrootte opgegeven! Dit is een bug, gelieve een verslag in te dienen! Geen elliptische curve opgegeven! Dit is een bug, gelieve een verslag in te dienen! Interne OpenPGP-fout! diff --git a/OpenKeychain/src/main/res/values-ru/strings.xml b/OpenKeychain/src/main/res/values-ru/strings.xml index 6b73d367c..e3f9ccaea 100644 --- a/OpenKeychain/src/main/res/values-ru/strings.xml +++ b/OpenKeychain/src/main/res/values-ru/strings.xml @@ -768,7 +768,7 @@ Связки должны создаваться с хотя бы одним ID пользователя! Основной ключ должен иметь флаг сертификата! Срок годности не может быть \'такой же как раньше\' при создании ключа. Это программная ошибка, пожалуйста, сообщите об этом! - Размер ключа должен быть больше или равен 512! + Размер ключа должен быть больше или равен 512! Не задан размер ключа! Это программная ошибка, пожалуйста, сообщите об этом! Не задана эллиптическая кривая! Это программная ошибка, пожалуйста, сообщите об этом! Внутренняя ошибка OpenPGP! diff --git a/OpenKeychain/src/main/res/values-sr/strings.xml b/OpenKeychain/src/main/res/values-sr/strings.xml index ed7bce5f7..db31cd414 100644 --- a/OpenKeychain/src/main/res/values-sr/strings.xml +++ b/OpenKeychain/src/main/res/values-sr/strings.xml @@ -944,7 +944,7 @@ Привесци морају садржати бар један кориснички ИД! Главни кључ мора имати заставицу овере! Датум истицања не може бити „исти као пре“ на стварању кључа. Ово је грешка у програмирању, поднесите извештај о грешци! - Величина кључа мора бити већа или једнака 512! + Величина кључа мора бити већа или једнака 512! Није наведена величина кључа! Ово је грешка у програмирању, поднесите извештај о грешци! Није наведена елиптичка крива! Ово је грешка у програмирању, поднесите извештај о грешци! Унутрашња ОпенПГП грешка! diff --git a/OpenKeychain/src/main/res/values-sv/strings.xml b/OpenKeychain/src/main/res/values-sv/strings.xml index 4a0a9d083..2f4986df9 100644 --- a/OpenKeychain/src/main/res/values-sv/strings.xml +++ b/OpenKeychain/src/main/res/values-sv/strings.xml @@ -727,7 +727,7 @@ Genererar ny huvudnyckel Nyckelringar måste skapas med minst ett användar-ID! Huvudnyckel måste ha en certifieringsflagga! - Nyckelstorlek måste vara större eller lika med 512! + Nyckelstorlek måste vara större eller lika med 512! Internt OpenPGP-fel! Okänd algoritm vald. Detta är ett programmeringsfel, skicka en buggrapport! Dåliga nyckelflaggor valda, DSA kan inte användas för kryptering! diff --git a/OpenKeychain/src/main/res/values-uk/strings.xml b/OpenKeychain/src/main/res/values-uk/strings.xml index 6c0420c0b..3dc19b573 100644 --- a/OpenKeychain/src/main/res/values-uk/strings.xml +++ b/OpenKeychain/src/main/res/values-uk/strings.xml @@ -454,7 +454,7 @@ Генерується новий основний ключ Не вказано параметрів основного ключа! Основний ключ повинен мати прапорець certify! - Розмір ключа має бути більшим або рівним 512! + Розмір ключа має бути більшим або рівним 512! Змінюється в\'язка %s Виняток шифрування! diff --git a/OpenKeychain/src/main/res/values/arrays.xml b/OpenKeychain/src/main/res/values/arrays.xml index 28b6fcd78..393a1e091 100644 --- a/OpenKeychain/src/main/res/values/arrays.xml +++ b/OpenKeychain/src/main/res/values/arrays.xml @@ -48,17 +48,15 @@ @string/key_size_custom - @string/key_size_1536 @string/key_size_2048 @string/key_size_3072 @string/key_size_4096 @string/key_size_8192 - @string/key_size_512 - @string/key_size_768 - @string/key_size_1024 - @string/key_size_custom + @string/key_size_2048 + @string/key_size_3072 + @string/key_size_4096 diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 171561625..e39132f42 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -458,10 +458,6 @@ "Search via Name, Email…" - "512" - "768" - "1024" - "1536" "2048" "3072" "4096" @@ -1029,7 +1025,7 @@ "Keyrings must be created with at least one user ID!" "Master key must have certify flag!" "Expiry time cannot be 'same as before' on key creation. This is a programming error, please file a bug report!" - "Key size must be greater or equal 512!" + "Key size must be greater or equal 2048!" "No key size specified! This is a programming error, please file a bug report!" "No elliptic curve specified! This is a programming error, please file a bug report!" "Internal OpenPGP error!" diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java index a659dc7da..ae7c13c76 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java @@ -75,11 +75,11 @@ public class ExportTest { { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.RSA, 2048, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.DSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); + Algorithm.DSA, 2048, null, KeyFlags.SIGN_DATA, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L)); + Algorithm.ELGAMAL, 2048, null, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("snips"); parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhrase1); @@ -93,11 +93,11 @@ public class ExportTest { { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.RSA, 2048, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.DSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); + Algorithm.DSA, 2048, null, KeyFlags.SIGN_DATA, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L)); + Algorithm.ELGAMAL, 2048, null, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("snails"); parcel.mNewUnlock = new ChangeUnlockParcel(null, new Passphrase("1234")); diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperationTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperationTest.java index e6c8c0efe..717dfe508 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperationTest.java @@ -74,11 +74,11 @@ public class PromoteKeyOperationTest { { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.RSA, 2048, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.DSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); + Algorithm.DSA, 2048, null, KeyFlags.SIGN_DATA, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L)); + Algorithm.ELGAMAL, 2048, null, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("derp"); parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhrase1); diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java index cc5ef8038..4710edcba 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java @@ -131,11 +131,11 @@ public class PgpEncryptDecryptTest { // insecure (1024 bit) RSA key SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.RSA, 2048, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); + Algorithm.RSA, 2048, null, KeyFlags.SIGN_DATA, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L)); + Algorithm.RSA, 2048, null, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("eve"); parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhraseInsecure); diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index c0e28cd4b..a3b5ae9fa 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -82,8 +82,8 @@ public class PgpKeyOperationTest { UncachedKeyRing ring; PgpKeyOperation op; SaveKeyringParcel parcel; - ArrayList onlyA = new ArrayList(); - ArrayList onlyB = new ArrayList(); + ArrayList onlyA = new ArrayList<>(); + ArrayList onlyB = new ArrayList<>(); static CryptoInputParcel cryptoInput; @@ -94,11 +94,11 @@ public class PgpKeyOperationTest { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.DSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.DSA, 2048, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( Algorithm.RSA, 2048, null, KeyFlags.SIGN_DATA, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L)); + Algorithm.RSA, 2048, null, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("twi"); parcel.mAddUserIds.add("pink"); @@ -153,7 +153,7 @@ public class PgpKeyOperationTest { parcel.mNewUnlock = new ChangeUnlockParcel(passphrase); assertFailure("creating ring with < 512 bytes keysize should fail", parcel, - LogType.MSG_CR_ERROR_KEYSIZE_512); + LogType.MSG_CR_ERROR_KEYSIZE_2048); } { @@ -391,7 +391,7 @@ public class PgpKeyOperationTest { parcel.mAddSubKeys.add(new SubkeyAdd( Algorithm.RSA, new Random().nextInt(512), null, KeyFlags.SIGN_DATA, 0L)); assertModifyFailure("creating a subkey with keysize < 512 should fail", ring, parcel, - LogType.MSG_CR_ERROR_KEYSIZE_512); + LogType.MSG_CR_ERROR_KEYSIZE_2048); } diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java index 5e552fecc..5a4e5aad2 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java @@ -89,8 +89,8 @@ public class UncachedKeyringCanonicalizeTest { static UncachedKeyRing staticRing; static int totalPackets; UncachedKeyRing ring; - ArrayList onlyA = new ArrayList(); - ArrayList onlyB = new ArrayList(); + ArrayList onlyA = new ArrayList<>(); + ArrayList onlyB = new ArrayList<>(); OperationResult.OperationLog log = new OperationResult.OperationLog(); PGPSignatureSubpacketGenerator subHashedPacketsGen; PGPSecretKey secretKey; diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java index 90189e377..dd0a537f6 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java @@ -87,8 +87,8 @@ public class UncachedKeyringMergeTest { static UncachedKeyRing staticRingA, staticRingB; UncachedKeyRing ringA, ringB; - ArrayList onlyA = new ArrayList(); - ArrayList onlyB = new ArrayList(); + ArrayList onlyA = new ArrayList<>(); + ArrayList onlyB = new ArrayList<>(); OperationResult.OperationLog log = new OperationResult.OperationLog(); PgpKeyOperation op; SaveKeyringParcel parcel; -- cgit v1.2.3 From d3d73f5f85478df08c6de24088292dc2d931421d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 4 Oct 2015 22:51:44 +0200 Subject: center wizard buttons for other languages --- .../src/main/res/layout/create_key_email_fragment.xml | 2 ++ .../src/main/res/layout/create_key_final_fragment.xml | 2 ++ .../src/main/res/layout/create_key_name_fragment.xml | 2 ++ .../main/res/layout/create_key_passphrase_fragment.xml | 2 ++ .../src/main/res/layout/create_key_start_fragment.xml | 2 ++ .../main/res/layout/create_yubi_key_blank_fragment.xml | 8 ++++---- .../res/layout/create_yubi_key_import_fragment.xml | 2 ++ .../main/res/layout/create_yubi_key_pin_fragment.xml | 2 ++ .../res/layout/create_yubi_key_pin_repeat_fragment.xml | 2 ++ .../main/res/layout/create_yubi_key_wait_fragment.xml | 18 +----------------- 10 files changed, 21 insertions(+), 21 deletions(-) diff --git a/OpenKeychain/src/main/res/layout/create_key_email_fragment.xml b/OpenKeychain/src/main/res/layout/create_key_email_fragment.xml index d4ece38ac..c1f692a88 100644 --- a/OpenKeychain/src/main/res/layout/create_key_email_fragment.xml +++ b/OpenKeychain/src/main/res/layout/create_key_email_fragment.xml @@ -62,6 +62,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" + android:layout_gravity="center_vertical" android:text="@string/btn_back" android:textAllCaps="true" android:minHeight="?android:attr/listPreferredItemHeight" @@ -79,6 +80,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" + android:layout_gravity="center_vertical" android:text="@string/btn_next" android:textAllCaps="true" android:minHeight="?android:attr/listPreferredItemHeight" diff --git a/OpenKeychain/src/main/res/layout/create_key_final_fragment.xml b/OpenKeychain/src/main/res/layout/create_key_final_fragment.xml index 9a6c33f82..118f0661a 100644 --- a/OpenKeychain/src/main/res/layout/create_key_final_fragment.xml +++ b/OpenKeychain/src/main/res/layout/create_key_final_fragment.xml @@ -155,6 +155,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" + android:layout_gravity="center_vertical" android:text="@string/btn_back" android:textAllCaps="true" android:minHeight="?android:attr/listPreferredItemHeight" @@ -172,6 +173,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" + android:layout_gravity="center_vertical" android:text="@string/btn_create_key" android:textAllCaps="true" android:minHeight="?android:attr/listPreferredItemHeight" diff --git a/OpenKeychain/src/main/res/layout/create_key_name_fragment.xml b/OpenKeychain/src/main/res/layout/create_key_name_fragment.xml index 7b8ba3fc1..4e37dd713 100644 --- a/OpenKeychain/src/main/res/layout/create_key_name_fragment.xml +++ b/OpenKeychain/src/main/res/layout/create_key_name_fragment.xml @@ -56,6 +56,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" + android:layout_gravity="center_vertical" android:text="@string/btn_back" android:textAllCaps="true" android:minHeight="?android:attr/listPreferredItemHeight" @@ -73,6 +74,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" + android:layout_gravity="center_vertical" android:text="@string/btn_next" android:textAllCaps="true" android:minHeight="?android:attr/listPreferredItemHeight" diff --git a/OpenKeychain/src/main/res/layout/create_key_passphrase_fragment.xml b/OpenKeychain/src/main/res/layout/create_key_passphrase_fragment.xml index 9d10bbe70..9368aa1ef 100644 --- a/OpenKeychain/src/main/res/layout/create_key_passphrase_fragment.xml +++ b/OpenKeychain/src/main/res/layout/create_key_passphrase_fragment.xml @@ -74,6 +74,7 @@ android:textAppearance="?android:attr/textAppearanceMedium" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_gravity="center_vertical" android:layout_weight="1" android:text="@string/btn_back" android:textAllCaps="true" @@ -91,6 +92,7 @@ android:textAppearance="?android:attr/textAppearanceMedium" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_gravity="center_vertical" android:layout_weight="1" android:text="@string/btn_next" android:textAllCaps="true" diff --git a/OpenKeychain/src/main/res/layout/create_key_start_fragment.xml b/OpenKeychain/src/main/res/layout/create_key_start_fragment.xml index 20c434c02..622cdf5a0 100644 --- a/OpenKeychain/src/main/res/layout/create_key_start_fragment.xml +++ b/OpenKeychain/src/main/res/layout/create_key_start_fragment.xml @@ -74,6 +74,7 @@ android:textAppearance="?android:attr/textAppearanceMedium" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_gravity="center_vertical" android:layout_weight="1" android:text="@string/first_time_import_key" android:textAllCaps="true" @@ -91,6 +92,7 @@ android:textAppearance="?android:attr/textAppearanceMedium" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_gravity="center_vertical" android:layout_weight="1" android:text="@string/btn_do_not_save" android:textAllCaps="true" diff --git a/OpenKeychain/src/main/res/layout/create_yubi_key_blank_fragment.xml b/OpenKeychain/src/main/res/layout/create_yubi_key_blank_fragment.xml index ca203d0b5..7e2bf2246 100644 --- a/OpenKeychain/src/main/res/layout/create_yubi_key_blank_fragment.xml +++ b/OpenKeychain/src/main/res/layout/create_yubi_key_blank_fragment.xml @@ -45,6 +45,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" + android:layout_gravity="center_vertical" android:text="@string/btn_back" android:textAllCaps="true" android:minHeight="?android:attr/listPreferredItemHeight" @@ -52,8 +53,7 @@ android:drawablePadding="8dp" android:gravity="left|center_vertical" android:clickable="true" - style="?android:attr/borderlessButtonStyle" - android:layout_gravity="center_vertical" /> + style="?android:attr/borderlessButtonStyle" /> + style="?android:attr/borderlessButtonStyle" /> diff --git a/OpenKeychain/src/main/res/layout/create_yubi_key_import_fragment.xml b/OpenKeychain/src/main/res/layout/create_yubi_key_import_fragment.xml index 838ee37b4..3a54f264f 100644 --- a/OpenKeychain/src/main/res/layout/create_yubi_key_import_fragment.xml +++ b/OpenKeychain/src/main/res/layout/create_yubi_key_import_fragment.xml @@ -94,6 +94,7 @@ android:textAppearance="?android:attr/textAppearanceMedium" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_gravity="center_vertical" android:layout_weight="1" android:text="@string/btn_back" android:textAllCaps="true" @@ -111,6 +112,7 @@ android:textAppearance="?android:attr/textAppearanceMedium" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_gravity="center_vertical" android:layout_weight="1" android:text="@string/btn_import" android:textAllCaps="true" diff --git a/OpenKeychain/src/main/res/layout/create_yubi_key_pin_fragment.xml b/OpenKeychain/src/main/res/layout/create_yubi_key_pin_fragment.xml index 393ec76d4..34871affe 100644 --- a/OpenKeychain/src/main/res/layout/create_yubi_key_pin_fragment.xml +++ b/OpenKeychain/src/main/res/layout/create_yubi_key_pin_fragment.xml @@ -80,6 +80,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" + android:layout_gravity="center_vertical" android:text="@string/btn_back" android:textAllCaps="true" android:minHeight="?android:attr/listPreferredItemHeight" @@ -97,6 +98,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" + android:layout_gravity="center_vertical" android:text="@string/btn_next" android:textAllCaps="true" android:minHeight="?android:attr/listPreferredItemHeight" diff --git a/OpenKeychain/src/main/res/layout/create_yubi_key_pin_repeat_fragment.xml b/OpenKeychain/src/main/res/layout/create_yubi_key_pin_repeat_fragment.xml index d233398ca..af9080f55 100644 --- a/OpenKeychain/src/main/res/layout/create_yubi_key_pin_repeat_fragment.xml +++ b/OpenKeychain/src/main/res/layout/create_yubi_key_pin_repeat_fragment.xml @@ -79,6 +79,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" + android:layout_gravity="center_vertical" android:clickable="true" android:drawableLeft="@drawable/ic_chevron_left_grey_24dp" android:drawablePadding="8dp" @@ -96,6 +97,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" + android:layout_gravity="center_vertical" android:clickable="true" android:drawablePadding="8dp" android:drawableRight="@drawable/ic_chevron_right_grey_24dp" diff --git a/OpenKeychain/src/main/res/layout/create_yubi_key_wait_fragment.xml b/OpenKeychain/src/main/res/layout/create_yubi_key_wait_fragment.xml index a000dc82e..7f26995a7 100644 --- a/OpenKeychain/src/main/res/layout/create_yubi_key_wait_fragment.xml +++ b/OpenKeychain/src/main/res/layout/create_yubi_key_wait_fragment.xml @@ -56,27 +56,11 @@ android:minHeight="?android:attr/listPreferredItemHeight" android:drawableLeft="@drawable/ic_chevron_left_grey_24dp" android:drawablePadding="8dp" + android:layout_gravity="center_vertical" android:gravity="left|center_vertical" android:clickable="true" style="?android:attr/borderlessButtonStyle" /> - - -- cgit v1.2.3 From dfc396a44cc84556ee190418a0a5bc5752b0f148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 4 Oct 2015 23:37:03 +0200 Subject: Fix tests for min requirement of 2048 bits --- .../keychain/operations/CertifyOperationTest.java | 12 +++---- .../keychain/pgp/PgpEncryptDecryptTest.java | 38 +++++++++++----------- .../keychain/pgp/PgpKeyOperationTest.java | 28 ++++++++-------- .../pgp/UncachedKeyringCanonicalizeTest.java | 2 +- .../keychain/pgp/UncachedKeyringMergeTest.java | 2 +- 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java index c1aa5a76f..1475deca9 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java @@ -78,11 +78,11 @@ public class CertifyOperationTest { { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.RSA, 2048, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.DSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); + Algorithm.DSA, 2048, null, KeyFlags.SIGN_DATA, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L)); + Algorithm.ELGAMAL, 2048, null, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("derp"); parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhrase1); @@ -96,11 +96,11 @@ public class CertifyOperationTest { { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.RSA, 2048, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.DSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); + Algorithm.DSA, 2048, null, KeyFlags.SIGN_DATA, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.ELGAMAL, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L)); + Algorithm.ELGAMAL, 2048, null, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("ditz"); byte[] uatdata = new byte[random.nextInt(150)+10]; diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java index 4710edcba..9f2d4e015 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java @@ -77,7 +77,7 @@ public class PgpEncryptDecryptTest { static UncachedKeyRing mStaticRing1, mStaticRing2, mStaticRingInsecure; static Passphrase mKeyPhrase1 = TestingUtils.genPassphrase(true); static Passphrase mKeyPhrase2 = TestingUtils.genPassphrase(true); - static Passphrase mKeyPhraseInsecure = TestingUtils.genPassphrase(true); +// static Passphrase mKeyPhraseInsecure = TestingUtils.genPassphrase(true); static PrintStream oldShadowStream; @@ -127,24 +127,24 @@ public class PgpEncryptDecryptTest { mStaticRing2 = result.getRing(); } - { - // insecure (1024 bit) RSA key - SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 2048, null, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 2048, null, KeyFlags.SIGN_DATA, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 2048, null, KeyFlags.ENCRYPT_COMMS, 0L)); - parcel.mAddUserIds.add("eve"); - parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhraseInsecure); - - PgpEditKeyResult result = op.createSecretKeyRing(parcel); - Assert.assertTrue("initial test key creation must succeed", result.success()); - Assert.assertNotNull("initial test key creation must succeed", result.getRing()); - - mStaticRingInsecure = result.getRing(); - } +// { +// // insecure (1024 bit) RSA key +// SaveKeyringParcel parcel = new SaveKeyringParcel(); +// parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( +// Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); +// parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( +// Algorithm.RSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); +// parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( +// Algorithm.RSA, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L)); +// parcel.mAddUserIds.add("eve"); +// parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhraseInsecure); +// +// PgpEditKeyResult result = op.createSecretKeyRing(parcel); +// Assert.assertTrue("initial test key creation must succeed", result.success()); +// Assert.assertNotNull("initial test key creation must succeed", result.getRing()); +// +// mStaticRingInsecure = result.getRing(); +// } } diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index a3b5ae9fa..a62b4dbb2 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -94,11 +94,11 @@ public class PgpKeyOperationTest { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.DSA, 2048, null, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.DSA, 3072, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( Algorithm.RSA, 2048, null, KeyFlags.SIGN_DATA, 0L)); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 2048, null, KeyFlags.ENCRYPT_COMMS, 0L)); + Algorithm.RSA, 3072, null, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("twi"); parcel.mAddUserIds.add("pink"); @@ -159,7 +159,7 @@ public class PgpKeyOperationTest { { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.ELGAMAL, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.ELGAMAL, 2048, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddUserIds.add("shy"); parcel.mNewUnlock = new ChangeUnlockParcel(passphrase); @@ -170,7 +170,7 @@ public class PgpKeyOperationTest { { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, null)); + Algorithm.RSA, 2048, null, KeyFlags.CERTIFY_OTHER, null)); parcel.mAddUserIds.add("lotus"); parcel.mNewUnlock = new ChangeUnlockParcel(passphrase); @@ -181,7 +181,7 @@ public class PgpKeyOperationTest { { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); + Algorithm.RSA, 2048, null, KeyFlags.SIGN_DATA, 0L)); parcel.mAddUserIds.add("shy"); parcel.mNewUnlock = new ChangeUnlockParcel(passphrase); @@ -192,7 +192,7 @@ public class PgpKeyOperationTest { { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.RSA, 2048, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mNewUnlock = new ChangeUnlockParcel(passphrase); assertFailure("creating ring without user ids should fail", parcel, @@ -216,7 +216,7 @@ public class PgpKeyOperationTest { public void testMasterFlags() throws Exception { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA, 0L)); + Algorithm.RSA, 4096, null, KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA, 0L)); parcel.mAddUserIds.add("luna"); ring = assertCreateSuccess("creating ring with master key flags must succeed", parcel); @@ -256,8 +256,8 @@ public class PgpKeyOperationTest { List subkeys = KeyringTestingHelper.itToList(ring.getPublicKeys()); Assert.assertEquals("number of subkeys must be three", 3, subkeys.size()); - Assert.assertTrue("key ring should have been created in the last 120 seconds", - ring.getPublicKey().getCreationTime().after(new Date(new Date().getTime()-1000*120))); + Assert.assertTrue("key ring should have been created in the last 360 seconds", + ring.getPublicKey().getCreationTime().after(new Date(new Date().getTime()-1000*360))); Assert.assertNull("key ring should not expire", ring.getPublicKey().getUnsafeExpiryTimeForTesting()); @@ -347,7 +347,7 @@ public class PgpKeyOperationTest { long expiry = new Date().getTime() / 1000 + 159; int flags = KeyFlags.SIGN_DATA; - int bits = 1024 + new Random().nextInt(8); + int bits = 2048 + new Random().nextInt(8); parcel.mAddSubKeys.add(new SubkeyAdd(Algorithm.RSA, bits, null, flags, expiry)); UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB); @@ -398,7 +398,7 @@ public class PgpKeyOperationTest { { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 1024, null, KeyFlags.SIGN_DATA, null)); + Algorithm.RSA, 2048, null, KeyFlags.SIGN_DATA, null)); assertModifyFailure("creating master key with null expiry should fail", ring, parcel, LogType.MSG_MF_ERROR_NULL_EXPIRY); @@ -406,7 +406,7 @@ public class PgpKeyOperationTest { { // a past expiry should fail parcel.reset(); - parcel.mAddSubKeys.add(new SubkeyAdd(Algorithm.RSA, 1024, null, KeyFlags.SIGN_DATA, + parcel.mAddSubKeys.add(new SubkeyAdd(Algorithm.RSA, 2048, null, KeyFlags.SIGN_DATA, new Date().getTime()/1000-10)); assertModifyFailure("creating subkey with past expiry date should fail", ring, parcel, LogType.MSG_MF_ERROR_PAST_EXPIRY); @@ -837,7 +837,7 @@ public class PgpKeyOperationTest { UncachedKeyRing modified; - { // keytocard should fail with BAD_NFC_SIZE when presented with the RSA-1024 key + { // keytocard should fail with BAD_NFC_SIZE when presented with the RSA-3072 key long keyId = KeyringTestingHelper.getSubkeyId(ring, 2); parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, false, true)); @@ -846,7 +846,7 @@ public class PgpKeyOperationTest { parcel, cryptoInput, LogType.MSG_MF_ERROR_BAD_NFC_SIZE); } - { // keytocard should fail with BAD_NFC_ALGO when presented with the DSA-1024 key + { // keytocard should fail with BAD_NFC_ALGO when presented with the DSA-3072 key long keyId = KeyringTestingHelper.getSubkeyId(ring, 0); parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, false, true)); diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java index 5a4e5aad2..a077f5398 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java @@ -358,7 +358,7 @@ public class UncachedKeyringCanonicalizeTest { SaveKeyringParcel parcel = new SaveKeyringParcel(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L)); + Algorithm.RSA, 2048, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddUserIds.add("trix"); PgpKeyOperation op = new PgpKeyOperation(null); diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java index dd0a537f6..59397e642 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java @@ -234,7 +234,7 @@ public class UncachedKeyringMergeTest { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( - Algorithm.RSA, 1024, null, KeyFlags.SIGN_DATA, 0L)); + Algorithm.RSA, 2048, null, KeyFlags.SIGN_DATA, 0L)); modifiedA = op.modifySecretKeyRing(secretRing, new CryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); modifiedB = op.modifySecretKeyRing(secretRing, new CryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); -- cgit v1.2.3 From 8f40c6df5108f30dc424e4d802f49f3392738724 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 6 Oct 2015 15:06:36 +0200 Subject: use only primary and mutually bound subkeys for fingerprint verification --- .../org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java | 7 ++++++- .../org/sufficientlysecure/keychain/provider/ProviderHelper.java | 3 +-- .../keychain/ui/CreateYubiKeyImportFragment.java | 8 ++++---- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java index 18a27dd96..6f1e78ce6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java @@ -154,8 +154,13 @@ public abstract class CanonicalizedKeyRing extends KeyRing { return getRing().getEncoded(); } - public boolean containsSubkey(String expectedFingerprint) { + /// Returns true iff the keyring contains a primary key or mutually bound subkey with the expected fingerprint + public boolean containsBoundSubkey(String expectedFingerprint) { for (CanonicalizedPublicKey key : publicKeyIterator()) { + boolean isMasterOrMutuallyBound = key.isMasterKey() || key.canSign(); + if (!isMasterOrMutuallyBound) { + continue; + } if (KeyFormattingUtils.convertFingerprintToHex( key.getFingerprint()).equalsIgnoreCase(expectedFingerprint)) { return true; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index a6823d3ac..375775ff1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -62,7 +62,6 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; -import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets; import org.sufficientlysecure.keychain.provider.KeychainContract.UpdatedKeys; import org.sufficientlysecure.keychain.remote.AccountSettings; import org.sufficientlysecure.keychain.remote.AppSettings; @@ -968,7 +967,7 @@ public class ProviderHelper { // If we have an expected fingerprint, make sure it matches if (expectedFingerprint != null) { - if (!canPublicRing.containsSubkey(expectedFingerprint)) { + if (!canPublicRing.containsBoundSubkey(expectedFingerprint)) { log(LogType.MSG_IP_FINGERPRINT_ERROR); return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null); } else { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyImportFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyImportFragment.java index f7925b7f4..648c5f962 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyImportFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyImportFragment.java @@ -49,7 +49,7 @@ public class CreateYubiKeyImportFragment extends QueueingCryptoOperationFragment implements NfcListenerFragment { - private static final String ARG_FINGERPRINT = "fingerprint"; + private static final String ARG_FINGERPRINTS = "fingerprint"; public static final String ARG_AID = "aid"; public static final String ARG_USER_ID = "user_ids"; @@ -72,7 +72,7 @@ public class CreateYubiKeyImportFragment CreateYubiKeyImportFragment frag = new CreateYubiKeyImportFragment(); Bundle args = new Bundle(); - args.putByteArray(ARG_FINGERPRINT, scannedFingerprints); + args.putByteArray(ARG_FINGERPRINTS, scannedFingerprints); args.putByteArray(ARG_AID, nfcAid); args.putString(ARG_USER_ID, userId); frag.setArguments(args); @@ -86,7 +86,7 @@ public class CreateYubiKeyImportFragment Bundle args = savedInstanceState != null ? savedInstanceState : getArguments(); - mNfcFingerprints = args.getByteArray(ARG_FINGERPRINT); + mNfcFingerprints = args.getByteArray(ARG_FINGERPRINTS); mNfcAid = args.getByteArray(ARG_AID); mNfcUserId = args.getString(ARG_USER_ID); @@ -149,7 +149,7 @@ public class CreateYubiKeyImportFragment public void onSaveInstanceState(Bundle args) { super.onSaveInstanceState(args); - args.putByteArray(ARG_FINGERPRINT, mNfcFingerprints); + args.putByteArray(ARG_FINGERPRINTS, mNfcFingerprints); args.putByteArray(ARG_AID, mNfcAid); args.putString(ARG_USER_ID, mNfcUserId); } -- cgit v1.2.3 From bafc10896922a50fb32d3eb105c389d863b53d20 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 6 Oct 2015 17:34:47 +0200 Subject: pgpdecryptverify: refactor signature processing --- .../keychain/pgp/CanonicalizedPublicKey.java | 8 +- .../pgp/OpenPgpSignatureResultBuilder.java | 5 +- .../keychain/pgp/PgpDecryptVerifyOperation.java | 148 ++++++++++----------- 3 files changed, 82 insertions(+), 79 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKey.java index 412468a48..476b4e59c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKey.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKey.java @@ -44,13 +44,17 @@ import java.util.Iterator; public class CanonicalizedPublicKey extends UncachedPublicKey { // this is the parent key ring - final KeyRing mRing; + final CanonicalizedKeyRing mRing; - CanonicalizedPublicKey(KeyRing ring, PGPPublicKey key) { + CanonicalizedPublicKey(CanonicalizedKeyRing ring, PGPPublicKey key) { super(key); mRing = ring; } + public CanonicalizedKeyRing getKeyRing() { + return mRing; + } + public IterableIterator getUserIds() { return new IterableIterator(mPublicKey.getUserIDs()); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java index 9d059b58f..2dd1e2dde 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java @@ -91,11 +91,12 @@ public class OpenPgpSignatureResultBuilder { return mInsecure; } - public void initValid(CanonicalizedPublicKeyRing signingRing, - CanonicalizedPublicKey signingKey) { + public void initValid(CanonicalizedPublicKey signingKey) { setSignatureAvailable(true); setKnownKey(true); + CanonicalizedKeyRing signingRing = signingKey.getKeyRing(); + // from RING setKeyId(signingRing.getMasterKeyId()); try { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java index 36b4f5e1e..3bb442143 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java @@ -214,32 +214,15 @@ public class PgpDecryptVerifyOperation extends BaseOperation return "unknown pub key" status including the first key id if (!sigList.isEmpty()) { @@ -482,7 +446,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation return "unknown pub key" status including the first key id if (!sigList.isEmpty()) { @@ -1189,7 +1137,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation Date: Wed, 7 Oct 2015 18:57:43 +0200 Subject: pgpdecryptverify: fix one pass signature check, actually use bracketed structure --- .../operations/results/OperationResult.java | 2 ++ .../keychain/pgp/PgpDecryptVerifyOperation.java | 33 +++++++++++++++++++--- OpenKeychain/src/main/res/values/strings.xml | 6 ++-- 3 files changed, 35 insertions(+), 6 deletions(-) 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 00c88089a..3b65d9fb1 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 @@ -661,6 +661,7 @@ public abstract class OperationResult implements Parcelable { MSG_DC_ERROR_INPUT (LogLevel.ERROR, R.string.msg_dc_error_input), MSG_DC_ERROR_NO_DATA (LogLevel.ERROR, R.string.msg_dc_error_no_data), MSG_DC_ERROR_NO_KEY (LogLevel.ERROR, R.string.msg_dc_error_no_key), + MSG_DC_ERROR_NO_SIGNATURE (LogLevel.ERROR, R.string.msg_dc_error_no_signature), MSG_DC_ERROR_PGP_EXCEPTION (LogLevel.ERROR, R.string.msg_dc_error_pgp_exception), MSG_DC_INTEGRITY_CHECK_OK (LogLevel.INFO, R.string.msg_dc_integrity_check_ok), MSG_DC_OK_META_ONLY (LogLevel.OK, R.string.msg_dc_ok_meta_only), @@ -687,6 +688,7 @@ public abstract class OperationResult implements Parcelable { MSG_VL_ERROR_MISSING_SIGLIST (LogLevel.ERROR, R.string.msg_vl_error_no_siglist), MSG_VL_ERROR_MISSING_LITERAL (LogLevel.ERROR, R.string.msg_vl_error_missing_literal), MSG_VL_ERROR_MISSING_KEY (LogLevel.ERROR, R.string.msg_vl_error_wrong_key), + MSG_VL_ERROR_NO_SIGNATURE (LogLevel.ERROR, R.string.msg_vl_error_no_signature), MSG_VL_CLEAR_SIGNATURE_CHECK (LogLevel.DEBUG, R.string.msg_vl_clear_signature_check), MSG_VL_ERROR_INTEGRITY_CHECK (LogLevel.ERROR, R.string.msg_vl_error_integrity_check), MSG_VL_OK (LogLevel.OK, R.string.msg_vl_ok), diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java index 3bb442143..4f3f323a5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java @@ -264,8 +264,20 @@ public class PgpDecryptVerifyOperation extends BaseOperation"Error opening input data stream!" "No encrypted data found in stream!" "No encrypted data with known secret key found in stream!" + "Missing signature data!" "Encountered OpenPGP Exception during operation!" "Integrity check OK!" "Only metadata was requested, skipping decryption" @@ -1197,8 +1198,9 @@ "Starting signature check" - "No signature list in signed literal data" - "Message not signed with right key" + "No signature list in signed literal data!" + "Message not signed with expected key!" + "Missing signature data!" "No payload in signed literal data" "Filename: %s" "MIME type: %s" -- cgit v1.2.3 From fe8db664a86a35b18ec62ddaaa82cf7aafff1e4d Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 8 Oct 2015 13:53:58 +0200 Subject: pgpdecryptverify: refactor signature verification state into SignatureChecker subclass --- .../keychain/pgp/PgpDecryptVerifyOperation.java | 275 +++++++++++---------- OpenKeychain/src/main/res/values/strings.xml | 1 - 2 files changed, 141 insertions(+), 135 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java index 4f3f323a5..d613b08eb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java @@ -207,22 +207,18 @@ public class PgpDecryptVerifyOperation extends BaseOperation 0) { out.write(buffer, 0, length); - signature.update(buffer, 0, length); + signatureChecker.updateSignatureData(buffer, 0, length); } updateProgress(R.string.progress_verifying_signature, 95, 100); log.add(LogType.MSG_VL_CLEAR_SIGNATURE_CHECK, indent + 1); o = pgpF.nextObject(); - if ( ! (o instanceof PGPSignatureList) ) { - log.add(LogType.MSG_VL_ERROR_NO_SIGNATURE, indent); - return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log); - } - PGPSignatureList signatureList = (PGPSignatureList) o; - if (signatureList.size() <= signatureData.signatureIndex) { - log.add(LogType.MSG_VL_ERROR_NO_SIGNATURE, indent); + if ( ! signatureChecker.verifySignature(o, log, indent) ) { return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log); } - // PGPOnePassSignature and PGPSignature packets are "bracketed", - // so we need to take the last-minus-index'th element here - PGPSignature messageSignature = signatureList.get(signatureList.size() -1 -signatureData.signatureIndex); - - // Verify signature and check binding signatures - boolean validSignature = signature.verify(messageSignature); - if (validSignature) { - log.add(LogType.MSG_DC_CLEAR_SIGNATURE_OK, indent + 1); - } else { - log.add(LogType.MSG_DC_CLEAR_SIGNATURE_BAD, indent + 1); - } - - signatureResultBuilder.setValidSignature(validSignature); - - OpenPgpSignatureResult signatureResult = signatureResultBuilder.build(); + OpenPgpSignatureResult signatureResult = signatureChecker.getSignatureResult(); if (signatureResult.getResult() != OpenPgpSignatureResult.RESULT_VALID_CONFIRMED && signatureResult.getResult() != OpenPgpSignatureResult.RESULT_VALID_UNCONFIRMED) { @@ -364,7 +330,6 @@ public class PgpDecryptVerifyOperation extends BaseOperation return "unknown pub key" status including the first key id - if (!sigList.isEmpty()) { - signatureResultBuilder.setSignatureAvailable(true); - signatureResultBuilder.setKnownKey(false); - signatureResultBuilder.setKeyId(sigList.get(0).getKeyID()); - } - } - - // check for insecure signing key - // TODO: checks on signingRing ? - if (signatureData != null && ! PgpSecurityConstants.isSecureKey(signatureData.signingKey)) { - log.add(LogType.MSG_DC_INSECURE_KEY, indent + 1); - signatureResultBuilder.setInsecure(true); - } - + SignatureChecker signatureChecker = new SignatureChecker(); + if (signatureChecker.initializeOnePassSignature(dataChunk, log, indent +1)) { dataChunk = plainFact.nextObject(); } @@ -544,16 +474,8 @@ public class PgpDecryptVerifyOperation extends BaseOperation 0) { @@ -587,40 +507,17 @@ public class PgpDecryptVerifyOperation extends BaseOperation"decrypting data…" "preparing signature…" "generating signature…" - "processing signature…" "verifying signature…" "signing…" "certifying…" -- cgit v1.2.3 From 4b2f561a7320a2437de3392d87db3b1fb23f512f Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 8 Oct 2015 14:36:20 +0200 Subject: pgpdecryptverify: move cleartext verification into SignatureChecker --- .../keychain/pgp/PgpDecryptVerifyOperation.java | 295 ++++++++++----------- 1 file changed, 139 insertions(+), 156 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java index d613b08eb..888869994 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java @@ -251,7 +251,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation 0) { long progress = 100 * alreadyWritten / wholeSize; // stop at 100% for wrong file sizes... @@ -501,7 +502,6 @@ public class PgpDecryptVerifyOperation extends BaseOperation 0) { @@ -1001,21 +964,8 @@ public class PgpDecryptVerifyOperation extends BaseOperation return "unknown pub key" status including the first key id - if (!sigList.isEmpty()) { - signatureResultBuilder.setSignatureAvailable(true); - signatureResultBuilder.setKnownKey(false); - signatureResultBuilder.setKeyId(sigList.get(0).getKeyID()); - } - } - - // check for insecure signing key - // TODO: checks on signingRing ? - if (signatureData != null && ! PgpSecurityConstants.isSecureKey(signatureData.signingKey)) { - log.add(LogType.MSG_DC_INSECURE_KEY, indent + 1); - signatureResultBuilder.setInsecure(true); - } - - return signature; - } - /** * Mostly taken from ClearSignedFileProcessor in Bouncy Castle */ @@ -1162,20 +1074,6 @@ public class PgpDecryptVerifyOperation extends BaseOperation Date: Thu, 8 Oct 2015 18:01:40 +0200 Subject: fix jacoco coverage --- OpenKeychain/build.gradle | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index 39681fd05..fcf099023 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -242,7 +242,7 @@ android { // apply plugin: 'spoon' -task jacocoTestReport(type:JacocoReport) { +task jacocoTestReport(type:JacocoReport, dependsOn: "testDebugUnitTest") { group = "Reporting" description = "Generate Jacoco coverage reports" @@ -252,7 +252,9 @@ task jacocoTestReport(type:JacocoReport) { '**/R$*.class', '**/*$ViewInjector*.*', '**/BuildConfig.*', - '**/Manifest*.*'] + '**/Manifest*.*', + '**/*Activity*.*', + '**/*Fragment*.*'] ) sourceDirectories = files("${buildDir.parent}/src/main/java") @@ -260,10 +262,7 @@ task jacocoTestReport(type:JacocoReport) { "${buildDir}/generated/source/buildConfig/debug", "${buildDir}/generated/source/r/debug" ]) - executionData = files([ - "${buildDir}/jacoco/testDebug.exec", - "${buildDir}/outputs/code-coverage/connected/coverage.ec" - ]) + executionData = fileTree(dir: "${buildDir}/jacoco", include: "**/*.exec") reports { xml.enabled = true -- cgit v1.2.3 From d6076a998c729737fe6b96b74123e9e1af0a5a50 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 8 Oct 2015 18:02:17 +0200 Subject: pgpdecryptverify: externalize PgpSignatureChecker --- .../keychain/pgp/PgpDecryptVerifyOperation.java | 330 ++------------------ .../keychain/pgp/PgpSignatureChecker.java | 336 +++++++++++++++++++++ 2 files changed, 369 insertions(+), 297 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignatureChecker.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java index 888869994..f31b6af59 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java @@ -18,6 +18,17 @@ package org.sufficientlysecure.keychain.pgp; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.SignatureException; +import java.util.Date; +import java.util.Iterator; + import android.content.Context; import android.support.annotation.NonNull; import android.webkit.MimeTypeMap; @@ -33,18 +44,14 @@ import org.spongycastle.openpgp.PGPEncryptedDataList; import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPKeyValidationException; import org.spongycastle.openpgp.PGPLiteralData; -import org.spongycastle.openpgp.PGPOnePassSignature; -import org.spongycastle.openpgp.PGPOnePassSignatureList; import org.spongycastle.openpgp.PGPPBEEncryptedData; import org.spongycastle.openpgp.PGPPublicKeyEncryptedData; -import org.spongycastle.openpgp.PGPSignature; import org.spongycastle.openpgp.PGPSignatureList; import org.spongycastle.openpgp.PGPUtil; import org.spongycastle.openpgp.jcajce.JcaPGPObjectFactory; import org.spongycastle.openpgp.operator.PBEDataDecryptorFactory; import org.spongycastle.openpgp.operator.PGPDigestCalculatorProvider; import org.spongycastle.openpgp.operator.jcajce.CachingDataDecryptorFactory; -import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; import org.spongycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder; import org.spongycastle.util.encoders.DecoderException; @@ -68,17 +75,6 @@ import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.ProgressScaler; -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.SignatureException; -import java.util.Date; -import java.util.Iterator; - public class PgpDecryptVerifyOperation extends BaseOperation { public PgpDecryptVerifyOperation(Context context, ProviderHelper providerHelper, Progressable progressable) { @@ -207,7 +203,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation 0) { - sig.update(line, 0, length); - } - } - private static int readInputLine(ByteArrayOutputStream bOut, InputStream fIn) throws IOException { bOut.reset(); @@ -1055,253 +1035,9 @@ public class PgpDecryptVerifyOperation extends BaseOperation= 0 && isWhiteSpace(line[end])) { - end--; - } - - return end + 1; - } - - private static boolean isWhiteSpace(byte b) { - return b == '\r' || b == '\n' || b == '\t' || b == ' '; - } - private static byte[] getLineSeparator() { String nl = System.getProperty("line.separator"); return nl.getBytes(); } - private class SignatureChecker { - - OpenPgpSignatureResultBuilder signatureResultBuilder = new OpenPgpSignatureResultBuilder(); - - private CanonicalizedPublicKey signingKey; - // we use the signatureIndex instead of the signature itself here for two reasons: - // 1) the signature may be either of type PGPSignature or PGPOnePassSignature (which have no common ancestor) - // 2) in case of the latter, we need the signatureIndex to know which PGPSignature to use later on - private int signatureIndex; - - PGPOnePassSignature onePassSignature; - PGPSignature signature; - - ProviderHelper mProviderHelper; - - boolean initializeSignature(Object dataChunk, OperationLog log, int indent) throws PGPException { - - if ( ! (dataChunk instanceof PGPSignatureList) ) { - return false; - } - - PGPSignatureList sigList = (PGPSignatureList) dataChunk; - findAvailableSignature(sigList); - - if (signingKey != null) { - - // key found in our database! - signatureResultBuilder.initValid(signingKey); - - JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = - new JcaPGPContentVerifierBuilderProvider() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - signature.init(contentVerifierBuilderProvider, signingKey.getPublicKey()); - checkKeySecurity(log, indent); - - - } else if (!sigList.isEmpty()) { - - signatureResultBuilder.setSignatureAvailable(true); - signatureResultBuilder.setKnownKey(false); - signatureResultBuilder.setKeyId(sigList.get(0).getKeyID()); - - } - - return true; - - } - - boolean initializeOnePassSignature(Object dataChunk, OperationLog log, int indent) throws PGPException { - - if ( ! (dataChunk instanceof PGPOnePassSignatureList) ) { - return false; - } - - log.add(LogType.MSG_DC_CLEAR_SIGNATURE, indent + 1); - - PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk; - findAvailableSignature(sigList); - - if (signingKey != null) { - - // key found in our database! - signatureResultBuilder.initValid(signingKey); - - JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = - new JcaPGPContentVerifierBuilderProvider() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - onePassSignature.init(contentVerifierBuilderProvider, signingKey.getPublicKey()); - - checkKeySecurity(log, indent); - - } else if (!sigList.isEmpty()) { - - signatureResultBuilder.setSignatureAvailable(true); - signatureResultBuilder.setKnownKey(false); - signatureResultBuilder.setKeyId(sigList.get(0).getKeyID()); - - } - - return true; - - } - - private void checkKeySecurity(OperationLog log, int indent) { - // TODO: checks on signingRing ? - if ( ! PgpSecurityConstants.isSecureKey(signingKey)) { - log.add(LogType.MSG_DC_INSECURE_KEY, indent + 1); - signatureResultBuilder.setInsecure(true); - } - } - - public boolean isInitialized() { - return signingKey != null; - } - - private void findAvailableSignature(PGPOnePassSignatureList sigList) { - // go through all signatures (should be just one), make sure we have - // the key and it matches the one we’re looking for - for (int i = 0; i < sigList.size(); ++i) { - try { - long sigKeyId = sigList.get(i).getKeyID(); - CanonicalizedPublicKeyRing signingRing = mProviderHelper.getCanonicalizedPublicKeyRing( - KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(sigKeyId) - ); - signatureIndex = i; - signingKey = signingRing.getPublicKey(sigKeyId); - onePassSignature = sigList.get(i); - return; - } catch (ProviderHelper.NotFoundException e) { - Log.d(Constants.TAG, "key not found, trying next signature..."); - } - } - } - - public void findAvailableSignature(PGPSignatureList sigList) { - // go through all signatures (should be just one), make sure we have - // the key and it matches the one we’re looking for - for (int i = 0; i < sigList.size(); ++i) { - try { - long sigKeyId = sigList.get(i).getKeyID(); - CanonicalizedPublicKeyRing signingRing = mProviderHelper.getCanonicalizedPublicKeyRing( - KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(sigKeyId) - ); - signatureIndex = i; - signingKey = signingRing.getPublicKey(sigKeyId); - signature = sigList.get(i); - return; - } catch (ProviderHelper.NotFoundException e) { - Log.d(Constants.TAG, "key not found, trying next signature..."); - } - } - } - - public void updateSignatureWithCleartext(byte[] clearText) throws IOException, SignatureException { - - InputStream sigIn = new BufferedInputStream(new ByteArrayInputStream(clearText)); - - ByteArrayOutputStream outputBuffer = new ByteArrayOutputStream(); - - int lookAhead = readInputLine(outputBuffer, sigIn); - - processLine(signature, outputBuffer.toByteArray()); - - if (lookAhead != -1) { - do { - lookAhead = readInputLine(outputBuffer, lookAhead, sigIn); - - signature.update((byte) '\r'); - signature.update((byte) '\n'); - - processLine(signature, outputBuffer.toByteArray()); - } while (lookAhead != -1); - } - - } - - public void updateSignatureData(byte[] buf, int off, int len) { - if (onePassSignature != null) { - onePassSignature.update(buf, off, len); - } - } - - void verifySignature(OperationLog log, int indent) throws PGPException { - - log.add(LogType.MSG_DC_CLEAR_SIGNATURE_CHECK, indent); - - // Verify signature - boolean validSignature = signature.verify(); - if (validSignature) { - log.add(LogType.MSG_DC_CLEAR_SIGNATURE_OK, indent + 1); - } else { - log.add(LogType.MSG_DC_CLEAR_SIGNATURE_BAD, indent + 1); - } - - // check for insecure hash algorithms - if (!PgpSecurityConstants.isSecureHashAlgorithm(onePassSignature.getHashAlgorithm())) { - log.add(LogType.MSG_DC_INSECURE_HASH_ALGO, indent + 1); - signatureResultBuilder.setInsecure(true); - } - - signatureResultBuilder.setValidSignature(validSignature); - - } - - boolean verifySignatureOnePass(Object o, OperationLog log, int indent) throws PGPException { - - if ( ! (o instanceof PGPSignatureList) ) { - log.add(LogType.MSG_DC_ERROR_NO_SIGNATURE, indent); - return false; - } - PGPSignatureList signatureList = (PGPSignatureList) o; - if (signatureList.size() <= signatureIndex) { - log.add(LogType.MSG_DC_ERROR_NO_SIGNATURE, indent); - return false; - } - - // PGPOnePassSignature and PGPSignature packets are "bracketed", - // so we need to take the last-minus-index'th element here - PGPSignature messageSignature = signatureList.get(signatureList.size() -1 - signatureIndex); - - // Verify signature - boolean validSignature = onePassSignature.verify(messageSignature); - if (validSignature) { - log.add(LogType.MSG_DC_CLEAR_SIGNATURE_OK, indent + 1); - } else { - log.add(LogType.MSG_DC_CLEAR_SIGNATURE_BAD, indent + 1); - } - - // check for insecure hash algorithms - if (!PgpSecurityConstants.isSecureHashAlgorithm(onePassSignature.getHashAlgorithm())) { - log.add(LogType.MSG_DC_INSECURE_HASH_ALGO, indent + 1); - signatureResultBuilder.setInsecure(true); - } - - signatureResultBuilder.setValidSignature(validSignature); - - return true; - - } - - public byte[] getSigningFingerprint() { - return signingKey.getFingerprint(); - } - - public OpenPgpSignatureResult getSignatureResult() { - return signatureResultBuilder.build(); - } - - } - } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignatureChecker.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignatureChecker.java new file mode 100644 index 000000000..2fccf2197 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignatureChecker.java @@ -0,0 +1,336 @@ +package org.sufficientlysecure.keychain.pgp; + + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.SignatureException; + +import org.openintents.openpgp.OpenPgpSignatureResult; +import org.spongycastle.openpgp.PGPException; +import org.spongycastle.openpgp.PGPOnePassSignature; +import org.spongycastle.openpgp.PGPOnePassSignatureList; +import org.spongycastle.openpgp.PGPSignature; +import org.spongycastle.openpgp.PGPSignatureList; +import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; +import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.util.Log; + + +/** This class is used to track the state of a single signature verification. + * + * + */ +class PgpSignatureChecker { + + OpenPgpSignatureResultBuilder signatureResultBuilder = new OpenPgpSignatureResultBuilder(); + + private CanonicalizedPublicKey signingKey; + + private int signatureIndex; + PGPOnePassSignature onePassSignature; + PGPSignature signature; + + ProviderHelper mProviderHelper; + + PgpSignatureChecker(ProviderHelper providerHelper) { + mProviderHelper = providerHelper; + } + + boolean initializeSignature(Object dataChunk, OperationLog log, int indent) throws PGPException { + + if (!(dataChunk instanceof PGPSignatureList)) { + return false; + } + + PGPSignatureList sigList = (PGPSignatureList) dataChunk; + findAvailableSignature(sigList); + + if (signingKey != null) { + + // key found in our database! + signatureResultBuilder.initValid(signingKey); + + JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = + new JcaPGPContentVerifierBuilderProvider() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + signature.init(contentVerifierBuilderProvider, signingKey.getPublicKey()); + checkKeySecurity(log, indent); + + + } else if (!sigList.isEmpty()) { + + signatureResultBuilder.setSignatureAvailable(true); + signatureResultBuilder.setKnownKey(false); + signatureResultBuilder.setKeyId(sigList.get(0).getKeyID()); + + } + + return true; + + } + + boolean initializeOnePassSignature(Object dataChunk, OperationLog log, int indent) throws PGPException { + + if (!(dataChunk instanceof PGPOnePassSignatureList)) { + return false; + } + + log.add(LogType.MSG_DC_CLEAR_SIGNATURE, indent + 1); + + PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk; + findAvailableSignature(sigList); + + if (signingKey != null) { + + // key found in our database! + signatureResultBuilder.initValid(signingKey); + + JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = + new JcaPGPContentVerifierBuilderProvider() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + onePassSignature.init(contentVerifierBuilderProvider, signingKey.getPublicKey()); + + checkKeySecurity(log, indent); + + } else if (!sigList.isEmpty()) { + + signatureResultBuilder.setSignatureAvailable(true); + signatureResultBuilder.setKnownKey(false); + signatureResultBuilder.setKeyId(sigList.get(0).getKeyID()); + + } + + return true; + + } + + private void checkKeySecurity(OperationLog log, int indent) { + // TODO: checks on signingRing ? + if (!PgpSecurityConstants.isSecureKey(signingKey)) { + log.add(LogType.MSG_DC_INSECURE_KEY, indent + 1); + signatureResultBuilder.setInsecure(true); + } + } + + public boolean isInitialized() { + return signingKey != null; + } + + private void findAvailableSignature(PGPOnePassSignatureList sigList) { + // go through all signatures (should be just one), make sure we have + // the key and it matches the one we’re looking for + for (int i = 0; i < sigList.size(); ++i) { + try { + long sigKeyId = sigList.get(i).getKeyID(); + CanonicalizedPublicKeyRing signingRing = mProviderHelper.getCanonicalizedPublicKeyRing( + KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(sigKeyId) + ); + signatureIndex = i; + signingKey = signingRing.getPublicKey(sigKeyId); + onePassSignature = sigList.get(i); + return; + } catch (ProviderHelper.NotFoundException e) { + Log.d(Constants.TAG, "key not found, trying next signature..."); + } + } + } + + public void findAvailableSignature(PGPSignatureList sigList) { + // go through all signatures (should be just one), make sure we have + // the key and it matches the one we’re looking for + for (int i = 0; i < sigList.size(); ++i) { + try { + long sigKeyId = sigList.get(i).getKeyID(); + CanonicalizedPublicKeyRing signingRing = mProviderHelper.getCanonicalizedPublicKeyRing( + KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(sigKeyId) + ); + signatureIndex = i; + signingKey = signingRing.getPublicKey(sigKeyId); + signature = sigList.get(i); + return; + } catch (ProviderHelper.NotFoundException e) { + Log.d(Constants.TAG, "key not found, trying next signature..."); + } + } + } + + public void updateSignatureWithCleartext(byte[] clearText) throws IOException, SignatureException { + + InputStream sigIn = new BufferedInputStream(new ByteArrayInputStream(clearText)); + + ByteArrayOutputStream outputBuffer = new ByteArrayOutputStream(); + + int lookAhead = readInputLine(outputBuffer, sigIn); + + processLine(signature, outputBuffer.toByteArray()); + + while (lookAhead != -1) { + lookAhead = readInputLine(outputBuffer, lookAhead, sigIn); + + signature.update((byte) '\r'); + signature.update((byte) '\n'); + + processLine(signature, outputBuffer.toByteArray()); + } + + } + + public void updateSignatureData(byte[] buf, int off, int len) { + if (signature != null) { + signature.update(buf, off, len); + } else if (onePassSignature != null) { + onePassSignature.update(buf, off, len); + } + } + + void verifySignature(OperationLog log, int indent) throws PGPException { + + log.add(LogType.MSG_DC_CLEAR_SIGNATURE_CHECK, indent); + + // Verify signature + boolean validSignature = signature.verify(); + if (validSignature) { + log.add(LogType.MSG_DC_CLEAR_SIGNATURE_OK, indent + 1); + } else { + log.add(LogType.MSG_DC_CLEAR_SIGNATURE_BAD, indent + 1); + } + + // check for insecure hash algorithms + if (!PgpSecurityConstants.isSecureHashAlgorithm(onePassSignature.getHashAlgorithm())) { + log.add(LogType.MSG_DC_INSECURE_HASH_ALGO, indent + 1); + signatureResultBuilder.setInsecure(true); + } + + signatureResultBuilder.setValidSignature(validSignature); + + } + + boolean verifySignatureOnePass(Object o, OperationLog log, int indent) throws PGPException { + + if (!(o instanceof PGPSignatureList)) { + log.add(LogType.MSG_DC_ERROR_NO_SIGNATURE, indent); + return false; + } + PGPSignatureList signatureList = (PGPSignatureList) o; + if (signatureList.size() <= signatureIndex) { + log.add(LogType.MSG_DC_ERROR_NO_SIGNATURE, indent); + return false; + } + + // PGPOnePassSignature and PGPSignature packets are "bracketed", + // so we need to take the last-minus-index'th element here + PGPSignature messageSignature = signatureList.get(signatureList.size() - 1 - signatureIndex); + + // Verify signature + boolean validSignature = onePassSignature.verify(messageSignature); + if (validSignature) { + log.add(LogType.MSG_DC_CLEAR_SIGNATURE_OK, indent + 1); + } else { + log.add(LogType.MSG_DC_CLEAR_SIGNATURE_BAD, indent + 1); + } + + // check for insecure hash algorithms + if (!PgpSecurityConstants.isSecureHashAlgorithm(onePassSignature.getHashAlgorithm())) { + log.add(LogType.MSG_DC_INSECURE_HASH_ALGO, indent + 1); + signatureResultBuilder.setInsecure(true); + } + + signatureResultBuilder.setValidSignature(validSignature); + + return true; + + } + + public byte[] getSigningFingerprint() { + return signingKey.getFingerprint(); + } + + public OpenPgpSignatureResult getSignatureResult() { + return signatureResultBuilder.build(); + } + + /** + * Mostly taken from ClearSignedFileProcessor in Bouncy Castle + */ + + private static void processLine(PGPSignature sig, byte[] line) + throws SignatureException { + int length = getLengthWithoutWhiteSpace(line); + if (length > 0) { + sig.update(line, 0, length); + } + } + + private static int readInputLine(ByteArrayOutputStream bOut, InputStream fIn) + throws IOException { + bOut.reset(); + + int lookAhead = -1; + int ch; + + while ((ch = fIn.read()) >= 0) { + bOut.write(ch); + if (ch == '\r' || ch == '\n') { + lookAhead = readPastEOL(bOut, ch, fIn); + break; + } + } + + return lookAhead; + } + + private static int readInputLine(ByteArrayOutputStream bOut, int lookAhead, InputStream fIn) + throws IOException { + bOut.reset(); + + int ch = lookAhead; + + do { + bOut.write(ch); + if (ch == '\r' || ch == '\n') { + lookAhead = readPastEOL(bOut, ch, fIn); + break; + } + } while ((ch = fIn.read()) >= 0); + + if (ch < 0) { + lookAhead = -1; + } + + return lookAhead; + } + + private static int readPastEOL(ByteArrayOutputStream bOut, int lastCh, InputStream fIn) + throws IOException { + int lookAhead = fIn.read(); + + if (lastCh == '\r' && lookAhead == '\n') { + bOut.write(lookAhead); + lookAhead = fIn.read(); + } + + return lookAhead; + } + + private static int getLengthWithoutWhiteSpace(byte[] line) { + int end = line.length - 1; + + while (end >= 0 && isWhiteSpace(line[end])) { + end--; + } + + return end + 1; + } + + private static boolean isWhiteSpace(byte b) { + return b == '\r' || b == '\n' || b == '\t' || b == ' '; + } + +} -- cgit v1.2.3 From e29f9017f7a83198537df2e2f5279359e2d86118 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 8 Oct 2015 18:36:03 +0200 Subject: pgpsignencrypt: unsupported parameter combinations are a bug --- .../keychain/operations/results/OperationResult.java | 1 - .../org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java | 4 +--- OpenKeychain/src/main/res/values/strings.xml | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) 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 3b65d9fb1..f959ddd76 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 @@ -705,7 +705,6 @@ public abstract class OperationResult implements Parcelable { // pgpsignencrypt MSG_PSE_ASYMMETRIC (LogLevel.INFO, R.string.msg_pse_asymmetric), - MSG_PSE_CLEARSIGN_ONLY (LogLevel.DEBUG, R.string.msg_pse_clearsign_only), MSG_PSE_COMPRESSING (LogLevel.DEBUG, R.string.msg_pse_compressing), MSG_PSE_ENCRYPTING (LogLevel.DEBUG, R.string.msg_pse_encrypting), MSG_PSE_ERROR_BAD_PASSPHRASE (LogLevel.ERROR, R.string.msg_pse_error_bad_passphrase), diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java index 29b2ef727..406c64ae8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java @@ -491,9 +491,7 @@ public class PgpSignEncryptOperation extends BaseOperation { literalGen.close(); } else { - pOut = null; - // TODO: Is this log right? - log.add(LogType.MSG_PSE_CLEARSIGN_ONLY, indent); + throw new AssertionError("cannot clearsign in non-ascii armored text, this is a bug!"); } if (enableSignature) { diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index c3fabaa69..03493d697 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -1221,7 +1221,6 @@ "Preparing public keys for encryption" - "Signing of cleartext input not supported!" "Preparing compression" "Encrypting data" "Bad password!" -- cgit v1.2.3 From ac28b6bbac979b14ff89943965ca63aaf2129a80 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 8 Oct 2015 18:36:55 +0200 Subject: test: add tests for detached and clearsign signatures --- .../keychain/pgp/PgpEncryptDecryptTest.java | 115 ++++++++++++++++++++- 1 file changed, 114 insertions(+), 1 deletion(-) diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java index 9f2d4e015..4a6c8b058 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java @@ -27,6 +27,7 @@ import java.util.Date; import java.util.HashSet; import java.util.Iterator; +import org.apache.tools.ant.util.StringUtils; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; @@ -287,7 +288,7 @@ public class PgpEncryptDecryptTest { } @Test - public void testAsymmetricSign() { + public void testAsymmetricSignBinary() { String plaintext = "dies ist ein plaintext ☭" + TestingUtils.genPassphrase(true); byte[] ciphertext; @@ -340,6 +341,118 @@ public class PgpEncryptDecryptTest { } + @Test + public void testAsymmetricSignCleartext() { + + String plaintext = "dies ist ein plaintext ☭" + TestingUtils.genPassphrase(true); + byte[] ciphertext; + + { // encrypt data with key + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes()); + + PgpSignEncryptOperation op = new PgpSignEncryptOperation(RuntimeEnvironment.application, + new ProviderHelper(RuntimeEnvironment.application), null); + + InputData data = new InputData(in, in.available()); + PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(); + + // only sign, as cleartext + input.setSignatureMasterKeyId(mStaticRing1.getMasterKeyId()); + input.setSignatureSubKeyId(KeyringTestingHelper.getSubkeyId(mStaticRing1, 1)); + input.setCleartextSignature(true); + input.setEnableAsciiArmorOutput(true); + input.setDetachedSignature(false); + + PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1), data, out); + Assert.assertTrue("signing must succeed", result.success()); + + ciphertext = out.toByteArray(); + } + + Assert.assertTrue("clearsigned text must contain plaintext", new String(ciphertext).contains(plaintext)); + + { // verification should succeed + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(ciphertext); + InputData data = new InputData(in, in.available()); + + PgpDecryptVerifyOperation op = operationWithFakePassphraseCache(null, null, null); + PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); + DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(), data, out); + + Assert.assertTrue("verification must succeed", result.success()); + Assert.assertArrayEquals("verification text should equal plaintext (save for a newline)", + (plaintext + StringUtils.LINE_SEP).getBytes(), out.toByteArray()); + Assert.assertEquals("decryptionResult should be RESULT_NOT_ENCRYPTED", + OpenPgpDecryptionResult.RESULT_NOT_ENCRYPTED, result.getDecryptionResult().getResult()); + Assert.assertEquals("signatureResult should be RESULT_VALID_CONFIRMED", + OpenPgpSignatureResult.RESULT_VALID_CONFIRMED, result.getSignatureResult().getResult()); + + OpenPgpMetadata metadata = result.getDecryptionMetadata(); + Assert.assertEquals("filesize must be correct", + out.toByteArray().length, metadata.getOriginalSize()); + + } + + } + + @Test + public void testAsymmetricSignDetached() { + + String plaintext = "dies ist ein plaintext ☭" + TestingUtils.genPassphrase(true); + byte[] detachedSignature; + + { // encrypt data with key + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes()); + + PgpSignEncryptOperation op = new PgpSignEncryptOperation(RuntimeEnvironment.application, + new ProviderHelper(RuntimeEnvironment.application), null); + + InputData data = new InputData(in, in.available()); + PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(); + + // only sign, as cleartext + input.setSignatureMasterKeyId(mStaticRing1.getMasterKeyId()); + input.setSignatureSubKeyId(KeyringTestingHelper.getSubkeyId(mStaticRing1, 1)); + input.setDetachedSignature(true); + + PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1), data, out); + Assert.assertTrue("signing must succeed", result.success()); + + detachedSignature = result.getDetachedSignature(); + } + + { // verification should succeed + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes()); + InputData data = new InputData(in, in.available()); + + PgpDecryptVerifyOperation op = operationWithFakePassphraseCache(null, null, null); + PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); + input.setDetachedSignature(detachedSignature); + DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(), data, out); + + Assert.assertTrue("verification must succeed", result.success()); + Assert.assertArrayEquals("verification text should equal plaintext (save for a newline)", + plaintext.getBytes(), out.toByteArray()); + Assert.assertEquals("decryptionResult should be RESULT_NOT_ENCRYPTED", + OpenPgpDecryptionResult.RESULT_NOT_ENCRYPTED, result.getDecryptionResult().getResult()); + Assert.assertEquals("signatureResult should be RESULT_VALID_CONFIRMED", + OpenPgpSignatureResult.RESULT_VALID_CONFIRMED, result.getSignatureResult().getResult()); + + // TODO should detached verify return any metadata? + // OpenPgpMetadata metadata = result.getDecryptionMetadata(); + // Assert.assertEquals("filesize must be correct", + // out.toByteArray().length, metadata.getOriginalSize()); + + } + + } + @Test public void testAsymmetricEncryptDecrypt() { -- cgit v1.2.3 From cda1ba47d27c668e99fe212f2ce0977962eabb86 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 8 Oct 2015 18:37:30 +0200 Subject: pgpdecryptverify: fix non-onepass signature checking --- .../org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java | 2 ++ .../java/org/sufficientlysecure/keychain/pgp/PgpSignatureChecker.java | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java index f31b6af59..39cd65671 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java @@ -963,6 +963,8 @@ public class PgpDecryptVerifyOperation extends BaseOperation Date: Thu, 8 Oct 2015 18:39:27 +0200 Subject: Constant for max number of canonicalized user ids --- .../java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 87e7ec461..96778649c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -84,6 +84,8 @@ public class UncachedKeyRing implements Serializable { final PGPKeyRing mRing; final boolean mIsSecret; + private static final int CANONICALIZE_MAX_USER_IDS = 100; + UncachedKeyRing(PGPKeyRing ring) { mRing = ring; mIsSecret = ring instanceof PGPSecretKeyRing; @@ -461,7 +463,7 @@ public class UncachedKeyRing implements Serializable { // strip out the first found user id with this name modified = PGPPublicKey.removeCertification(modified, rawUserId); } - if (processedUserIds.size() > 100) { + if (processedUserIds.size() > CANONICALIZE_MAX_USER_IDS) { log.add(LogType.MSG_KC_UID_TOO_MANY, indent, userId); // strip out the user id modified = PGPPublicKey.removeCertification(modified, rawUserId); -- cgit v1.2.3 From 1328309009efc584375e79e478cdbf3c3a221508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 8 Oct 2015 18:47:28 +0200 Subject: Remove ShareHelper: Not compat with Android >= 5, reduce code complexity --- .../keychain/ui/DisplayTextFragment.java | 20 +--- .../keychain/ui/EncryptFilesFragment.java | 21 +---- .../keychain/ui/EncryptTextFragment.java | 20 +--- .../keychain/util/ShareHelper.java | 104 --------------------- 4 files changed, 6 insertions(+), 159 deletions(-) delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ShareHelper.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DisplayTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DisplayTextFragment.java index dc06e9115..1060714f0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DisplayTextFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DisplayTextFragment.java @@ -36,7 +36,6 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.Notify.Style; -import org.sufficientlysecure.keychain.util.ShareHelper; public class DisplayTextFragment extends DecryptFragment { @@ -60,22 +59,6 @@ public class DisplayTextFragment extends DecryptFragment { return frag; } - /** - * Create Intent Chooser but exclude decrypt activites - */ - private Intent sendWithChooserExcludingDecrypt(String text) { - Intent prototype = createSendIntent(text); - String title = getString(R.string.title_share_message); - - // we don't want to decrypt the decrypted, no inception ;) - String[] blacklist = new String[]{ - Constants.PACKAGE_NAME + ".ui.DecryptActivity", - "org.thialfihar.android.apg.ui.DecryptActivity" - }; - - return new ShareHelper(getActivity()).createChooserExcluding(prototype, title, blacklist); - } - private Intent createSendIntent(String text) { Intent sendIntent = new Intent(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, text); @@ -146,7 +129,8 @@ public class DisplayTextFragment extends DecryptFragment { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.decrypt_share: { - startActivity(sendWithChooserExcludingDecrypt(mText.getText().toString())); + startActivity(Intent.createChooser(createSendIntent(mText.getText().toString()), + getString(R.string.title_share_message))); break; } case R.id.decrypt_copy: { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java index 0e357cfcd..ebb9674bf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java @@ -69,7 +69,6 @@ import org.sufficientlysecure.keychain.util.FileHelper; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.Preferences; -import org.sufficientlysecure.keychain.util.ShareHelper; public class EncryptFilesFragment extends CachingCryptoOperationFragment { @@ -404,7 +403,7 @@ public class EncryptFilesFragment public void onDeleted() { if (mAfterEncryptAction == AfterEncryptAction.SHARE) { // Share encrypted message/file - startActivity(sendWithChooserExcludingEncrypt()); + startActivity(Intent.createChooser(createSendIntent(), getString(R.string.title_share_file))); } else { Activity activity = getActivity(); if (activity == null) { @@ -424,7 +423,7 @@ public class EncryptFilesFragment case SHARE: // Share encrypted message/file - startActivity(sendWithChooserExcludingEncrypt()); + startActivity(Intent.createChooser(createSendIntent(), getString(R.string.title_share_file))); break; case COPY: @@ -620,22 +619,6 @@ public class EncryptFilesFragment return data; } - /** - * Create Intent Chooser but exclude OK's EncryptActivity. - */ - private Intent sendWithChooserExcludingEncrypt() { - Intent prototype = createSendIntent(); - String title = getString(R.string.title_share_file); - - // we don't want to encrypt the encrypted, no inception ;) - String[] blacklist = new String[]{ - Constants.PACKAGE_NAME + ".ui.EncryptFilesActivity", - "org.thialfihar.android.apg.ui.EncryptActivity" - }; - - return new ShareHelper(getActivity()).createChooserExcluding(prototype, title, blacklist); - } - private Intent createSendIntent() { Intent sendIntent; // file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java index ab676285e..0513a6495 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java @@ -46,7 +46,6 @@ import org.sufficientlysecure.keychain.ui.util.Notify.ActionListener; import org.sufficientlysecure.keychain.ui.util.Notify.Style; import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.Preferences; -import org.sufficientlysecure.keychain.util.ShareHelper; import java.util.Date; import java.util.HashSet; @@ -289,22 +288,6 @@ public class EncryptTextFragment result.createNotify(activity).show(); } - /** - * Create Intent Chooser but exclude OK's EncryptActivity. - */ - private Intent sendWithChooserExcludingEncrypt(byte[] resultBytes) { - Intent prototype = createSendIntent(resultBytes); - String title = getString(R.string.title_share_message); - - // we don't want to encrypt the encrypted, no inception ;) - String[] blacklist = new String[]{ - Constants.PACKAGE_NAME + ".ui.EncryptTextActivity", - "org.thialfihar.android.apg.ui.EncryptActivity" - }; - - return new ShareHelper(getActivity()).createChooserExcluding(prototype, title, blacklist); - } - private Intent createSendIntent(byte[] resultBytes) { Intent sendIntent; sendIntent = new Intent(Intent.ACTION_SEND); @@ -343,7 +326,8 @@ public class EncryptTextFragment if (mShareAfterEncrypt) { // Share encrypted message/file - startActivity(sendWithChooserExcludingEncrypt(result.getResultBytes())); + startActivity(Intent.createChooser(createSendIntent(result.getResultBytes()), + getString(R.string.title_share_message))); } else { // Copy to clipboard copyToClipboard(result); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ShareHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ShareHelper.java deleted file mode 100644 index 0297d149c..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ShareHelper.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * - * 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 . - */ - -package org.sufficientlysecure.keychain.util; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.LabeledIntent; -import android.content.pm.ResolveInfo; -import android.os.Build; -import android.os.Parcelable; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -public class ShareHelper { - Context mContext; - - public ShareHelper(Context context) { - mContext = context; - } - - /** - * Create Intent Chooser but exclude specific activites, e.g., EncryptActivity to prevent encrypting again - *

- * Put together from some stackoverflow posts... - */ - public Intent createChooserExcluding(Intent prototype, String title, String[] activityBlacklist) { - // Produced an empty list on Huawei U8860 with Android Version 4.0.3 - // TODO: test on 4.1, 4.2, 4.3, only tested on 4.4 - // Disabled on 5.0 because using EXTRA_INITIAL_INTENTS prevents the usage based sorting - // introduced in 5.0: https://medium.com/@xXxXxXxXxXam/how-lollipops-share-menu-is-organized-d204888f606d - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT || Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - return Intent.createChooser(prototype, title); - } - - List targetedShareIntents = new ArrayList<>(); - - List resInfoList = mContext.getPackageManager().queryIntentActivities(prototype, 0); - List resInfoListFiltered = new ArrayList<>(); - if (!resInfoList.isEmpty()) { - for (ResolveInfo resolveInfo : resInfoList) { - // do not add blacklisted ones - if (resolveInfo.activityInfo == null || Arrays.asList(activityBlacklist).contains(resolveInfo.activityInfo.name)) - continue; - - resInfoListFiltered.add(resolveInfo); - } - - if (!resInfoListFiltered.isEmpty()) { - // sorting for nice readability - Collections.sort(resInfoListFiltered, new Comparator() { - @Override - public int compare(ResolveInfo first, ResolveInfo second) { - String firstName = first.loadLabel(mContext.getPackageManager()).toString(); - String secondName = second.loadLabel(mContext.getPackageManager()).toString(); - return firstName.compareToIgnoreCase(secondName); - } - }); - - // create the custom intent list - for (ResolveInfo resolveInfo : resInfoListFiltered) { - Intent targetedShareIntent = (Intent) prototype.clone(); - targetedShareIntent.setPackage(resolveInfo.activityInfo.packageName); - targetedShareIntent.setClassName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name); - - LabeledIntent lIntent = new LabeledIntent(targetedShareIntent, - resolveInfo.activityInfo.packageName, - resolveInfo.loadLabel(mContext.getPackageManager()), - resolveInfo.activityInfo.icon); - targetedShareIntents.add(lIntent); - } - - // Create chooser with only one Intent in it - Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(targetedShareIntents.size() - 1), title); - // append all other Intents - // TODO this line looks wrong?! - chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[]{})); - return chooserIntent; - } - - } - - // fallback to Android's default chooser - return Intent.createChooser(prototype, title); - } -} -- cgit v1.2.3 From 81a462c2ac66dd0dc16019af2099c7dd96fe9f36 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 8 Oct 2015 19:54:50 +0200 Subject: pgpdecryptverify: get rid of duplicate code path for binary signature verification --- .../operations/KeybaseVerificationOperation.java | 1 - .../keychain/pgp/PgpDecryptVerifyInputParcel.java | 14 +--- .../keychain/pgp/PgpDecryptVerifyOperation.java | 94 +--------------------- .../keychain/pgp/PgpEncryptDecryptTest.java | 2 +- 4 files changed, 3 insertions(+), 108 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java index aaff0a07c..f3ceac681 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java @@ -151,7 +151,6 @@ public class KeybaseVerificationOperation extends BaseOperation CREATOR = new Creator() { public PgpDecryptVerifyInputParcel createFromParcel(final Parcel source) { return new PgpDecryptVerifyInputParcel(source); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java index 39cd65671..d3c722761 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java @@ -35,7 +35,6 @@ import android.webkit.MimeTypeMap; import org.openintents.openpgp.OpenPgpDecryptionResult; import org.openintents.openpgp.OpenPgpMetadata; -import org.openintents.openpgp.OpenPgpSignatureResult; import org.spongycastle.bcpg.ArmoredInputStream; import org.spongycastle.openpgp.PGPCompressedData; import org.spongycastle.openpgp.PGPDataValidationException; @@ -149,9 +148,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation 0) { - out.write(buffer, 0, length); - signatureChecker.updateSignatureData(buffer, 0, length); - } - - updateProgress(R.string.progress_verifying_signature, 95, 100); - log.add(LogType.MSG_VL_CLEAR_SIGNATURE_CHECK, indent + 1); - - o = pgpF.nextObject(); - if ( ! signatureChecker.verifySignatureOnePass(o, log, indent) ) { - return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log); - } - - OpenPgpSignatureResult signatureResult = signatureChecker.getSignatureResult(); - - if (signatureResult.getResult() != OpenPgpSignatureResult.RESULT_VALID_CONFIRMED - && signatureResult.getResult() != OpenPgpSignatureResult.RESULT_VALID_UNCONFIRMED) { - log.add(LogType.MSG_VL_ERROR_INTEGRITY_CHECK, indent); - return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log); - } - - updateProgress(R.string.progress_done, 100, 100); - - log.add(LogType.MSG_VL_OK, indent); - - // Return a positive result, with metadata and verification info - DecryptVerifyResult result = new DecryptVerifyResult(DecryptVerifyResult.RESULT_OK, log); - result.setSignatureResult(signatureResult); - result.setDecryptionResult( - new OpenPgpDecryptionResult(OpenPgpDecryptionResult.RESULT_NOT_ENCRYPTED)); - return result; - } - private static class EncryptStreamResult { // this is non-null iff an error occured, return directly diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java index 4a6c8b058..84ebc5296 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java @@ -288,7 +288,7 @@ public class PgpEncryptDecryptTest { } @Test - public void testAsymmetricSignBinary() { + public void testAsymmetricSignLiteral() { String plaintext = "dies ist ein plaintext ☭" + TestingUtils.genPassphrase(true); byte[] ciphertext; -- cgit v1.2.3 From 3bf653775b7fa668d11ea4a2369d90ad0c7f645d Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 8 Oct 2015 19:55:28 +0200 Subject: improve tests, get rid of some redundant checks --- .../keychain/pgp/PgpDecryptVerifyOperation.java | 10 ---------- .../keychain/pgp/PgpEncryptDecryptTest.java | 11 +++++++---- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java index d3c722761..0709d4f62 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java @@ -502,11 +502,6 @@ public class PgpDecryptVerifyOperation extends BaseOperation Date: Thu, 8 Oct 2015 20:01:04 +0200 Subject: pgpdecryptverify: only use keys for verification which are allowed to sign (OKC-01-013) --- .../sufficientlysecure/keychain/pgp/PgpSignatureChecker.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignatureChecker.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignatureChecker.java index a892a8a0d..4067372a1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignatureChecker.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignatureChecker.java @@ -132,8 +132,12 @@ class PgpSignatureChecker { CanonicalizedPublicKeyRing signingRing = mProviderHelper.getCanonicalizedPublicKeyRing( KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(sigKeyId) ); + CanonicalizedPublicKey keyCandidate = signingRing.getPublicKey(sigKeyId); + if ( ! signingKey.canSign()) { + continue; + } signatureIndex = i; - signingKey = signingRing.getPublicKey(sigKeyId); + signingKey = keyCandidate; onePassSignature = sigList.get(i); return; } catch (ProviderHelper.NotFoundException e) { @@ -151,8 +155,12 @@ class PgpSignatureChecker { CanonicalizedPublicKeyRing signingRing = mProviderHelper.getCanonicalizedPublicKeyRing( KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(sigKeyId) ); + CanonicalizedPublicKey keyCandidate = signingRing.getPublicKey(sigKeyId); + if ( ! signingKey.canSign()) { + continue; + } signatureIndex = i; - signingKey = signingRing.getPublicKey(sigKeyId); + signingKey = keyCandidate; signature = sigList.get(i); return; } catch (ProviderHelper.NotFoundException e) { -- cgit v1.2.3