aboutsummaryrefslogtreecommitdiffstats
path: root/OpenPGP-Keychain/src/main/java
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2014-04-06 12:57:42 +0200
committerDominik Schürmann <dominik@dominikschuermann.de>2014-04-06 12:57:42 +0200
commit6d1137190529dc7add74926cea52c377883319be (patch)
treefd88b29a048f3aec1daa2a84bbaf22c0efa3663f /OpenPGP-Keychain/src/main/java
parent17997dd362fe62d72113a0536069d0fdb9c3211b (diff)
downloadopen-keychain-6d1137190529dc7add74926cea52c377883319be.tar.gz
open-keychain-6d1137190529dc7add74926cea52c377883319be.tar.bz2
open-keychain-6d1137190529dc7add74926cea52c377883319be.zip
Rename folder structure from OpenPGP Keychain to OpenKeychain
Diffstat (limited to 'OpenPGP-Keychain/src/main/java')
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java82
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java191
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java75
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ClipboardReflection.java95
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/DialogFragmentWorkaround.java68
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ListFragmentWorkaround.java37
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ActionBarHelper.java120
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ContactHelper.java41
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java177
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/FileHelper.java131
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java70
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java171
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java200
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java836
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java93
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java218
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java294
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java644
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java769
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java607
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpToX509.java313
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/NoAsymmetricEncryptionException.java26
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralException.java29
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralMsgIdException.java35
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java297
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java301
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java752
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobContract.java40
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobDatabase.java47
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobProvider.java162
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java673
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AccountSettings.java85
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java50
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java484
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java261
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/WrongPackageSignatureException.java27
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java109
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java201
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java198
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java134
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java108
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java35
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java174
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java303
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java905
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java130
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java380
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java107
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java388
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java182
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java261
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java180
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java189
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java295
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java760
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java256
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java30
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java268
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java380
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java259
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java98
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java75
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java79
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java75
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java489
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java87
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java98
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java305
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysNFCFragment.java68
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java205
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java155
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java95
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java700
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java387
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java130
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java143
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java350
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java83
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java176
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java211
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java127
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java253
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java277
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java124
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java311
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java347
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/AsyncTaskResultWrapper.java46
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/HighlightQueryCursorAdapter.java65
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java186
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java274
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java167
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java130
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyValueSpinnerAdapter.java101
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java70
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java165
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java101
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java175
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java181
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/BadImportKeyDialogFragment.java67
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java159
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java124
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java174
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java220
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java328
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java154
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java186
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java99
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java212
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/Editor.java27
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FixedListView.java55
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java203
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/IntegerListPreference.java94
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java377
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyServerEditor.java82
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java429
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UnderlineTextView.java69
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java265
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/AlgorithmNames.java93
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/Choice.java45
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java353
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java41
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/IntentIntegratorSupportV4.java46
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/IterableIterator.java39
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java52
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeychainServiceListener.java22
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/Log.java83
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PRNGFixes.java352
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PausableThreadPoolExecutor.java94
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PositionAwareInputStream.java83
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/Primes.java188
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressDialogUpdater.java25
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressScaler.java50
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/QrCodeUtils.java72
133 files changed, 0 insertions, 26804 deletions
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java
deleted file mode 100644
index b3bfaa229..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Constants.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain;
-
-import android.os.Environment;
-
-import org.spongycastle.jce.provider.BouncyCastleProvider;
-import org.sufficientlysecure.keychain.remote.ui.AppsListActivity;
-import org.sufficientlysecure.keychain.ui.DecryptActivity;
-import org.sufficientlysecure.keychain.ui.EncryptActivity;
-import org.sufficientlysecure.keychain.ui.ImportKeysActivity;
-import org.sufficientlysecure.keychain.ui.KeyListActivity;
-
-public final class Constants {
-
- public static final boolean DEBUG = BuildConfig.DEBUG;
-
- public static final String TAG = "Keychain";
-
- public static final String PACKAGE_NAME = "org.sufficientlysecure.keychain";
-
- // as defined in http://tools.ietf.org/html/rfc3156, section 7
- public static final String NFC_MIME = "application/pgp-keys";
-
- // used by QR Codes (Guardian Project, Monkeysphere compatiblity)
- public static final String FINGERPRINT_SCHEME = "openpgp4fpr";
-
- // Not BC due to the use of Spongy Castle for Android
- public static final String SC = BouncyCastleProvider.PROVIDER_NAME;
- public static final String BOUNCY_CASTLE_PROVIDER_NAME = SC;
-
- public static final String INTENT_PREFIX = PACKAGE_NAME + ".action.";
-
- public static final class Path {
- public static final String APP_DIR = Environment.getExternalStorageDirectory()
- + "/OpenKeychain";
- public static final String APP_DIR_FILE = APP_DIR + "/export.asc";
- }
-
- public static final class Pref {
- public static final String DEFAULT_ENCRYPTION_ALGORITHM = "defaultEncryptionAlgorithm";
- public static final String DEFAULT_HASH_ALGORITHM = "defaultHashAlgorithm";
- public static final String DEFAULT_ASCII_ARMOR = "defaultAsciiArmor";
- public static final String DEFAULT_MESSAGE_COMPRESSION = "defaultMessageCompression";
- public static final String DEFAULT_FILE_COMPRESSION = "defaultFileCompression";
- public static final String PASSPHRASE_CACHE_TTL = "passphraseCacheTtl";
- public static final String LANGUAGE = "language";
- public static final String FORCE_V3_SIGNATURES = "forceV3Signatures";
- public static final String KEY_SERVERS = "keyServers";
- }
-
- public static final class Defaults {
- public static final String KEY_SERVERS = "pool.sks-keyservers.net, subkeys.pgp.net, pgp.mit.edu";
- }
-
- public static final class DrawerItems {
- public static final Class KEY_LIST = KeyListActivity.class;
- public static final Class ENCRYPT = EncryptActivity.class;
- public static final Class DECRYPT = DecryptActivity.class;
- public static final Class REGISTERED_APPS_LIST = AppsListActivity.class;
- public static final Class[] ARRAY = new Class[]{
- KEY_LIST,
- ENCRYPT,
- DECRYPT,
- REGISTERED_APPS_LIST
- };
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java
deleted file mode 100644
index 784ec340e..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain;
-
-import org.spongycastle.bcpg.CompressionAlgorithmTags;
-
-/**
- *
- * TODO:
- *
- * - refactor ids, some are not needed and can be done with xml
- *
- */
-public final class Id {
-
- public static final class menu {
-
- public static final class option {
- public static final int new_passphrase = 0x21070001;
- public static final int create = 0x21070002;
- public static final int about = 0x21070003;
- public static final int manage_public_keys = 0x21070004;
- public static final int manage_secret_keys = 0x21070005;
- public static final int export_keys = 0x21070007;
- public static final int preferences = 0x21070008;
- public static final int search = 0x21070009;
- public static final int help = 0x21070010;
- public static final int key_server = 0x21070011;
- public static final int scanQRCode = 0x21070012;
- public static final int encrypt = 0x21070013;
- public static final int encrypt_to_clipboard = 0x21070014;
- public static final int decrypt = 0x21070015;
- public static final int reply = 0x21070016;
- public static final int cancel = 0x21070017;
- public static final int save = 0x21070018;
- public static final int okay = 0x21070019;
- public static final int import_from_file = 0x21070020;
- public static final int import_from_qr_code = 0x21070021;
- public static final int import_from_nfc = 0x21070022;
- public static final int crypto_consumers = 0x21070023;
- public static final int createExpert = 0x21070024;
- }
- }
-
- // use only lower 16 bits due to compatibility lib
- public static final class message {
- public static final int progress_update = 0x00006001;
- public static final int done = 0x00006002;
- public static final int import_keys = 0x00006003;
- public static final int export_keys = 0x00006004;
- public static final int import_done = 0x00006005;
- public static final int export_done = 0x00006006;
- public static final int create_key = 0x00006007;
- public static final int edit_key = 0x00006008;
- public static final int delete_done = 0x00006009;
- public static final int query_done = 0x00006010;
- public static final int unknown_signature_key = 0x00006011;
- }
-
- // use only lower 16 bits due to compatibility lib
- public static final class request {
- public static final int public_keys = 0x00007001;
- public static final int secret_keys = 0x00007002;
- public static final int filename = 0x00007003;
-// public static final int output_filename = 0x00007004;
- public static final int key_server_preference = 0x00007005;
-// public static final int look_up_key_id = 0x00007006;
- public static final int export_to_server = 0x00007007;
- public static final int import_from_qr_code = 0x00007008;
- public static final int sign_key = 0x00007009;
- }
-
- public static final class dialog {
- public static final int passphrase = 0x21070001;
- public static final int encrypting = 0x21070002;
- public static final int decrypting = 0x21070003;
- public static final int new_passphrase = 0x21070004;
- public static final int passphrases_do_not_match = 0x21070005;
- public static final int no_passphrase = 0x21070006;
- public static final int saving = 0x21070007;
- public static final int delete_key = 0x21070008;
- public static final int import_keys = 0x21070009;
- public static final int importing = 0x2107000a;
- public static final int export_key = 0x2107000b;
- public static final int export_keys = 0x2107000c;
- public static final int exporting = 0x2107000d;
- public static final int new_account = 0x2107000e;
- public static final int change_log = 0x21070010;
- public static final int output_filename = 0x21070011;
- public static final int delete_file = 0x21070012;
- public static final int deleting = 0x21070013;
- public static final int help = 0x21070014;
- public static final int querying = 0x21070015;
- public static final int lookup_unknown_key = 0x21070016;
- public static final int signing = 0x21070017;
- }
-
- public static final class task {
- public static final int import_keys = 0x21070001;
- public static final int export_keys = 0x21070002;
- }
-
- public static final class type {
- public static final int public_key = 0x21070001;
- public static final int secret_key = 0x21070002;
- public static final int user_id = 0x21070003;
- public static final int key = 0x21070004;
- public static final int public_secret_key = 0x21070005;
- }
-
- public static final class choice {
- public static final class algorithm {
- public static final int dsa = 0x21070001;
- public static final int elgamal = 0x21070002;
- public static final int rsa = 0x21070003;
- }
-
- public static final class compression {
- public static final int none = 0x21070001;
- public static final int zlib = CompressionAlgorithmTags.ZLIB;
- public static final int bzip2 = CompressionAlgorithmTags.BZIP2;
- public static final int zip = CompressionAlgorithmTags.ZIP;
- }
-
- public static final class usage {
- public static final int sign_only = 0x21070001;
- public static final int encrypt_only = 0x21070002;
- public static final int sign_and_encrypt = 0x21070003;
- }
-
- public static final class action {
- public static final int encrypt = 0x21070001;
- public static final int decrypt = 0x21070002;
- public static final int import_public = 0x21070003;
- public static final int import_secret = 0x21070004;
- }
- }
-
- public static final class return_value {
- public static final int ok = 0;
- public static final int error = -1;
- public static final int no_master_key = -2;
- public static final int updated = 1;
- public static final int bad = -3;
- }
-
- public static final class target {
- public static final int clipboard = 0x21070001;
- public static final int email = 0x21070002;
- public static final int file = 0x21070003;
- public static final int message = 0x21070004;
- }
-
- public static final class mode {
- public static final int undefined = 0x21070001;
- public static final int byte_array = 0x21070002;
- public static final int file = 0x21070003;
- public static final int stream = 0x21070004;
- }
-
- public static final class key {
- public static final int none = 0;
- public static final int symmetric = -1;
- }
-
- public static final class content {
- public static final int unknown = 0;
- public static final int encrypted_data = 1;
- public static final int keys = 2;
- }
-
- public static final class keyserver {
- public static final int search = 0x21070001;
- public static final int get = 0x21070002;
- public static final int add = 0x21070003;
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java
deleted file mode 100644
index 9b80e76f3..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain;
-
-import android.app.Application;
-import android.os.Environment;
-
-import org.spongycastle.jce.provider.BouncyCastleProvider;
-
-import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.util.PRNGFixes;
-
-import java.io.File;
-import java.security.Provider;
-import java.security.Security;
-
-public class KeychainApplication extends Application {
-
- /**
- * Called when the application is starting, before any activity, service, or receiver objects
- * (excluding content providers) have been created.
- */
- @Override
- public void onCreate() {
- super.onCreate();
-
- /*
- * Sets Bouncy (Spongy) Castle as preferred security provider
- *
- * insertProviderAt() position starts from 1
- */
- Security.insertProviderAt(new BouncyCastleProvider(), 1);
-
- /*
- * apply RNG fixes
- *
- * among other things, executes Security.insertProviderAt(new
- * LinuxPRNGSecureRandomProvider(), 1) for Android <= SDK 17
- */
- PRNGFixes.apply();
- Log.d(Constants.TAG, "Bouncy Castle set and PRNG Fixes applied!");
-
- if (Constants.DEBUG) {
- Provider[] providers = Security.getProviders();
- Log.d(Constants.TAG, "Installed Security Providers:");
- for (Provider p : providers) {
- Log.d(Constants.TAG, "provider class: " + p.getClass().getName());
- }
- }
-
- // Create APG directory on sdcard if not existing
- if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- File dir = new File(Constants.Path.APP_DIR);
- if (!dir.exists() && !dir.mkdirs()) {
- // ignore this for now, it's not crucial
- // that the directory doesn't exist at this point
- }
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ClipboardReflection.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ClipboardReflection.java
deleted file mode 100644
index 1cac5762d..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ClipboardReflection.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.compatibility;
-
-import android.content.Context;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.lang.reflect.Method;
-
-public class ClipboardReflection {
-
- private static final String clipboardLabel = "Keychain";
-
- /**
- * Wrapper around ClipboardManager based on Android version using Reflection API
- *
- * @param context
- * @param text
- */
- public static void copyToClipboard(Context context, String text) {
- Object clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE);
- try {
- if ("android.text.ClipboardManager".equals(clipboard.getClass().getName())) {
- Method methodSetText = clipboard.getClass()
- .getMethod("setText", CharSequence.class);
- methodSetText.invoke(clipboard, text);
- } else if ("android.content.ClipboardManager".equals(clipboard.getClass().getName())) {
- Class<?> classClipData = Class.forName("android.content.ClipData");
- Method methodNewPlainText = classClipData.getMethod("newPlainText",
- CharSequence.class, CharSequence.class);
- Object clip = methodNewPlainText.invoke(null, clipboardLabel, text);
- methodNewPlainText = clipboard.getClass()
- .getMethod("setPrimaryClip", classClipData);
- methodNewPlainText.invoke(clipboard, clip);
- }
- } catch (Exception e) {
- Log.e(Constants.TAG, "There was an error copying the text to the clipboard", e);
- }
- }
-
- /**
- * Wrapper around ClipboardManager based on Android version using Reflection API
- *
- * @param context
- */
- public static CharSequence getClipboardText(Context context) {
- Object clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE);
- try {
- if ("android.text.ClipboardManager".equals(clipboard.getClass().getName())) {
- // CharSequence text = clipboard.getText();
- Method methodGetText = clipboard.getClass().getMethod("getText");
- Object text = methodGetText.invoke(clipboard);
-
- return (CharSequence) text;
- } else if ("android.content.ClipboardManager".equals(clipboard.getClass().getName())) {
- // ClipData clipData = clipboard.getPrimaryClip();
- Method methodGetPrimaryClip = clipboard.getClass().getMethod("getPrimaryClip");
- Object clipData = methodGetPrimaryClip.invoke(clipboard);
-
- // ClipData.Item clipDataItem = clipData.getItemAt(0);
- Method methodGetItemAt = clipData.getClass().getMethod("getItemAt", int.class);
- Object clipDataItem = methodGetItemAt.invoke(clipData, 0);
-
- // CharSequence text = clipDataItem.coerceToText(context);
- Method methodGetString = clipDataItem.getClass().getMethod("coerceToText",
- Context.class);
- Object text = methodGetString.invoke(clipDataItem, context);
-
- return (CharSequence) text;
- } else {
- return null;
- }
- } catch (Exception e) {
- Log.e(Constants.TAG, "There was an error getting the text from the clipboard", e);
- return null;
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/DialogFragmentWorkaround.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/DialogFragmentWorkaround.java
deleted file mode 100644
index 36f7fd23b..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/DialogFragmentWorkaround.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.compatibility;
-
-import android.os.Build;
-import android.os.Handler;
-
-/**
- * Bug on Android >= 4.2
- *
- * http://code.google.com/p/android/issues/detail?id=41901
- *
- * DialogFragment disappears on pressing home and comming back. This also happens especially in
- * FileDialogFragment after launching a file manager and coming back.
- *
- * Usage: <code>
- * DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() {
- * public void run() {
- * // show dialog...
- * }
- * });
- * </code>
- */
-public class DialogFragmentWorkaround {
- public static final SDKLevel17Interface INTERFACE =
- ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) ? new SDKLevel17Impl()
- : new SDKLevelPriorLevel17Impl());
-
- private static final int RUNNABLE_DELAY = 300;
-
- public interface SDKLevel17Interface {
- // Workaround for http://code.google.com/p/android/issues/detail?id=41901
- void runnableRunDelayed(Runnable runnable);
- }
-
- private static class SDKLevelPriorLevel17Impl implements SDKLevel17Interface {
- @Override
- public void runnableRunDelayed(Runnable runnable) {
- runnable.run();
- }
- }
-
- private static class SDKLevel17Impl implements SDKLevel17Interface {
- @Override
- public void runnableRunDelayed(Runnable runnable) {
- new Handler().postDelayed(runnable, RUNNABLE_DELAY);
- }
- }
-
- // Can't instantiate this class
- private DialogFragmentWorkaround() {
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ListFragmentWorkaround.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ListFragmentWorkaround.java
deleted file mode 100644
index 1cb91c688..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/compatibility/ListFragmentWorkaround.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.compatibility;
-
-import android.support.v4.app.ListFragment;
-import android.view.View;
-import android.widget.ListView;
-
-/**
- * Bug on Android >= 4.1
- * <p/>
- * http://code.google.com/p/android/issues/detail?id=35885
- * <p/>
- * Items are not checked in layout
- */
-public class ListFragmentWorkaround extends ListFragment {
-
- @Override
- public void onListItemClick(ListView l, View v, int position, long id) {
- l.setItemChecked(position, l.isItemChecked(position));
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ActionBarHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ActionBarHelper.java
deleted file mode 100644
index a26df556d..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ActionBarHelper.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.helper;
-
-import android.app.Activity;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.TextView;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.util.Log;
-
-public class ActionBarHelper {
-
- /**
- * Set actionbar without home button if called from another app
- *
- * @param activity
- */
- public static void setBackButton(ActionBarActivity activity) {
- final ActionBar actionBar = activity.getSupportActionBar();
- Log.d(Constants.TAG, "calling package (only set when using startActivityForResult)="
- + activity.getCallingPackage());
- if (activity.getCallingPackage() != null
- && activity.getCallingPackage().equals(Constants.PACKAGE_NAME)) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setHomeButtonEnabled(true);
- } else {
- actionBar.setDisplayHomeAsUpEnabled(false);
- actionBar.setHomeButtonEnabled(false);
- }
- }
-
- /**
- * Sets custom view on ActionBar for Done/Cancel activities
- *
- * @param actionBar
- * @param firstText
- * @param firstDrawableId
- * @param firstOnClickListener
- * @param secondText
- * @param secondDrawableId
- * @param secondOnClickListener
- */
- public static void setTwoButtonView(ActionBar actionBar,
- int firstText, int firstDrawableId, OnClickListener firstOnClickListener,
- int secondText, int secondDrawableId, OnClickListener secondOnClickListener) {
-
- // Inflate the custom action bar view
- final LayoutInflater inflater = (LayoutInflater) actionBar.getThemedContext()
- .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
- final View customActionBarView = inflater.inflate(
- R.layout.actionbar_custom_view_done_cancel, null);
-
- TextView firstTextView = ((TextView) customActionBarView.findViewById(R.id.actionbar_done_text));
- firstTextView.setText(firstText);
- firstTextView.setCompoundDrawablesWithIntrinsicBounds(firstDrawableId, 0, 0, 0);
- customActionBarView.findViewById(R.id.actionbar_done).setOnClickListener(
- firstOnClickListener);
- TextView secondTextView = ((TextView) customActionBarView.findViewById(R.id.actionbar_cancel_text));
- secondTextView.setText(secondText);
- secondTextView.setCompoundDrawablesWithIntrinsicBounds(secondDrawableId, 0, 0, 0);
- customActionBarView.findViewById(R.id.actionbar_cancel).setOnClickListener(
- secondOnClickListener);
-
- // Show the custom action bar view and hide the normal Home icon and title.
- actionBar.setDisplayShowTitleEnabled(false);
- actionBar.setDisplayShowHomeEnabled(false);
- actionBar.setDisplayShowCustomEnabled(true);
- actionBar.setCustomView(customActionBarView, new ActionBar.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
- }
-
- /**
- * Sets custom view on ActionBar for Done activities
- *
- * @param actionBar
- * @param firstText
- * @param firstOnClickListener
- */
- public static void setOneButtonView(ActionBar actionBar, int firstText, int firstDrawableId,
- OnClickListener firstOnClickListener) {
- // Inflate a "Done" custom action bar view to serve as the "Up" affordance.
- final LayoutInflater inflater = (LayoutInflater) actionBar.getThemedContext()
- .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
- final View customActionBarView = inflater
- .inflate(R.layout.actionbar_custom_view_done, null);
-
- TextView firstTextView = ((TextView) customActionBarView.findViewById(R.id.actionbar_done_text));
- firstTextView.setText(firstText);
- firstTextView.setCompoundDrawablesWithIntrinsicBounds(firstDrawableId, 0, 0, 0);
- customActionBarView.findViewById(R.id.actionbar_done).setOnClickListener(
- firstOnClickListener);
-
- // Show the custom action bar view and hide the normal Home icon and title.
- actionBar.setDisplayShowTitleEnabled(false);
- actionBar.setDisplayShowHomeEnabled(false);
- actionBar.setDisplayShowCustomEnabled(true);
- actionBar.setCustomView(customActionBarView);
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ContactHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ContactHelper.java
deleted file mode 100644
index f8ed21816..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ContactHelper.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.helper;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.content.Context;
-import android.util.Patterns;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-public class ContactHelper {
-
- public static final List<String> getMailAccounts(Context context) {
- final Account[] accounts = AccountManager.get(context).getAccounts();
- final Set<String> emailSet = new HashSet<String>();
- for (Account account : accounts) {
- if (Patterns.EMAIL_ADDRESS.matcher(account.name).matches()) {
- emailSet.add(account.name);
- }
- }
- return new ArrayList<String>(emailSet);
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java
deleted file mode 100644
index 810f22d8e..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.helper;
-
-import android.app.ProgressDialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
-import android.support.v7.app.ActionBarActivity;
-import android.widget.Toast;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
-import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment;
-import org.sufficientlysecure.keychain.util.Log;
-
-public class ExportHelper {
- protected FileDialogFragment mFileDialog;
- protected String mExportFilename;
-
- ActionBarActivity mActivity;
-
- public ExportHelper(ActionBarActivity activity) {
- super();
- this.mActivity = activity;
- }
-
- public void deleteKey(Uri dataUri, Handler deleteHandler) {
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(deleteHandler);
- long masterKeyId = ProviderHelper.getMasterKeyId(mActivity, dataUri);
-
- DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger,
- new long[]{ masterKeyId });
- deleteKeyDialog.show(mActivity.getSupportFragmentManager(), "deleteKeyDialog");
- }
-
- /**
- * Show dialog where to export keys
- */
- public void showExportKeysDialog(final long[] masterKeyIds, final String exportFilename,
- final boolean showSecretCheckbox) {
- mExportFilename = exportFilename;
-
- // Message is received after file is selected
- Handler returnHandler = new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.what == FileDialogFragment.MESSAGE_OKAY) {
- Bundle data = message.getData();
- mExportFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME);
-
- exportKeys(masterKeyIds, data.getBoolean(FileDialogFragment.MESSAGE_DATA_CHECKED));
- }
- }
- };
-
- // Create a new Messenger for the communication back
- final Messenger messenger = new Messenger(returnHandler);
-
- DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() {
- public void run() {
- String title = null;
- if (masterKeyIds == null) {
- // export all keys
- title = mActivity.getString(R.string.title_export_keys);
- } else {
- // export only key specified at data uri
- title = mActivity.getString(R.string.title_export_key);
- }
-
- String message = mActivity.getString(R.string.specify_file_to_export_to);
- String checkMsg = showSecretCheckbox ?
- mActivity.getString(R.string.also_export_secret_keys) : null;
-
- mFileDialog = FileDialogFragment.newInstance(messenger, title, message,
- exportFilename, checkMsg);
-
- mFileDialog.show(mActivity.getSupportFragmentManager(), "fileDialog");
- }
- });
- }
-
- /**
- * Export keys
- */
- public void exportKeys(long[] masterKeyIds, boolean exportSecret) {
- Log.d(Constants.TAG, "exportKeys started");
-
- // Send all information needed to service to export key in other thread
- final Intent intent = new Intent(mActivity, KeychainIntentService.class);
-
- intent.setAction(KeychainIntentService.ACTION_EXPORT_KEYRING);
-
- // fill values for this action
- Bundle data = new Bundle();
-
- data.putString(KeychainIntentService.EXPORT_FILENAME, mExportFilename);
- data.putBoolean(KeychainIntentService.EXPORT_SECRET, exportSecret);
-
- if (masterKeyIds == null) {
- data.putBoolean(KeychainIntentService.EXPORT_ALL, true);
- } else {
- data.putLongArray(KeychainIntentService.EXPORT_KEY_RING_MASTER_KEY_ID, masterKeyIds);
- }
-
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
-
- // Message is received after exporting is done in KeychainIntentService
- KeychainIntentServiceHandler exportHandler = new KeychainIntentServiceHandler(mActivity,
- mActivity.getString(R.string.progress_exporting),
- ProgressDialog.STYLE_HORIZONTAL,
- true,
- new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialogInterface) {
- mActivity.stopService(intent);
- }
- }) {
- public void handleMessage(Message message) {
- // handle messages by standard KeychainIntentServiceHandler first
- super.handleMessage(message);
-
- if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- // get returned data bundle
- Bundle returnData = message.getData();
-
- int exported = returnData.getInt(KeychainIntentService.RESULT_EXPORT);
- String toastMessage;
- if (exported == 1) {
- toastMessage = mActivity.getString(R.string.key_exported);
- } else if (exported > 0) {
- toastMessage = mActivity.getString(R.string.keys_exported, exported);
- } else {
- toastMessage = mActivity.getString(R.string.no_keys_exported);
- }
- Toast.makeText(mActivity, toastMessage, Toast.LENGTH_SHORT).show();
-
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(exportHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
-
- // show progress dialog
- exportHandler.showProgressDialog(mActivity);
-
- // start service with intent
- mActivity.startService(intent);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/FileHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/FileHelper.java
deleted file mode 100644
index d24aeca52..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/FileHelper.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.helper;
-
-import android.app.Activity;
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Environment;
-import android.support.v4.app.Fragment;
-import android.widget.Toast;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.util.Log;
-
-public class FileHelper {
-
- /**
- * Checks if external storage is mounted if file is located on external storage
- *
- * @param file
- * @return true if storage is mounted
- */
- public static boolean isStorageMounted(String file) {
- if (file.startsWith(Environment.getExternalStorageDirectory().getAbsolutePath())) {
- if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Opens the preferred installed file manager on Android and shows a toast if no manager is
- * installed.
- *
- * @param activity
- * @param filename default selected file, not supported by all file managers
- * @param mimeType can be text/plain for example
- * @param requestCode requestCode used to identify the result coming back from file manager to
- * onActivityResult() in your activity
- */
- public static void openFile(Activity activity, String filename, String mimeType, int requestCode) {
- Intent intent = buildFileIntent(filename, mimeType);
-
- try {
- activity.startActivityForResult(intent, requestCode);
- } catch (ActivityNotFoundException e) {
- // No compatible file manager was found.
- Toast.makeText(activity, R.string.no_filemanager_installed, Toast.LENGTH_SHORT).show();
- }
- }
-
- public static void openFile(Fragment fragment, String filename, String mimeType, int requestCode) {
- Intent intent = buildFileIntent(filename, mimeType);
-
- try {
- fragment.startActivityForResult(intent, requestCode);
- } catch (ActivityNotFoundException e) {
- // No compatible file manager was found.
- Toast.makeText(fragment.getActivity(), R.string.no_filemanager_installed,
- Toast.LENGTH_SHORT).show();
- }
- }
-
- private static Intent buildFileIntent(String filename, String mimeType) {
- Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
- intent.addCategory(Intent.CATEGORY_OPENABLE);
-
- intent.setData(Uri.parse("file://" + filename));
- intent.setType(mimeType);
-
- return intent;
- }
-
- /**
- * Get a file path from a Uri.
- * <p/>
- * from https://github.com/iPaulPro/aFileChooser/blob/master/aFileChooser/src/com/ipaulpro/
- * afilechooser/utils/FileUtils.java
- *
- * @param context
- * @param uri
- * @return
- * @author paulburke
- */
- public static String getPath(Context context, Uri uri) {
- Log.d(Constants.TAG + " File -",
- "Authority: " + uri.getAuthority() + ", Fragment: " + uri.getFragment()
- + ", Port: " + uri.getPort() + ", Query: " + uri.getQuery() + ", Scheme: "
- + uri.getScheme() + ", Host: " + uri.getHost() + ", Segments: "
- + uri.getPathSegments().toString());
-
- if ("content".equalsIgnoreCase(uri.getScheme())) {
- String[] projection = {"_data"};
- Cursor cursor = null;
-
- try {
- cursor = context.getContentResolver().query(uri, projection, null, null, null);
- int columnIndex = cursor.getColumnIndexOrThrow("_data");
- if (cursor.moveToFirst()) {
- return cursor.getString(columnIndex);
- }
- } catch (Exception e) {
- // Eat it
- }
- } else if ("file".equalsIgnoreCase(uri.getScheme())) {
- return uri.getPath();
- }
-
- return null;
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java
deleted file mode 100644
index b31a889f0..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.helper;
-
-import android.os.Bundle;
-import android.text.SpannableStringBuilder;
-import android.text.Spanned;
-
-import android.text.style.StrikethroughSpan;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.util.Iterator;
-import java.util.Set;
-
-public class OtherHelper {
-
- /**
- * Logs bundle content to debug for inspecting the content
- *
- * @param bundle
- * @param bundleName
- */
- public static void logDebugBundle(Bundle bundle, String bundleName) {
- if (Constants.DEBUG) {
- if (bundle != null) {
- Set<String> ks = bundle.keySet();
- Iterator<String> iterator = ks.iterator();
-
- Log.d(Constants.TAG, "Bundle " + bundleName + ":");
- Log.d(Constants.TAG, "------------------------------");
- while (iterator.hasNext()) {
- String key = iterator.next();
- Object value = bundle.get(key);
-
- if (value != null) {
- Log.d(Constants.TAG, key + " : " + value.toString());
- } else {
- Log.d(Constants.TAG, key + " : null");
- }
- }
- Log.d(Constants.TAG, "------------------------------");
- } else {
- Log.d(Constants.TAG, "Bundle " + bundleName + ": null");
- }
- }
- }
-
- public static SpannableStringBuilder strikeOutText(CharSequence text) {
- SpannableStringBuilder sb = new SpannableStringBuilder(text);
- sb.setSpan(new StrikethroughSpan(), 0, text.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
- return sb;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java
deleted file mode 100644
index ca5555fea..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.helper;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import org.spongycastle.bcpg.HashAlgorithmTags;
-import org.spongycastle.openpgp.PGPEncryptedData;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-
-import java.util.Vector;
-
-/**
- * Singleton Implementation of a Preference Helper
- */
-public class Preferences {
- private static Preferences sPreferences;
- private SharedPreferences mSharedPreferences;
-
- public static synchronized Preferences getPreferences(Context context) {
- return getPreferences(context, false);
- }
-
- public static synchronized Preferences getPreferences(Context context, boolean forceNew) {
- if (sPreferences == null || forceNew) {
- sPreferences = new Preferences(context);
- }
- return sPreferences;
- }
-
- private Preferences(Context context) {
- mSharedPreferences = context.getSharedPreferences("APG.main", Context.MODE_PRIVATE);
- }
-
- public String getLanguage() {
- return mSharedPreferences.getString(Constants.Pref.LANGUAGE, "");
- }
-
- public void setLanguage(String value) {
- SharedPreferences.Editor editor = mSharedPreferences.edit();
- editor.putString(Constants.Pref.LANGUAGE, value);
- editor.commit();
- }
-
- public long getPassphraseCacheTtl() {
- int ttl = mSharedPreferences.getInt(Constants.Pref.PASSPHRASE_CACHE_TTL, 180);
- // fix the value if it was set to "never" in previous versions, which currently is not
- // supported
- if (ttl == 0) {
- ttl = 180;
- }
- return (long) ttl;
- }
-
- public void setPassphraseCacheTtl(int value) {
- SharedPreferences.Editor editor = mSharedPreferences.edit();
- editor.putInt(Constants.Pref.PASSPHRASE_CACHE_TTL, value);
- editor.commit();
- }
-
- public int getDefaultEncryptionAlgorithm() {
- return mSharedPreferences.getInt(Constants.Pref.DEFAULT_ENCRYPTION_ALGORITHM,
- PGPEncryptedData.AES_256);
- }
-
- public void setDefaultEncryptionAlgorithm(int value) {
- SharedPreferences.Editor editor = mSharedPreferences.edit();
- editor.putInt(Constants.Pref.DEFAULT_ENCRYPTION_ALGORITHM, value);
- editor.commit();
- }
-
- public int getDefaultHashAlgorithm() {
- return mSharedPreferences.getInt(Constants.Pref.DEFAULT_HASH_ALGORITHM,
- HashAlgorithmTags.SHA512);
- }
-
- public void setDefaultHashAlgorithm(int value) {
- SharedPreferences.Editor editor = mSharedPreferences.edit();
- editor.putInt(Constants.Pref.DEFAULT_HASH_ALGORITHM, value);
- editor.commit();
- }
-
- public int getDefaultMessageCompression() {
- return mSharedPreferences.getInt(Constants.Pref.DEFAULT_MESSAGE_COMPRESSION,
- Id.choice.compression.zlib);
- }
-
- public void setDefaultMessageCompression(int value) {
- SharedPreferences.Editor editor = mSharedPreferences.edit();
- editor.putInt(Constants.Pref.DEFAULT_MESSAGE_COMPRESSION, value);
- editor.commit();
- }
-
- public int getDefaultFileCompression() {
- return mSharedPreferences.getInt(Constants.Pref.DEFAULT_FILE_COMPRESSION,
- Id.choice.compression.none);
- }
-
- public void setDefaultFileCompression(int value) {
- SharedPreferences.Editor editor = mSharedPreferences.edit();
- editor.putInt(Constants.Pref.DEFAULT_FILE_COMPRESSION, value);
- editor.commit();
- }
-
- public boolean getDefaultAsciiArmor() {
- return mSharedPreferences.getBoolean(Constants.Pref.DEFAULT_ASCII_ARMOR, false);
- }
-
- public void setDefaultAsciiArmor(boolean value) {
- SharedPreferences.Editor editor = mSharedPreferences.edit();
- editor.putBoolean(Constants.Pref.DEFAULT_ASCII_ARMOR, value);
- editor.commit();
- }
-
- public boolean getForceV3Signatures() {
- return mSharedPreferences.getBoolean(Constants.Pref.FORCE_V3_SIGNATURES, false);
- }
-
- public void setForceV3Signatures(boolean value) {
- SharedPreferences.Editor editor = mSharedPreferences.edit();
- editor.putBoolean(Constants.Pref.FORCE_V3_SIGNATURES, value);
- editor.commit();
- }
-
- public String[] getKeyServers() {
- String rawData = mSharedPreferences.getString(Constants.Pref.KEY_SERVERS,
- Constants.Defaults.KEY_SERVERS);
- Vector<String> servers = new Vector<String>();
- String chunks[] = rawData.split(",");
- for (String c : chunks) {
- String tmp = c.trim();
- if (tmp.length() > 0) {
- servers.add(tmp);
- }
- }
- return servers.toArray(chunks);
- }
-
- public void setKeyServers(String[] value) {
- SharedPreferences.Editor editor = mSharedPreferences.edit();
- String rawData = "";
- for (String v : value) {
- String tmp = v.trim();
- if (tmp.length() == 0) {
- continue;
- }
- if (!"".equals(rawData)) {
- rawData += ",";
- }
- rawData += tmp;
- }
- editor.putString(Constants.Pref.KEY_SERVERS, rawData);
- editor.commit();
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java
deleted file mode 100644
index c6c62d649..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.pgp;
-
-import org.spongycastle.openpgp.PGPKeyRing;
-import org.spongycastle.openpgp.PGPObjectFactory;
-import org.spongycastle.openpgp.PGPSecretKey;
-import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.spongycastle.openpgp.PGPSignature;
-import org.spongycastle.openpgp.PGPSignatureList;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-
-public class PgpConversionHelper {
-
- /**
- * Convert from byte[] to PGPKeyRing
- *
- * @param keysBytes
- * @return
- */
- public static PGPKeyRing BytesToPGPKeyRing(byte[] keysBytes) {
- PGPObjectFactory factory = new PGPObjectFactory(keysBytes);
- PGPKeyRing keyRing = null;
- try {
- if ((keyRing = (PGPKeyRing) factory.nextObject()) == null) {
- Log.e(Constants.TAG, "No keys given!");
- }
- } catch (IOException e) {
- Log.e(Constants.TAG, "Error while converting to PGPKeyRing!", e);
- }
-
- return keyRing;
- }
-
- /**
- * Convert from byte[] to ArrayList<PGPSecretKey>
- *
- * @param keysBytes
- * @return
- */
- public static ArrayList<PGPSecretKey> BytesToPGPSecretKeyList(byte[] keysBytes) {
- PGPObjectFactory factory = new PGPObjectFactory(keysBytes);
- Object obj = null;
- ArrayList<PGPSecretKey> keys = new ArrayList<PGPSecretKey>();
- try {
- while ((obj = factory.nextObject()) != null) {
- PGPSecretKey secKey = null;
- if (obj instanceof PGPSecretKey) {
- secKey = (PGPSecretKey) obj;
- if (secKey == null) {
- Log.e(Constants.TAG, "No keys given!");
- }
- keys.add(secKey);
- } else if (obj instanceof PGPSecretKeyRing) { //master keys are sent as keyrings
- PGPSecretKeyRing keyRing = null;
- keyRing = (PGPSecretKeyRing) obj;
- if (keyRing == null) {
- Log.e(Constants.TAG, "No keys given!");
- }
- @SuppressWarnings("unchecked")
- Iterator<PGPSecretKey> itr = keyRing.getSecretKeys();
- while (itr.hasNext()) {
- keys.add(itr.next());
- }
- }
- }
- } catch (IOException e) {
- }
-
- return keys;
- }
-
- /**
- * Convert from byte[] to PGPSecretKey
- * <p/>
- * Singles keys are encoded as keyRings with one single key in it by Bouncy Castle
- *
- * @param keyBytes
- * @return
- */
- public static PGPSecretKey BytesToPGPSecretKey(byte[] keyBytes) {
- PGPObjectFactory factory = new PGPObjectFactory(keyBytes);
- Object obj = null;
- try {
- obj = factory.nextObject();
- } catch (IOException e) {
- Log.e(Constants.TAG, "Error while converting to PGPSecretKey!", e);
- }
- PGPSecretKey secKey = null;
- if (obj instanceof PGPSecretKey) {
- if ((secKey = (PGPSecretKey) obj) == null) {
- Log.e(Constants.TAG, "No keys given!");
- }
- } else if (obj instanceof PGPSecretKeyRing) { //master keys are sent as keyrings
- PGPSecretKeyRing keyRing = null;
- if ((keyRing = (PGPSecretKeyRing) obj) == null) {
- Log.e(Constants.TAG, "No keys given!");
- }
- secKey = keyRing.getSecretKey();
- }
-
- return secKey;
- }
-
- /**
- * Convert from byte[] to PGPSignature
- *
- * @param sigBytes
- * @return
- */
- public static PGPSignature BytesToPGPSignature(byte[] sigBytes) {
- PGPObjectFactory factory = new PGPObjectFactory(sigBytes);
- PGPSignatureList signatures = null;
- try {
- if ((signatures = (PGPSignatureList) factory.nextObject()) == null || signatures.isEmpty()) {
- Log.e(Constants.TAG, "No signatures given!");
- return null;
- }
- } catch (IOException e) {
- Log.e(Constants.TAG, "Error while converting to PGPSignature!", e);
- return null;
- }
-
- return signatures.get(0);
- }
-
- /**
- * Convert from ArrayList<PGPSecretKey> to byte[]
- *
- * @param keys
- * @return
- */
- public static byte[] PGPSecretKeyArrayListToBytes(ArrayList<PGPSecretKey> keys) {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- for (PGPSecretKey key : keys) {
- try {
- key.encode(os);
- } catch (IOException e) {
- Log.e(Constants.TAG, "Error while converting ArrayList<PGPSecretKey> to byte[]!", e);
- }
- }
-
- return os.toByteArray();
- }
-
- /**
- * Convert from PGPSecretKey to byte[]
- *
- * @param key
- * @return
- */
- public static byte[] PGPSecretKeyToBytes(PGPSecretKey key) {
- try {
- return key.getEncoded();
- } catch (IOException e) {
- Log.e(Constants.TAG, "Encoding failed", e);
-
- return null;
- }
- }
-
- /**
- * Convert from PGPSecretKeyRing to byte[]
- *
- * @param keyRing
- * @return
- */
- public static byte[] PGPSecretKeyRingToBytes(PGPSecretKeyRing keyRing) {
- try {
- return keyRing.getEncoded();
- } catch (IOException e) {
- Log.e(Constants.TAG, "Encoding failed", e);
-
- return null;
- }
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
deleted file mode 100644
index 8a0bf99d7..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
+++ /dev/null
@@ -1,836 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.pgp;
-
-import android.content.Context;
-
-import org.openintents.openpgp.OpenPgpSignatureResult;
-import org.spongycastle.bcpg.ArmoredInputStream;
-import org.spongycastle.bcpg.SignatureSubpacketTags;
-import org.spongycastle.openpgp.PGPCompressedData;
-import org.spongycastle.openpgp.PGPEncryptedData;
-import org.spongycastle.openpgp.PGPEncryptedDataList;
-import org.spongycastle.openpgp.PGPException;
-import org.spongycastle.openpgp.PGPLiteralData;
-import org.spongycastle.openpgp.PGPObjectFactory;
-import org.spongycastle.openpgp.PGPOnePassSignature;
-import org.spongycastle.openpgp.PGPOnePassSignatureList;
-import org.spongycastle.openpgp.PGPPBEEncryptedData;
-import org.spongycastle.openpgp.PGPPrivateKey;
-import org.spongycastle.openpgp.PGPPublicKey;
-import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
-import org.spongycastle.openpgp.PGPPublicKeyRing;
-import org.spongycastle.openpgp.PGPSecretKey;
-import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.spongycastle.openpgp.PGPSignature;
-import org.spongycastle.openpgp.PGPSignatureList;
-import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
-import org.spongycastle.openpgp.PGPUtil;
-import org.spongycastle.openpgp.operator.PBEDataDecryptorFactory;
-import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
-import org.spongycastle.openpgp.operator.PGPDigestCalculatorProvider;
-import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
-import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
-import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
-import org.spongycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder;
-import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
-import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.service.PassphraseCacheService;
-import org.sufficientlysecure.keychain.util.InputData;
-import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.SignatureException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- * This class uses a Builder pattern!
- */
-public class PgpDecryptVerify {
- private Context mContext;
- private InputData mData;
- private OutputStream mOutStream;
-
- private ProgressDialogUpdater mProgressDialogUpdater;
- private boolean mAllowSymmetricDecryption;
- private String mPassphrase;
- private Set<Long> mAllowedKeyIds;
-
- private PgpDecryptVerify(Builder builder) {
- // private Constructor can only be called from Builder
- this.mContext = builder.mContext;
- this.mData = builder.mData;
- this.mOutStream = builder.mOutStream;
-
- this.mProgressDialogUpdater = builder.mProgressDialogUpdater;
- this.mAllowSymmetricDecryption = builder.mAllowSymmetricDecryption;
- this.mPassphrase = builder.mPassphrase;
- this.mAllowedKeyIds = builder.mAllowedKeyIds;
- }
-
- public static class Builder {
- // mandatory parameter
- private Context mContext;
- private InputData mData;
- private OutputStream mOutStream;
-
- // optional
- private ProgressDialogUpdater mProgressDialogUpdater = null;
- private boolean mAllowSymmetricDecryption = true;
- private String mPassphrase = null;
- private Set<Long> mAllowedKeyIds = null;
-
- public Builder(Context context, InputData data, OutputStream outStream) {
- this.mContext = context;
- this.mData = data;
- this.mOutStream = outStream;
- }
-
- public Builder progressDialogUpdater(ProgressDialogUpdater progressDialogUpdater) {
- this.mProgressDialogUpdater = progressDialogUpdater;
- return this;
- }
-
- public Builder allowSymmetricDecryption(boolean allowSymmetricDecryption) {
- this.mAllowSymmetricDecryption = allowSymmetricDecryption;
- return this;
- }
-
- public Builder passphrase(String passphrase) {
- this.mPassphrase = passphrase;
- return this;
- }
-
- /**
- * Allow these key ids alone for decryption.
- * This means only ciphertexts encrypted for one of these private key can be decrypted.
- *
- * @param allowedKeyIds
- * @return
- */
- public Builder allowedKeyIds(Set<Long> allowedKeyIds) {
- this.mAllowedKeyIds = allowedKeyIds;
- return this;
- }
-
- public PgpDecryptVerify build() {
- return new PgpDecryptVerify(this);
- }
- }
-
- public void updateProgress(int message, int current, int total) {
- if (mProgressDialogUpdater != null) {
- mProgressDialogUpdater.setProgress(message, current, total);
- }
- }
-
- public void updateProgress(int current, int total) {
- if (mProgressDialogUpdater != null) {
- mProgressDialogUpdater.setProgress(current, total);
- }
- }
-
- /**
- * Decrypts and/or verifies data based on parameters of class
- *
- * @return
- * @throws IOException
- * @throws PgpGeneralException
- * @throws PGPException
- * @throws SignatureException
- */
- public PgpDecryptVerifyResult execute()
- throws IOException, PgpGeneralException, PGPException, SignatureException {
- // automatically works with ascii armor input and binary
- InputStream in = PGPUtil.getDecoderStream(mData.getInputStream());
- if (in instanceof ArmoredInputStream) {
- ArmoredInputStream aIn = (ArmoredInputStream) in;
- // it is ascii armored
- Log.d(Constants.TAG, "ASCII Armor Header Line: " + aIn.getArmorHeaderLine());
-
- if (aIn.isClearText()) {
- // a cleartext signature, verify it with the other method
- return verifyCleartextSignature(aIn);
- }
- // else: ascii armored encryption! go on...
- }
-
- return decryptVerify(in);
- }
-
- /**
- * Decrypt and/or verifies binary or ascii armored pgp
- *
- * @param in
- * @return
- * @throws IOException
- * @throws PgpGeneralException
- * @throws PGPException
- * @throws SignatureException
- */
- private PgpDecryptVerifyResult decryptVerify(InputStream in)
- throws IOException, PgpGeneralException, PGPException, SignatureException {
- PgpDecryptVerifyResult returnData = new PgpDecryptVerifyResult();
-
- PGPObjectFactory pgpF = new PGPObjectFactory(in);
- PGPEncryptedDataList enc;
- Object o = pgpF.nextObject();
-
- int currentProgress = 0;
- updateProgress(R.string.progress_reading_data, currentProgress, 100);
-
- if (o instanceof PGPEncryptedDataList) {
- enc = (PGPEncryptedDataList) o;
- } else {
- enc = (PGPEncryptedDataList) pgpF.nextObject();
- }
-
- if (enc == null) {
- throw new PgpGeneralException(mContext.getString(R.string.error_invalid_data));
- }
-
- InputStream clear;
- PGPEncryptedData encryptedData;
-
- currentProgress += 5;
-
- PGPPublicKeyEncryptedData encryptedDataAsymmetric = null;
- PGPPBEEncryptedData encryptedDataSymmetric = null;
- PGPSecretKey secretKey = null;
- Iterator<?> it = enc.getEncryptedDataObjects();
- boolean symmetricPacketFound = false;
- // find secret key
- while (it.hasNext()) {
- Object obj = it.next();
- if (obj instanceof PGPPublicKeyEncryptedData) {
- updateProgress(R.string.progress_finding_key, currentProgress, 100);
-
- PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj;
- long masterKeyId = ProviderHelper.getMasterKeyId(mContext,
- KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(encData.getKeyID()))
- );
- PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRing(mContext, masterKeyId);
- if (secretKeyRing == null) {
- throw new PgpGeneralException(mContext.getString(R.string.error_no_secret_key_found));
- }
- secretKey = secretKeyRing.getSecretKey(encData.getKeyID());
- if (secretKey == null) {
- throw new PgpGeneralException(mContext.getString(R.string.error_no_secret_key_found));
- }
- // secret key exists in database
-
- // allow only a specific key for decryption?
- if (mAllowedKeyIds != null) {
- Log.d(Constants.TAG, "encData.getKeyID():" + encData.getKeyID());
- Log.d(Constants.TAG, "allowedKeyIds: " + mAllowedKeyIds);
- Log.d(Constants.TAG, "masterKeyId: " + masterKeyId);
-
- if (!mAllowedKeyIds.contains(masterKeyId)) {
- throw new PgpGeneralException(
- mContext.getString(R.string.error_no_secret_key_found));
- }
- }
-
- encryptedDataAsymmetric = encData;
-
- // if no passphrase was explicitly set try to get it from the cache service
- if (mPassphrase == null) {
- // returns "" if key has no passphrase
- mPassphrase =
- PassphraseCacheService.getCachedPassphrase(mContext, masterKeyId);
-
- // if passphrase was not cached, return here
- // indicating that a passphrase is missing!
- if (mPassphrase == null) {
- returnData.setKeyIdPassphraseNeeded(masterKeyId);
- returnData.setStatus(PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED);
- return returnData;
- }
- }
-
- // break out of while, only get first object here
- // TODO???: There could be more pgp objects, which are not decrypted!
- break;
- } else if (mAllowSymmetricDecryption && obj instanceof PGPPBEEncryptedData) {
- symmetricPacketFound = true;
-
- encryptedDataSymmetric = (PGPPBEEncryptedData) obj;
-
- // if no passphrase is given, return here
- // indicating that a passphrase is missing!
- if (mPassphrase == null) {
- returnData.setStatus(PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED);
- return returnData;
- }
-
- // break out of while, only get first object here
- // TODO???: There could be more pgp objects, which are not decrypted!
- break;
- }
- }
-
- if (symmetricPacketFound) {
- updateProgress(R.string.progress_preparing_streams, currentProgress, 100);
-
- PGPDigestCalculatorProvider digestCalcProvider = new JcaPGPDigestCalculatorProviderBuilder()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build();
- PBEDataDecryptorFactory decryptorFactory = new JcePBEDataDecryptorFactoryBuilder(
- digestCalcProvider).setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
- mPassphrase.toCharArray());
-
- clear = encryptedDataSymmetric.getDataStream(decryptorFactory);
-
- encryptedData = encryptedDataSymmetric;
- currentProgress += 5;
- } else {
- if (secretKey == null) {
- throw new PgpGeneralException(mContext.getString(R.string.error_no_secret_key_found));
- }
-
- currentProgress += 5;
- updateProgress(R.string.progress_extracting_key, currentProgress, 100);
- PGPPrivateKey privateKey;
- try {
- PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
- mPassphrase.toCharArray());
- privateKey = secretKey.extractPrivateKey(keyDecryptor);
- } catch (PGPException e) {
- throw new PGPException(mContext.getString(R.string.error_wrong_passphrase));
- }
- if (privateKey == null) {
- throw new PgpGeneralException(
- mContext.getString(R.string.error_could_not_extract_private_key));
- }
- currentProgress += 5;
- updateProgress(R.string.progress_preparing_streams, currentProgress, 100);
-
- PublicKeyDataDecryptorFactory decryptorFactory = new JcePublicKeyDataDecryptorFactoryBuilder()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(privateKey);
-
- clear = encryptedDataAsymmetric.getDataStream(decryptorFactory);
-
- encryptedData = encryptedDataAsymmetric;
- currentProgress += 5;
- }
-
- PGPObjectFactory plainFact = new PGPObjectFactory(clear);
- Object dataChunk = plainFact.nextObject();
- PGPOnePassSignature signature = null;
- OpenPgpSignatureResult signatureResult = null;
- PGPPublicKey signatureKey = null;
- int signatureIndex = -1;
-
- if (dataChunk instanceof PGPCompressedData) {
- updateProgress(R.string.progress_decompressing_data, currentProgress, 100);
-
- PGPObjectFactory fact = new PGPObjectFactory(
- ((PGPCompressedData) dataChunk).getDataStream());
- dataChunk = fact.nextObject();
- plainFact = fact;
- currentProgress += 10;
- }
-
- long signatureKeyId = 0;
- if (dataChunk instanceof PGPOnePassSignatureList) {
- updateProgress(R.string.progress_processing_signature, currentProgress, 100);
-
- signatureResult = new OpenPgpSignatureResult();
- PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk;
- for (int i = 0; i < sigList.size(); ++i) {
- signature = sigList.get(i);
- signatureKey = ProviderHelper
- .getPGPPublicKeyRing(mContext, signature.getKeyID()).getPublicKey();
- if (signatureKeyId == 0) {
- signatureKeyId = signature.getKeyID();
- }
- if (signatureKey == null) {
- signature = null;
- } else {
- signatureIndex = i;
- signatureKeyId = signature.getKeyID();
- String userId = null;
- PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingWithKeyId(
- mContext, signatureKeyId);
- if (signKeyRing != null) {
- userId = PgpKeyHelper.getMainUserId(signKeyRing.getPublicKey());
- }
- signatureResult.setUserId(userId);
- break;
- }
- }
-
- signatureResult.setKeyId(signatureKeyId);
-
- if (signature != null) {
- JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
- new JcaPGPContentVerifierBuilderProvider()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
-
- signature.init(contentVerifierBuilderProvider, signatureKey);
- } else {
- signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY);
- }
-
- dataChunk = plainFact.nextObject();
- currentProgress += 10;
- }
-
- if (dataChunk instanceof PGPSignatureList) {
- dataChunk = plainFact.nextObject();
- }
-
- if (dataChunk instanceof PGPLiteralData) {
- updateProgress(R.string.progress_decrypting, currentProgress, 100);
-
- PGPLiteralData literalData = (PGPLiteralData) dataChunk;
-
- byte[] buffer = new byte[1 << 16];
- InputStream dataIn = literalData.getInputStream();
-
- int startProgress = currentProgress;
- int endProgress = 100;
- if (signature != null) {
- endProgress = 90;
- } else if (encryptedData.isIntegrityProtected()) {
- endProgress = 95;
- }
-
- int n;
- // TODO: progress calculation is broken here! Try to rework it based on commented code!
-// int progress = 0;
- long startPos = mData.getStreamPosition();
- while ((n = dataIn.read(buffer)) > 0) {
- mOutStream.write(buffer, 0, n);
-// progress += n;
- if (signature != null) {
- try {
- signature.update(buffer, 0, n);
- } catch (SignatureException e) {
- signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_ERROR);
- signature = null;
- }
- }
- // TODO: dead code?!
- // unknown size, but try to at least have a moving, slowing down progress bar
-// currentProgress = startProgress + (endProgress - startProgress) * progress
-// / (progress + 100000);
- if (mData.getSize() - startPos == 0) {
- currentProgress = endProgress;
- } else {
- currentProgress = (int) (startProgress + (endProgress - startProgress)
- * (mData.getStreamPosition() - startPos) / (mData.getSize() - startPos));
- }
- updateProgress(currentProgress, 100);
- }
-
- if (signature != null) {
- updateProgress(R.string.progress_verifying_signature, 90, 100);
-
- PGPSignatureList signatureList = (PGPSignatureList) plainFact.nextObject();
- PGPSignature messageSignature = signatureList.get(signatureIndex);
-
- // these are not cleartext signatures!
- // TODO: what about binary signatures?
- signatureResult.setSignatureOnly(false);
-
- //Now check binding signatures
- boolean validKeyBinding = verifyKeyBinding(mContext, messageSignature, signatureKey);
- boolean validSignature = signature.verify(messageSignature);
-
- // TODO: implement CERTIFIED!
- if (validKeyBinding & validSignature) {
- signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED);
- }
- }
- }
-
- if (encryptedData.isIntegrityProtected()) {
- updateProgress(R.string.progress_verifying_integrity, 95, 100);
-
- if (encryptedData.verify()) {
- // passed
- Log.d(Constants.TAG, "Integrity verification: success!");
- } else {
- // failed
- Log.d(Constants.TAG, "Integrity verification: failed!");
- throw new PgpGeneralException(mContext.getString(R.string.error_integrity_check_failed));
- }
- } else {
- // no integrity check
- Log.e(Constants.TAG, "Encrypted data was not integrity protected!");
- // TODO: inform user?
- }
-
- updateProgress(R.string.progress_done, 100, 100);
-
- returnData.setSignatureResult(signatureResult);
- return returnData;
- }
-
- /**
- * This method verifies cleartext signatures
- * as defined in http://tools.ietf.org/html/rfc4880#section-7
- * <p/>
- * The method is heavily based on
- * pg/src/main/java/org/spongycastle/openpgp/examples/ClearSignedFileProcessor.java
- *
- * @return
- * @throws IOException
- * @throws PgpGeneralException
- * @throws PGPException
- * @throws SignatureException
- */
- private PgpDecryptVerifyResult verifyCleartextSignature(ArmoredInputStream aIn)
- throws IOException, PgpGeneralException, PGPException, SignatureException {
- PgpDecryptVerifyResult returnData = new PgpDecryptVerifyResult();
- OpenPgpSignatureResult signatureResult = new OpenPgpSignatureResult();
- // cleartext signatures are never encrypted ;)
- signatureResult.setSignatureOnly(true);
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- updateProgress(R.string.progress_done, 0, 100);
-
- ByteArrayOutputStream lineOut = new ByteArrayOutputStream();
- int lookAhead = readInputLine(lineOut, aIn);
- byte[] lineSep = getLineSeparator();
-
- byte[] line = lineOut.toByteArray();
- out.write(line, 0, getLengthWithoutSeparator(line));
- out.write(lineSep);
-
- while (lookAhead != -1 && aIn.isClearText()) {
- lookAhead = readInputLine(lineOut, lookAhead, aIn);
- line = lineOut.toByteArray();
- out.write(line, 0, getLengthWithoutSeparator(line));
- out.write(lineSep);
- }
-
- out.close();
-
- byte[] clearText = out.toByteArray();
- mOutStream.write(clearText);
-
- updateProgress(R.string.progress_processing_signature, 60, 100);
- PGPObjectFactory pgpFact = new PGPObjectFactory(aIn);
-
- PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject();
- if (sigList == null) {
- throw new PgpGeneralException(mContext.getString(R.string.error_corrupt_data));
- }
- PGPSignature signature = null;
- long signatureKeyId = 0;
- PGPPublicKey signatureKey = null;
- for (int i = 0; i < sigList.size(); ++i) {
-
- signature = sigList.get(i);
- signatureKeyId = signature.getKeyID();
-
- // find data about this subkey
- HashMap<String, Object> data = ProviderHelper.getGenericData(mContext,
- KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(signature.getKeyID())),
- new String[] { KeyRings.MASTER_KEY_ID, KeyRings.USER_ID },
- new int[] { ProviderHelper.FIELD_TYPE_INTEGER, ProviderHelper.FIELD_TYPE_STRING });
- // any luck? otherwise, try next.
- if(data.get(KeyRings.MASTER_KEY_ID) == null) {
- signature = null;
- // do NOT reset signatureKeyId, that one is shown when no known one is found!
- continue;
- }
-
- // this one can't fail now (yay database constraints)
- signatureKey = ProviderHelper.getPGPPublicKeyRing(mContext, (Long) data.get(KeyRings.MASTER_KEY_ID)).getPublicKey();
- signatureResult.setUserId((String) data.get(KeyRings.USER_ID));
-
- break;
- }
-
- signatureResult.setKeyId(signatureKeyId);
-
- if (signature == null) {
- signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY);
- returnData.setSignatureResult(signatureResult);
-
- updateProgress(R.string.progress_done, 100, 100);
- return returnData;
- }
-
- JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
- new JcaPGPContentVerifierBuilderProvider()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
-
- signature.init(contentVerifierBuilderProvider, signatureKey);
-
- InputStream sigIn = new BufferedInputStream(new ByteArrayInputStream(clearText));
-
- lookAhead = readInputLine(lineOut, sigIn);
-
- processLine(signature, lineOut.toByteArray());
-
- if (lookAhead != -1) {
- do {
- lookAhead = readInputLine(lineOut, lookAhead, sigIn);
-
- signature.update((byte) '\r');
- signature.update((byte) '\n');
-
- processLine(signature, lineOut.toByteArray());
- } while (lookAhead != -1);
- }
-
- //Now check binding signatures
- boolean validKeyBinding = verifyKeyBinding(mContext, signature, signatureKey);
- boolean validSignature = signature.verify();
-
- if (validSignature & validKeyBinding) {
- signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED);
- }
-
- // TODO: what about SIGNATURE_SUCCESS_CERTIFIED and SIGNATURE_ERROR????
-
- returnData.setSignatureResult(signatureResult);
-
- updateProgress(R.string.progress_done, 100, 100);
- return returnData;
- }
-
- private static boolean verifyKeyBinding(Context context,
- PGPSignature signature, PGPPublicKey signatureKey) {
- long signatureKeyId = signature.getKeyID();
- boolean validKeyBinding = false;
-
- PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingWithKeyId(context,
- signatureKeyId);
- PGPPublicKey mKey = null;
- if (signKeyRing != null) {
- mKey = signKeyRing.getPublicKey();
- }
-
- if (signature.getKeyID() != mKey.getKeyID()) {
- validKeyBinding = verifyKeyBinding(mKey, signatureKey);
- } else { //if the key used to make the signature was the master key, no need to check binding sigs
- validKeyBinding = true;
- }
- return validKeyBinding;
- }
-
- private static boolean verifyKeyBinding(PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) {
- boolean validSubkeyBinding = false;
- boolean validTempSubkeyBinding = false;
- boolean validPrimaryKeyBinding = false;
-
- JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
- new JcaPGPContentVerifierBuilderProvider()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
-
- Iterator<PGPSignature> itr = signingPublicKey.getSignatures();
-
- while (itr.hasNext()) { //what does gpg do if the subkey binding is wrong?
- //gpg has an invalid subkey binding error on key import I think, but doesn't shout
- //about keys without subkey signing. Can't get it to import a slightly broken one
- //either, so we will err on bad subkey binding here.
- PGPSignature sig = itr.next();
- if (sig.getKeyID() == masterPublicKey.getKeyID() &&
- sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) {
- //check and if ok, check primary key binding.
- try {
- sig.init(contentVerifierBuilderProvider, masterPublicKey);
- validTempSubkeyBinding = sig.verifyCertification(masterPublicKey, signingPublicKey);
- } catch (PGPException e) {
- continue;
- } catch (SignatureException e) {
- continue;
- }
-
- if (validTempSubkeyBinding) {
- validSubkeyBinding = true;
- }
- if (validTempSubkeyBinding) {
- validPrimaryKeyBinding = verifyPrimaryKeyBinding(sig.getUnhashedSubPackets(),
- masterPublicKey, signingPublicKey);
- if (validPrimaryKeyBinding) {
- break;
- }
- validPrimaryKeyBinding = verifyPrimaryKeyBinding(sig.getHashedSubPackets(),
- masterPublicKey, signingPublicKey);
- if (validPrimaryKeyBinding) {
- break;
- }
- }
- }
- }
- return (validSubkeyBinding & validPrimaryKeyBinding);
- }
-
- private static boolean verifyPrimaryKeyBinding(PGPSignatureSubpacketVector pkts,
- PGPPublicKey masterPublicKey,
- PGPPublicKey signingPublicKey) {
- boolean validPrimaryKeyBinding = false;
- JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
- new JcaPGPContentVerifierBuilderProvider()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
- PGPSignatureList eSigList;
-
- if (pkts.hasSubpacket(SignatureSubpacketTags.EMBEDDED_SIGNATURE)) {
- try {
- eSigList = pkts.getEmbeddedSignatures();
- } catch (IOException e) {
- return false;
- } catch (PGPException e) {
- return false;
- }
- for (int j = 0; j < eSigList.size(); ++j) {
- PGPSignature emSig = eSigList.get(j);
- if (emSig.getSignatureType() == PGPSignature.PRIMARYKEY_BINDING) {
- try {
- emSig.init(contentVerifierBuilderProvider, signingPublicKey);
- validPrimaryKeyBinding = emSig.verifyCertification(masterPublicKey, signingPublicKey);
- if (validPrimaryKeyBinding) {
- break;
- }
- } catch (PGPException e) {
- continue;
- } catch (SignatureException e) {
- continue;
- }
- }
- }
- }
-
- return validPrimaryKeyBinding;
- }
-
- /**
- * Mostly taken from ClearSignedFileProcessor in Bouncy Castle
- *
- * @param sig
- * @param line
- * @throws SignatureException
- */
- 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 = readPassedEOL(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 = readPassedEOL(bOut, ch, fIn);
- break;
- }
- } while ((ch = fIn.read()) >= 0);
-
- if (ch < 0) {
- lookAhead = -1;
- }
-
- return lookAhead;
- }
-
- private static int readPassedEOL(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 getLengthWithoutSeparator(byte[] line) {
- int end = line.length - 1;
-
- while (end >= 0 && isLineEnding(line[end])) {
- end--;
- }
-
- return end + 1;
- }
-
- private static boolean isLineEnding(byte b) {
- return b == '\r' || b == '\n';
- }
-
- 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 == ' ';
- }
-
- private static byte[] getLineSeparator() {
- String nl = System.getProperty("line.separator");
- byte[] nlBytes = new byte[nl.length()];
-
- for (int i = 0; i != nlBytes.length; i++) {
- nlBytes[i] = (byte) nl.charAt(i);
- }
-
- return nlBytes;
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java
deleted file mode 100644
index ad240e834..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.pgp;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import org.openintents.openpgp.OpenPgpSignatureResult;
-
-public class PgpDecryptVerifyResult implements Parcelable {
- public static final int SUCCESS = 1;
- public static final int KEY_PASSHRASE_NEEDED = 2;
- public static final int SYMMETRIC_PASSHRASE_NEEDED = 3;
-
- int mStatus;
- long mKeyIdPassphraseNeeded;
-
- OpenPgpSignatureResult mSignatureResult;
-
- public int getStatus() {
- return mStatus;
- }
-
- public void setStatus(int mStatus) {
- this.mStatus = mStatus;
- }
-
- public long getKeyIdPassphraseNeeded() {
- return mKeyIdPassphraseNeeded;
- }
-
- public void setKeyIdPassphraseNeeded(long mKeyIdPassphraseNeeded) {
- this.mKeyIdPassphraseNeeded = mKeyIdPassphraseNeeded;
- }
-
- public OpenPgpSignatureResult getSignatureResult() {
- return mSignatureResult;
- }
-
- public void setSignatureResult(OpenPgpSignatureResult signatureResult) {
- this.mSignatureResult = signatureResult;
- }
-
- public PgpDecryptVerifyResult() {
-
- }
-
- public PgpDecryptVerifyResult(PgpDecryptVerifyResult b) {
- this.mStatus = b.mStatus;
- this.mKeyIdPassphraseNeeded = b.mKeyIdPassphraseNeeded;
- this.mSignatureResult = b.mSignatureResult;
- }
-
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mStatus);
- dest.writeLong(mKeyIdPassphraseNeeded);
- dest.writeParcelable(mSignatureResult, 0);
- }
-
- public static final Creator<PgpDecryptVerifyResult> CREATOR = new Creator<PgpDecryptVerifyResult>() {
- public PgpDecryptVerifyResult createFromParcel(final Parcel source) {
- PgpDecryptVerifyResult vr = new PgpDecryptVerifyResult();
- vr.mStatus = source.readInt();
- vr.mKeyIdPassphraseNeeded = source.readLong();
- vr.mSignatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader());
- return vr;
- }
-
- public PgpDecryptVerifyResult[] newArray(final int size) {
- return new PgpDecryptVerifyResult[size];
- }
- };
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java
deleted file mode 100644
index f884b1776..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.pgp;
-
-import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-
-import org.spongycastle.openpgp.PGPEncryptedDataList;
-import org.spongycastle.openpgp.PGPObjectFactory;
-import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
-import org.spongycastle.openpgp.PGPPublicKeyRing;
-import org.spongycastle.openpgp.PGPSecretKey;
-import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.spongycastle.openpgp.PGPUtil;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.exception.NoAsymmetricEncryptionException;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.RandomAccessFile;
-import java.security.SecureRandom;
-import java.util.Iterator;
-import java.util.regex.Pattern;
-
-public class PgpHelper {
-
- public static final Pattern PGP_MESSAGE = Pattern.compile(
- ".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", Pattern.DOTALL);
-
- public static final Pattern PGP_CLEARTEXT_SIGNATURE = Pattern
- .compile(".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----" +
- "BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*",
- Pattern.DOTALL);
-
- public static final Pattern PGP_PUBLIC_KEY = Pattern.compile(
- ".*?(-----BEGIN PGP PUBLIC KEY BLOCK-----.*?-----END PGP PUBLIC KEY BLOCK-----).*",
- Pattern.DOTALL);
-
- public static String getVersion(Context context) {
- String version = null;
- try {
- PackageInfo pi = context.getPackageManager().getPackageInfo(Constants.PACKAGE_NAME, 0);
- version = pi.versionName;
- return version;
- } catch (NameNotFoundException e) {
- Log.e(Constants.TAG, "Version could not be retrieved!", e);
- return "0.0.0";
- }
- }
-
- public static String getFullVersion(Context context) {
- return "OpenPGP Keychain v" + getVersion(context);
- }
-
- public static long getDecryptionKeyId(Context context, InputStream inputStream)
- throws PgpGeneralException, NoAsymmetricEncryptionException, IOException {
- InputStream in = PGPUtil.getDecoderStream(inputStream);
- PGPObjectFactory pgpF = new PGPObjectFactory(in);
- PGPEncryptedDataList enc;
- Object o = pgpF.nextObject();
-
- // the first object might be a PGP marker packet.
- if (o instanceof PGPEncryptedDataList) {
- enc = (PGPEncryptedDataList) o;
- } else {
- enc = (PGPEncryptedDataList) pgpF.nextObject();
- }
-
- if (enc == null) {
- throw new PgpGeneralException(context.getString(R.string.error_invalid_data));
- }
-
- // TODO: currently we always only look at the first known key
- // find the secret key
- PGPSecretKey secretKey = null;
- Iterator<?> it = enc.getEncryptedDataObjects();
- boolean gotAsymmetricEncryption = false;
- while (it.hasNext()) {
- Object obj = it.next();
- if (obj instanceof PGPPublicKeyEncryptedData) {
- gotAsymmetricEncryption = true;
- PGPPublicKeyEncryptedData pbe = (PGPPublicKeyEncryptedData) obj;
- secretKey = ProviderHelper.getPGPSecretKeyRing(context, pbe.getKeyID()).getSecretKey();
- if (secretKey != null) {
- break;
- }
- }
- }
-
- if (!gotAsymmetricEncryption) {
- throw new NoAsymmetricEncryptionException();
- }
-
- if (secretKey == null) {
- return Id.key.none;
- }
-
- return secretKey.getKeyID();
- }
-
- public static int getStreamContent(Context context, InputStream inStream) throws IOException {
- InputStream in = PGPUtil.getDecoderStream(inStream);
- PGPObjectFactory pgpF = new PGPObjectFactory(in);
- Object object = pgpF.nextObject();
- while (object != null) {
- if (object instanceof PGPPublicKeyRing || object instanceof PGPSecretKeyRing) {
- return Id.content.keys;
- } else if (object instanceof PGPEncryptedDataList) {
- return Id.content.encrypted_data;
- }
- object = pgpF.nextObject();
- }
-
- return Id.content.unknown;
- }
-
- /**
- * Generate a random filename
- *
- * @param length
- * @return
- */
- public static String generateRandomFilename(int length) {
- SecureRandom random = new SecureRandom();
-
- byte bytes[] = new byte[length];
- random.nextBytes(bytes);
- String result = "";
- for (int i = 0; i < length; ++i) {
- int v = (bytes[i] + 256) % 64;
- if (v < 10) {
- result += (char) ('0' + v);
- } else if (v < 36) {
- result += (char) ('A' + v - 10);
- } else if (v < 62) {
- result += (char) ('a' + v - 36);
- } else if (v == 62) {
- result += '_';
- } else if (v == 63) {
- result += '.';
- }
- }
- return result;
- }
-
- /**
- * Go once through stream to get length of stream. The length is later used to display progress
- * when encrypting/decrypting
- *
- * @param in
- * @return
- * @throws IOException
- */
- public static long getLengthOfStream(InputStream in) throws IOException {
- long size = 0;
- long n = 0;
- byte dummy[] = new byte[0x10000];
- while ((n = in.read(dummy)) > 0) {
- size += n;
- }
- return size;
- }
-
- /**
- * Deletes file securely by overwriting it with random data before deleting it.
- * <p/>
- * TODO: Does this really help on flash storage?
- *
- * @param context
- * @param progress
- * @param file
- * @throws IOException
- */
- public static void deleteFileSecurely(Context context, ProgressDialogUpdater progress, File file)
- throws IOException {
- long length = file.length();
- SecureRandom random = new SecureRandom();
- RandomAccessFile raf = new RandomAccessFile(file, "rws");
- raf.seek(0);
- raf.getFilePointer();
- byte[] data = new byte[1 << 16];
- int pos = 0;
- String msg = context.getString(R.string.progress_deleting_securely, file.getName());
- while (pos < length) {
- if (progress != null) {
- progress.setProgress(msg, (int) (100 * pos / length), 100);
- }
- random.nextBytes(data);
- raf.write(data);
- pos += data.length;
- }
- raf.close();
- file.delete();
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
deleted file mode 100644
index d03f3ccc2..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.pgp;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.os.Environment;
-
-import org.spongycastle.bcpg.ArmoredOutputStream;
-import org.spongycastle.openpgp.PGPException;
-import org.spongycastle.openpgp.PGPKeyRing;
-import org.spongycastle.openpgp.PGPPublicKey;
-import org.spongycastle.openpgp.PGPPublicKeyRing;
-import org.spongycastle.openpgp.PGPSecretKey;
-import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
-import org.sufficientlysecure.keychain.util.HkpKeyServer;
-import org.sufficientlysecure.keychain.util.IterableIterator;
-import org.sufficientlysecure.keychain.util.KeyServer.AddKeyException;
-import org.sufficientlysecure.keychain.util.KeychainServiceListener;
-import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-public class PgpImportExport {
-
- private Context mContext;
- private ProgressDialogUpdater mProgress;
-
- private KeychainServiceListener mKeychainServiceListener;
-
- public PgpImportExport(Context context, ProgressDialogUpdater progress) {
- super();
- this.mContext = context;
- this.mProgress = progress;
- }
-
- public PgpImportExport(Context context,
- ProgressDialogUpdater progress, KeychainServiceListener keychainListener) {
- super();
- this.mContext = context;
- this.mProgress = progress;
- this.mKeychainServiceListener = keychainListener;
- }
-
- public void updateProgress(int message, int current, int total) {
- if (mProgress != null) {
- mProgress.setProgress(message, current, total);
- }
- }
-
- public void updateProgress(String message, int current, int total) {
- if (mProgress != null) {
- mProgress.setProgress(message, current, total);
- }
- }
-
- public void updateProgress(int current, int total) {
- if (mProgress != null) {
- mProgress.setProgress(current, total);
- }
- }
-
- public boolean uploadKeyRingToServer(HkpKeyServer server, PGPPublicKeyRing keyring) {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- ArmoredOutputStream aos = null;
- try {
- aos = new ArmoredOutputStream(bos);
- aos.write(keyring.getEncoded());
- aos.close();
-
- String armoredKey = bos.toString("UTF-8");
- server.add(armoredKey);
-
- return true;
- } catch (IOException e) {
- return false;
- } catch (AddKeyException e) {
- // TODO: tell the user?
- return false;
- } finally {
- try {
- if (aos != null) { aos.close(); }
- if (bos != null) { bos.close(); }
- } catch (IOException e) {
- }
- }
- }
-
- /**
- * Imports keys from given data. If keyIds is given only those are imported
- */
- public Bundle importKeyRings(List<ImportKeysListEntry> entries)
- throws PgpGeneralException, PGPException, IOException {
- Bundle returnData = new Bundle();
-
- updateProgress(R.string.progress_importing, 0, 100);
-
- int newKeys = 0;
- int oldKeys = 0;
- int badKeys = 0;
-
- int position = 0;
- try {
- for (ImportKeysListEntry entry : entries) {
- Object obj = PgpConversionHelper.BytesToPGPKeyRing(entry.getBytes());
-
- if (obj instanceof PGPKeyRing) {
- PGPKeyRing keyring = (PGPKeyRing) obj;
-
- int status = storeKeyRingInCache(keyring);
-
- if (status == Id.return_value.error) {
- throw new PgpGeneralException(
- mContext.getString(R.string.error_saving_keys));
- }
-
- // update the counts to display to the user at the end
- if (status == Id.return_value.updated) {
- ++oldKeys;
- } else if (status == Id.return_value.ok) {
- ++newKeys;
- } else if (status == Id.return_value.bad) {
- ++badKeys;
- }
- } else {
- Log.e(Constants.TAG, "Object not recognized as PGPKeyRing!");
- }
-
- position++;
- updateProgress(position / entries.size() * 100, 100);
- }
- } catch (Exception e) {
- Log.e(Constants.TAG, "Exception on parsing key file!", e);
- }
-
- returnData.putInt(KeychainIntentService.RESULT_IMPORT_ADDED, newKeys);
- returnData.putInt(KeychainIntentService.RESULT_IMPORT_UPDATED, oldKeys);
- returnData.putInt(KeychainIntentService.RESULT_IMPORT_BAD, badKeys);
-
- return returnData;
- }
-
- public Bundle exportKeyRings(ArrayList<Long> publicKeyRingMasterIds,
- ArrayList<Long> secretKeyRingMasterIds,
- OutputStream outStream) throws PgpGeneralException,
- PGPException, IOException {
- Bundle returnData = new Bundle();
-
- int masterKeyIdsSize = publicKeyRingMasterIds.size() + secretKeyRingMasterIds.size();
- int progress = 0;
-
- updateProgress(
- mContext.getResources().getQuantityString(R.plurals.progress_exporting_key,
- masterKeyIdsSize), 0, 100);
-
- if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- throw new PgpGeneralException(
- mContext.getString(R.string.error_external_storage_not_ready));
- }
- // For each public masterKey id
- for (long pubKeyMasterId : publicKeyRingMasterIds) {
- progress++;
- // Create an output stream
- ArmoredOutputStream arOutStream = new ArmoredOutputStream(outStream);
- arOutStream.setHeader("Version", PgpHelper.getFullVersion(mContext));
-
- updateProgress(progress * 100 / masterKeyIdsSize, 100);
- PGPPublicKeyRing publicKeyRing =
- ProviderHelper.getPGPPublicKeyRing(mContext, pubKeyMasterId);
-
- if (publicKeyRing != null) {
- publicKeyRing.encode(arOutStream);
- }
-
- if (mKeychainServiceListener.hasServiceStopped()) {
- arOutStream.close();
- return null;
- }
-
- arOutStream.close();
- }
-
- // For each secret masterKey id
- for (long secretKeyMasterId : secretKeyRingMasterIds) {
- progress++;
- // Create an output stream
- ArmoredOutputStream arOutStream = new ArmoredOutputStream(outStream);
- arOutStream.setHeader("Version", PgpHelper.getFullVersion(mContext));
-
- updateProgress(progress * 100 / masterKeyIdsSize, 100);
- PGPSecretKeyRing secretKeyRing =
- ProviderHelper.getPGPSecretKeyRing(mContext, secretKeyMasterId);
-
- if (secretKeyRing != null) {
- secretKeyRing.encode(arOutStream);
- }
- if (mKeychainServiceListener.hasServiceStopped()) {
- arOutStream.close();
- return null;
- }
-
- arOutStream.close();
- }
-
- returnData.putInt(KeychainIntentService.RESULT_EXPORT, masterKeyIdsSize);
-
- updateProgress(R.string.progress_done, 100, 100);
-
- return returnData;
- }
-
- /**
- * TODO: implement Id.return_value.updated as status when key already existed
- */
- @SuppressWarnings("unchecked")
- public int storeKeyRingInCache(PGPKeyRing keyring) {
- int status = Integer.MIN_VALUE; // out of bounds value (Id.return_value.*)
- try {
- if (keyring instanceof PGPSecretKeyRing) {
- PGPSecretKeyRing secretKeyRing = (PGPSecretKeyRing) keyring;
- boolean save = true;
-
- for (PGPSecretKey testSecretKey : new IterableIterator<PGPSecretKey>(
- secretKeyRing.getSecretKeys())) {
- if (!testSecretKey.isMasterKey()) {
- if (testSecretKey.isPrivateKeyEmpty()) {
- // this is bad, something is very wrong...
- save = false;
- status = Id.return_value.bad;
- }
- }
- }
-
- if (save) {
- // TODO: preserve certifications
- // (http://osdir.com/ml/encryption.bouncy-castle.devel/2007-01/msg00054.html ?)
- PGPPublicKeyRing newPubRing = null;
- for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(
- secretKeyRing.getPublicKeys())) {
- if (newPubRing == null) {
- newPubRing = new PGPPublicKeyRing(key.getEncoded(),
- new JcaKeyFingerprintCalculator());
- }
- newPubRing = PGPPublicKeyRing.insertPublicKey(newPubRing, key);
- }
- if (newPubRing != null) {
- ProviderHelper.saveKeyRing(mContext, newPubRing);
- }
- ProviderHelper.saveKeyRing(mContext, secretKeyRing);
- // TODO: remove status returns, use exceptions!
- status = Id.return_value.ok;
- }
- } else if (keyring instanceof PGPPublicKeyRing) {
- PGPPublicKeyRing publicKeyRing = (PGPPublicKeyRing) keyring;
- ProviderHelper.saveKeyRing(mContext, publicKeyRing);
- // TODO: remove status returns, use exceptions!
- status = Id.return_value.ok;
- }
- } catch (IOException e) {
- status = Id.return_value.error;
- }
-
- return status;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java
deleted file mode 100644
index 4c786f555..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java
+++ /dev/null
@@ -1,644 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.pgp;
-
-import android.content.Context;
-import android.graphics.Color;
-import android.text.Spannable;
-import android.text.SpannableStringBuilder;
-import android.text.style.ForegroundColorSpan;
-
-import org.spongycastle.bcpg.sig.KeyFlags;
-import org.spongycastle.openpgp.PGPPublicKey;
-import org.spongycastle.openpgp.PGPPublicKeyRing;
-import org.spongycastle.openpgp.PGPSecretKey;
-import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.spongycastle.openpgp.PGPSignature;
-import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
-import org.spongycastle.util.encoders.Hex;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.util.IterableIterator;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.security.DigestException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.Locale;
-import java.util.Vector;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class PgpKeyHelper {
-
- private static final Pattern USER_ID_PATTERN = Pattern.compile("^(.*?)(?: \\((.*)\\))?(?: <(.*)>)?$");
-
- public static Date getCreationDate(PGPPublicKey key) {
- return key.getCreationTime();
- }
-
- public static Date getCreationDate(PGPSecretKey key) {
- return key.getPublicKey().getCreationTime();
- }
-
- @SuppressWarnings("unchecked")
- public static PGPSecretKey getKeyNum(PGPSecretKeyRing keyRing, long num) {
- long cnt = 0;
- if (keyRing == null) {
- return null;
- }
- for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(keyRing.getSecretKeys())) {
- if (cnt == num) {
- return key;
- }
- cnt++;
- }
-
- return null;
- }
-
- @SuppressWarnings("unchecked")
- public static Vector<PGPPublicKey> getEncryptKeys(PGPPublicKeyRing keyRing) {
- Vector<PGPPublicKey> encryptKeys = new Vector<PGPPublicKey>();
-
- for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(keyRing.getPublicKeys())) {
- if (isEncryptionKey(key)) {
- encryptKeys.add(key);
- }
- }
-
- return encryptKeys;
- }
-
- @SuppressWarnings("unchecked")
- public static Vector<PGPSecretKey> getSigningKeys(PGPSecretKeyRing keyRing) {
- Vector<PGPSecretKey> signingKeys = new Vector<PGPSecretKey>();
-
- for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(keyRing.getSecretKeys())) {
- if (isSigningKey(key)) {
- signingKeys.add(key);
- }
- }
-
- return signingKeys;
- }
-
- @SuppressWarnings("unchecked")
- public static Vector<PGPSecretKey> getCertificationKeys(PGPSecretKeyRing keyRing) {
- Vector<PGPSecretKey> signingKeys = new Vector<PGPSecretKey>();
-
- for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(keyRing.getSecretKeys())) {
- if (isCertificationKey(key)) {
- signingKeys.add(key);
- }
- }
-
- return signingKeys;
- }
-
- public static Vector<PGPPublicKey> getUsableEncryptKeys(PGPPublicKeyRing keyRing) {
- Vector<PGPPublicKey> usableKeys = new Vector<PGPPublicKey>();
- Vector<PGPPublicKey> encryptKeys = getEncryptKeys(keyRing);
- PGPPublicKey masterKey = null;
- for (int i = 0; i < encryptKeys.size(); ++i) {
- PGPPublicKey key = encryptKeys.get(i);
- if (!isExpired(key) && !key.isRevoked()) {
- if (key.isMasterKey()) {
- masterKey = key;
- } else {
- usableKeys.add(key);
- }
- }
- }
- if (masterKey != null) {
- usableKeys.add(masterKey);
- }
- return usableKeys;
- }
-
- public static boolean isExpired(PGPPublicKey key) {
- Date creationDate = getCreationDate(key);
- Date expiryDate = getExpiryDate(key);
- Date now = new Date();
- if (now.compareTo(creationDate) >= 0
- && (expiryDate == null || now.compareTo(expiryDate) <= 0)) {
- return false;
- }
- return true;
- }
-
- public static Vector<PGPSecretKey> getUsableCertificationKeys(PGPSecretKeyRing keyRing) {
- Vector<PGPSecretKey> usableKeys = new Vector<PGPSecretKey>();
- Vector<PGPSecretKey> signingKeys = getCertificationKeys(keyRing);
- PGPSecretKey masterKey = null;
- for (int i = 0; i < signingKeys.size(); ++i) {
- PGPSecretKey key = signingKeys.get(i);
- if (key.isMasterKey()) {
- masterKey = key;
- } else {
- usableKeys.add(key);
- }
- }
- if (masterKey != null) {
- usableKeys.add(masterKey);
- }
- return usableKeys;
- }
-
- public static Vector<PGPSecretKey> getUsableSigningKeys(PGPSecretKeyRing keyRing) {
- Vector<PGPSecretKey> usableKeys = new Vector<PGPSecretKey>();
- Vector<PGPSecretKey> signingKeys = getSigningKeys(keyRing);
- PGPSecretKey masterKey = null;
- for (int i = 0; i < signingKeys.size(); ++i) {
- PGPSecretKey key = signingKeys.get(i);
- if (key.isMasterKey()) {
- masterKey = key;
- } else {
- usableKeys.add(key);
- }
- }
- if (masterKey != null) {
- usableKeys.add(masterKey);
- }
- return usableKeys;
- }
-
- public static Date getExpiryDate(PGPPublicKey key) {
- Date creationDate = getCreationDate(key);
- if (key.getValidDays() == 0) {
- // no expiry
- return null;
- }
- Calendar calendar = GregorianCalendar.getInstance();
- calendar.setTime(creationDate);
- calendar.add(Calendar.DATE, key.getValidDays());
-
- return calendar.getTime();
- }
-
- public static Date getExpiryDate(PGPSecretKey key) {
- return getExpiryDate(key.getPublicKey());
- }
-
- public static PGPPublicKey getEncryptPublicKey(Context context, long masterKeyId) {
- PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRing(context, masterKeyId);
- if (keyRing == null) {
- Log.e(Constants.TAG, "keyRing is null!");
- return null;
- }
- Vector<PGPPublicKey> encryptKeys = getUsableEncryptKeys(keyRing);
- if (encryptKeys.size() == 0) {
- Log.e(Constants.TAG, "encryptKeys is null!");
- return null;
- }
- return encryptKeys.get(0);
- }
-
- public static PGPSecretKey getCertificationKey(Context context, long masterKeyId) {
- PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId);
- if (keyRing == null) {
- return null;
- }
- Vector<PGPSecretKey> signingKeys = getUsableCertificationKeys(keyRing);
- if (signingKeys.size() == 0) {
- return null;
- }
- return signingKeys.get(0);
- }
-
- public static PGPSecretKey getSigningKey(Context context, long masterKeyId) {
- PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId);
- if (keyRing == null) {
- return null;
- }
- Vector<PGPSecretKey> signingKeys = getUsableSigningKeys(keyRing);
- if (signingKeys.size() == 0) {
- return null;
- }
- return signingKeys.get(0);
- }
-
- @SuppressWarnings("unchecked")
- public static String getMainUserId(PGPPublicKey key) {
- for (String userId : new IterableIterator<String>(key.getUserIDs())) {
- return userId;
- }
- return null;
- }
-
- @SuppressWarnings("unchecked")
- public static String getMainUserId(PGPSecretKey key) {
- for (String userId : new IterableIterator<String>(key.getUserIDs())) {
- return userId;
- }
- return null;
- }
-
- public static String getMainUserIdSafe(Context context, PGPPublicKey key) {
- String userId = getMainUserId(key);
- if (userId == null || userId.equals("")) {
- userId = context.getString(R.string.user_id_no_name);
- }
- return userId;
- }
-
- public static String getMainUserIdSafe(Context context, PGPSecretKey key) {
- String userId = getMainUserId(key);
- if (userId == null || userId.equals("")) {
- userId = context.getString(R.string.user_id_no_name);
- }
- return userId;
- }
-
- public static int getKeyUsage(PGPSecretKey key) {
- return getKeyUsage(key.getPublicKey());
- }
-
- @SuppressWarnings("unchecked")
- private static int getKeyUsage(PGPPublicKey key) {
- int usage = 0;
- if (key.getVersion() >= 4) {
- for (PGPSignature sig : new IterableIterator<PGPSignature>(key.getSignatures())) {
- if (key.isMasterKey() && sig.getKeyID() != key.getKeyID()) {
- continue;
- }
-
- PGPSignatureSubpacketVector hashed = sig.getHashedSubPackets();
- if (hashed != null) {
- usage |= hashed.getKeyFlags();
- }
-
- PGPSignatureSubpacketVector unhashed = sig.getUnhashedSubPackets();
- if (unhashed != null) {
- usage |= unhashed.getKeyFlags();
- }
- }
- }
- return usage;
- }
-
- @SuppressWarnings("unchecked")
- public static boolean isEncryptionKey(PGPPublicKey key) {
- if (!key.isEncryptionKey()) {
- return false;
- }
-
- if (key.getVersion() <= 3) {
- // this must be true now
- return key.isEncryptionKey();
- }
-
- // special cases
- if (key.getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT) {
- return true;
- }
-
- if (key.getAlgorithm() == PGPPublicKey.RSA_ENCRYPT) {
- return true;
- }
-
- for (PGPSignature sig : new IterableIterator<PGPSignature>(key.getSignatures())) {
- if (key.isMasterKey() && sig.getKeyID() != key.getKeyID()) {
- continue;
- }
- PGPSignatureSubpacketVector hashed = sig.getHashedSubPackets();
-
- if (hashed != null
- && (hashed.getKeyFlags() & (KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE)) != 0) {
- return true;
- }
-
- PGPSignatureSubpacketVector unhashed = sig.getUnhashedSubPackets();
-
- if (unhashed != null
- && (unhashed.getKeyFlags() & (KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE)) != 0) {
- return true;
- }
- }
- return false;
- }
-
- public static boolean isEncryptionKey(PGPSecretKey key) {
- return isEncryptionKey(key.getPublicKey());
- }
-
- @SuppressWarnings("unchecked")
- public static boolean isSigningKey(PGPPublicKey key) {
- if (key.getVersion() <= 3) {
- return true;
- }
-
- // special case
- if (key.getAlgorithm() == PGPPublicKey.RSA_SIGN) {
- return true;
- }
-
- for (PGPSignature sig : new IterableIterator<PGPSignature>(key.getSignatures())) {
- if (key.isMasterKey() && sig.getKeyID() != key.getKeyID()) {
- continue;
- }
- PGPSignatureSubpacketVector hashed = sig.getHashedSubPackets();
-
- if (hashed != null && (hashed.getKeyFlags() & KeyFlags.SIGN_DATA) != 0) {
- return true;
- }
-
- PGPSignatureSubpacketVector unhashed = sig.getUnhashedSubPackets();
-
- if (unhashed != null && (unhashed.getKeyFlags() & KeyFlags.SIGN_DATA) != 0) {
- return true;
- }
- }
-
- return false;
- }
-
- public static boolean isSigningKey(PGPSecretKey key) {
- return isSigningKey(key.getPublicKey());
- }
-
- @SuppressWarnings("unchecked")
- public static boolean isCertificationKey(PGPPublicKey key) {
- if (key.getVersion() <= 3) {
- return true;
- }
-
- for (PGPSignature sig : new IterableIterator<PGPSignature>(key.getSignatures())) {
- if (key.isMasterKey() && sig.getKeyID() != key.getKeyID()) {
- continue;
- }
- PGPSignatureSubpacketVector hashed = sig.getHashedSubPackets();
-
- if (hashed != null && (hashed.getKeyFlags() & KeyFlags.CERTIFY_OTHER) != 0) {
- return true;
- }
-
- PGPSignatureSubpacketVector unhashed = sig.getUnhashedSubPackets();
-
- if (unhashed != null && (unhashed.getKeyFlags() & KeyFlags.CERTIFY_OTHER) != 0) {
- return true;
- }
- }
-
- return false;
- }
-
- public static boolean isAuthenticationKey(PGPSecretKey key) {
- return isAuthenticationKey(key.getPublicKey());
- }
-
- @SuppressWarnings("unchecked")
- public static boolean isAuthenticationKey(PGPPublicKey key) {
- if (key.getVersion() <= 3) {
- return true;
- }
-
- for (PGPSignature sig : new IterableIterator<PGPSignature>(key.getSignatures())) {
- if (key.isMasterKey() && sig.getKeyID() != key.getKeyID()) {
- continue;
- }
- PGPSignatureSubpacketVector hashed = sig.getHashedSubPackets();
-
- if (hashed != null && (hashed.getKeyFlags() & KeyFlags.AUTHENTICATION) != 0) {
- return true;
- }
-
- PGPSignatureSubpacketVector unhashed = sig.getUnhashedSubPackets();
-
- if (unhashed != null && (unhashed.getKeyFlags() & KeyFlags.AUTHENTICATION) != 0) {
- return true;
- }
- }
-
- return false;
- }
-
- public static boolean isCertificationKey(PGPSecretKey key) {
- return isCertificationKey(key.getPublicKey());
- }
-
- public static String getAlgorithmInfo(PGPPublicKey key) {
- return getAlgorithmInfo(key.getAlgorithm(), key.getBitStrength());
- }
-
- public static String getAlgorithmInfo(PGPSecretKey key) {
- return getAlgorithmInfo(key.getPublicKey());
- }
-
- public static String getAlgorithmInfo(int algorithm, int keySize) {
- String algorithmStr;
-
- switch (algorithm) {
- case PGPPublicKey.RSA_ENCRYPT:
- case PGPPublicKey.RSA_GENERAL:
- case PGPPublicKey.RSA_SIGN: {
- algorithmStr = "RSA";
- break;
- }
- case PGPPublicKey.DSA: {
- algorithmStr = "DSA";
- break;
- }
-
- case PGPPublicKey.ELGAMAL_ENCRYPT:
- case PGPPublicKey.ELGAMAL_GENERAL: {
- algorithmStr = "ElGamal";
- break;
- }
-
- default: {
- algorithmStr = "Unknown";
- break;
- }
- }
- if(keySize > 0)
- return algorithmStr + ", " + keySize + " bit";
- else
- return algorithmStr;
- }
-
- /**
- * Converts fingerprint to hex (optional: with whitespaces after 4 characters)
- * <p/>
- * Fingerprint is shown using lowercase characters. Studies have shown that humans can
- * better differentiate between numbers and letters when letters are lowercase.
- *
- * @param fingerprint
- * @return
- */
- public static String convertFingerprintToHex(byte[] fingerprint) {
- String hexString = Hex.toHexString(fingerprint);
-
- return hexString;
- }
-
- /**
- * Convert key id from long to 64 bit hex string
- * <p/>
- * V4: "The Key ID is the low-order 64 bits of the fingerprint"
- * <p/>
- * see http://tools.ietf.org/html/rfc4880#section-12.2
- *
- * @param keyId
- * @return
- */
- public static String convertKeyIdToHex(long keyId) {
- long upper = keyId >> 32;
- if (upper == 0) {
- // this is a short key id
- return convertKeyIdToHexShort(keyId);
- }
- return "0x" + convertKeyIdToHex32bit(keyId >> 32) + convertKeyIdToHex32bit(keyId);
- }
-
- public static String convertKeyIdToHexShort(long keyId) {
- return "0x" + convertKeyIdToHex32bit(keyId);
- }
-
- private static String convertKeyIdToHex32bit(long keyId) {
- String hexString = Long.toHexString(keyId & 0xffffffffL).toLowerCase(Locale.US);
- while (hexString.length() < 8) {
- hexString = "0" + hexString;
- }
- return hexString;
- }
-
-
- public static SpannableStringBuilder colorizeFingerprint(String fingerprint) {
- // split by 4 characters
- fingerprint = fingerprint.replaceAll("(.{4})(?!$)", "$1 ");
-
- // add line breaks to have a consistent "image" that can be recognized
- char[] chars = fingerprint.toCharArray();
- chars[24] = '\n';
- fingerprint = String.valueOf(chars);
-
- SpannableStringBuilder sb = new SpannableStringBuilder(fingerprint);
- try {
- // for each 4 characters of the fingerprint + 1 space
- for (int i = 0; i < fingerprint.length(); i += 5) {
- int spanEnd = Math.min(i + 4, fingerprint.length());
- String fourChars = fingerprint.substring(i, spanEnd);
-
- int raw = Integer.parseInt(fourChars, 16);
- byte[] bytes = {(byte) ((raw >> 8) & 0xff - 128), (byte) (raw & 0xff - 128)};
- int[] color = getRgbForData(bytes);
- int r = color[0];
- int g = color[1];
- int b = color[2];
-
- // we cannot change black by multiplication, so adjust it to an almost-black grey,
- // which will then be brightened to the minimal brightness level
- if (r == 0 && g == 0 && b == 0) {
- r = 1;
- g = 1;
- b = 1;
- }
-
- // Convert rgb to brightness
- double brightness = 0.2126 * r + 0.7152 * g + 0.0722 * b;
-
- // If a color is too dark to be seen on black,
- // then brighten it up to a minimal brightness.
- if (brightness < 80) {
- double factor = 80.0 / brightness;
- r = Math.min(255, (int) (r * factor));
- g = Math.min(255, (int) (g * factor));
- b = Math.min(255, (int) (b * factor));
-
- // If it is too light, then darken it to a respective maximal brightness.
- } else if (brightness > 180) {
- double factor = 180.0 / brightness;
- r = (int) (r * factor);
- g = (int) (g * factor);
- b = (int) (b * factor);
- }
-
- // Create a foreground color with the 3 digest integers as RGB
- // and then converting that int to hex to use as a color
- sb.setSpan(new ForegroundColorSpan(Color.rgb(r, g, b)),
- i, spanEnd, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
- }
- } catch (Exception e) {
- Log.e(Constants.TAG, "Colorization failed", e);
- // if anything goes wrong, then just display the fingerprint without colour,
- // instead of partially correct colour or wrong colours
- return new SpannableStringBuilder(fingerprint);
- }
-
- return sb;
- }
-
- /**
- * Converts the given bytes to a unique RGB color using SHA1 algorithm
- *
- * @param bytes
- * @return an integer array containing 3 numeric color representations (Red, Green, Black)
- * @throws java.security.NoSuchAlgorithmException
- * @throws java.security.DigestException
- */
- private static int[] getRgbForData(byte[] bytes) throws NoSuchAlgorithmException, DigestException {
- MessageDigest md = MessageDigest.getInstance("SHA1");
-
- md.update(bytes);
- byte[] digest = md.digest();
-
- int[] result = {((int) digest[0] + 256) % 256,
- ((int) digest[1] + 256) % 256,
- ((int) digest[2] + 256) % 256};
- return result;
- }
-
- /**
- * Splits userId string into naming part, email part, and comment part
- *
- * @param userId
- * @return array with naming (0), email (1), comment (2)
- */
- public static String[] splitUserId(String userId) {
- String[] result = new String[]{null, null, null};
-
- if (userId == null || userId.equals("")) {
- return result;
- }
-
- /*
- * User ID matching:
- * http://fiddle.re/t4p6f
- *
- * test cases:
- * "Max Mustermann (this is a comment) <max@example.com>"
- * "Max Mustermann <max@example.com>"
- * "Max Mustermann (this is a comment)"
- * "Max Mustermann [this is nothing]"
- */
- Matcher matcher = USER_ID_PATTERN.matcher(userId);
- if (matcher.matches()) {
- result[0] = matcher.group(1);
- result[1] = matcher.group(3);
- result[2] = matcher.group(2);
- }
-
- return result;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
deleted file mode 100644
index 48b959738..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.pgp;
-
-import android.util.Pair;
-
-import org.spongycastle.bcpg.CompressionAlgorithmTags;
-import org.spongycastle.bcpg.HashAlgorithmTags;
-import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
-import org.spongycastle.bcpg.sig.KeyFlags;
-import org.spongycastle.jce.spec.ElGamalParameterSpec;
-import org.spongycastle.openpgp.PGPEncryptedData;
-import org.spongycastle.openpgp.PGPException;
-import org.spongycastle.openpgp.PGPKeyPair;
-import org.spongycastle.openpgp.PGPKeyRingGenerator;
-import org.spongycastle.openpgp.PGPPrivateKey;
-import org.spongycastle.openpgp.PGPPublicKey;
-import org.spongycastle.openpgp.PGPPublicKeyRing;
-import org.spongycastle.openpgp.PGPSecretKey;
-import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.spongycastle.openpgp.PGPSignature;
-import org.spongycastle.openpgp.PGPSignatureGenerator;
-import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
-import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
-import org.spongycastle.openpgp.PGPUtil;
-import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
-import org.spongycastle.openpgp.operator.PBESecretKeyEncryptor;
-import org.spongycastle.openpgp.operator.PGPContentSignerBuilder;
-import org.spongycastle.openpgp.operator.PGPDigestCalculator;
-import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
-import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
-import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
-import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
-import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException;
-import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
-import org.sufficientlysecure.keychain.util.IterableIterator;
-import org.sufficientlysecure.keychain.util.Primes;
-import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.SecureRandom;
-import java.security.SignatureException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.Iterator;
-import java.util.List;
-import java.util.TimeZone;
-
-/** This class is the single place where ALL operations that actually modify a PGP public or secret
- * key take place.
- *
- * Note that no android specific stuff should be done here, ie no imports from com.android.
- *
- * All operations support progress reporting to a ProgressDialogUpdater passed on initialization.
- * This indicator may be null.
- *
- */
-public class PgpKeyOperation {
- private ProgressDialogUpdater mProgress;
-
- private static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[]{
- SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192,
- SymmetricKeyAlgorithmTags.AES_128, SymmetricKeyAlgorithmTags.CAST5,
- SymmetricKeyAlgorithmTags.TRIPLE_DES};
- private static final int[] PREFERRED_HASH_ALGORITHMS = new int[]{HashAlgorithmTags.SHA1,
- HashAlgorithmTags.SHA256, HashAlgorithmTags.RIPEMD160};
- private static final int[] PREFERRED_COMPRESSION_ALGORITHMS = new int[]{
- CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.BZIP2,
- CompressionAlgorithmTags.ZIP};
-
- public PgpKeyOperation(ProgressDialogUpdater progress) {
- super();
- this.mProgress = progress;
- }
-
- void updateProgress(int message, int current, int total) {
- if (mProgress != null) {
- mProgress.setProgress(message, current, total);
- }
- }
-
- void updateProgress(int current, int total) {
- if (mProgress != null) {
- mProgress.setProgress(current, total);
- }
- }
-
- /**
- * Creates new secret key.
- *
- * @param algorithmChoice
- * @param keySize
- * @param passphrase
- * @param isMasterKey
- * @return A newly created PGPSecretKey
- * @throws NoSuchAlgorithmException
- * @throws PGPException
- * @throws NoSuchProviderException
- * @throws PgpGeneralMsgIdException
- * @throws InvalidAlgorithmParameterException
- */
-
- // TODO: key flags?
- public PGPSecretKey createKey(int algorithmChoice, int keySize, String passphrase,
- boolean isMasterKey)
- throws NoSuchAlgorithmException, PGPException, NoSuchProviderException,
- PgpGeneralMsgIdException, InvalidAlgorithmParameterException {
-
- if (keySize < 512) {
- throw new PgpGeneralMsgIdException(R.string.error_key_size_minimum512bit);
- }
-
- if (passphrase == null) {
- passphrase = "";
- }
-
- int algorithm;
- KeyPairGenerator keyGen;
-
- switch (algorithmChoice) {
- case Id.choice.algorithm.dsa: {
- keyGen = KeyPairGenerator.getInstance("DSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME);
- keyGen.initialize(keySize, new SecureRandom());
- algorithm = PGPPublicKey.DSA;
- break;
- }
-
- case Id.choice.algorithm.elgamal: {
- if (isMasterKey) {
- throw new PgpGeneralMsgIdException(R.string.error_master_key_must_not_be_el_gamal);
- }
- keyGen = KeyPairGenerator.getInstance("ElGamal", Constants.BOUNCY_CASTLE_PROVIDER_NAME);
- BigInteger p = Primes.getBestPrime(keySize);
- BigInteger g = new BigInteger("2");
-
- ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g);
-
- keyGen.initialize(elParams);
- algorithm = PGPPublicKey.ELGAMAL_ENCRYPT;
- break;
- }
-
- case Id.choice.algorithm.rsa: {
- keyGen = KeyPairGenerator.getInstance("RSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME);
- keyGen.initialize(keySize, new SecureRandom());
-
- algorithm = PGPPublicKey.RSA_GENERAL;
- break;
- }
-
- default: {
- throw new PgpGeneralMsgIdException(R.string.error_unknown_algorithm_choice);
- }
- }
-
- // build new key pair
- PGPKeyPair keyPair = new JcaPGPKeyPair(algorithm, keyGen.generateKeyPair(), new Date());
-
- // define hashing and signing algos
- PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(
- HashAlgorithmTags.SHA1);
-
- // Build key encrypter and decrypter based on passphrase
- PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
- PGPEncryptedData.CAST5, sha1Calc)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
-
- return new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(),
- sha1Calc, isMasterKey, keyEncryptor);
- }
-
- public PGPSecretKeyRing changeSecretKeyPassphrase(PGPSecretKeyRing keyRing, String oldPassphrase,
- String newPassphrase)
- throws IOException, PGPException, NoSuchProviderException {
-
- updateProgress(R.string.progress_building_key, 0, 100);
- if (oldPassphrase == null) {
- oldPassphrase = "";
- }
- if (newPassphrase == null) {
- newPassphrase = "";
- }
-
- PGPSecretKeyRing newKeyRing = PGPSecretKeyRing.copyWithNewPassword(
- keyRing,
- new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build()).setProvider(
- Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassphrase.toCharArray()),
- new JcePBESecretKeyEncryptorBuilder(keyRing.getSecretKey()
- .getKeyEncryptionAlgorithm()).build(newPassphrase.toCharArray()));
-
- return newKeyRing;
-
- }
-
- private Pair<PGPSecretKeyRing, PGPPublicKeyRing> buildNewSecretKey(
- ArrayList<String> userIds, ArrayList<PGPSecretKey> keys,
- ArrayList<GregorianCalendar> keysExpiryDates,
- ArrayList<Integer> keysUsages,
- String newPassphrase, String oldPassphrase)
- throws PgpGeneralMsgIdException, PGPException, SignatureException, IOException {
-
- int usageId = keysUsages.get(0);
- boolean canSign;
- String mainUserId = userIds.get(0);
-
- PGPSecretKey masterKey = keys.get(0);
-
- // this removes all userIds and certifications previously attached to the masterPublicKey
- PGPPublicKey masterPublicKey = masterKey.getPublicKey();
-
- PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
- Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassphrase.toCharArray());
- PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(keyDecryptor);
-
- updateProgress(R.string.progress_certifying_master_key, 20, 100);
-
- for (String userId : userIds) {
- PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
- masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
- PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
-
- sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey);
-
- PGPSignature certification = sGen.generateCertification(userId, masterPublicKey);
- masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification);
- }
-
- PGPKeyPair masterKeyPair = new PGPKeyPair(masterPublicKey, masterPrivateKey);
-
- PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator();
- PGPSignatureSubpacketGenerator unhashedPacketsGen = new PGPSignatureSubpacketGenerator();
-
- hashedPacketsGen.setKeyFlags(true, usageId);
-
- hashedPacketsGen.setPreferredSymmetricAlgorithms(true, PREFERRED_SYMMETRIC_ALGORITHMS);
- hashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS);
- hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS);
-
- if (keysExpiryDates.get(0) != null) {
- GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
- creationDate.setTime(masterPublicKey.getCreationTime());
- GregorianCalendar expiryDate = keysExpiryDates.get(0);
- //note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c
- //here we purposefully ignore partial days in each date - long type has no fractional part!
- long numDays = (expiryDate.getTimeInMillis() / 86400000) -
- (creationDate.getTimeInMillis() / 86400000);
- if (numDays <= 0) {
- throw new PgpGeneralMsgIdException(R.string.error_expiry_must_come_after_creation);
- }
- hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400);
- } else {
- hashedPacketsGen.setKeyExpirationTime(false, 0);
- // do this explicitly, although since we're rebuilding,
- // this happens anyway
- }
-
- updateProgress(R.string.progress_building_master_key, 30, 100);
-
- // define hashing and signing algos
- PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(
- HashAlgorithmTags.SHA1);
- PGPContentSignerBuilder certificationSignerBuilder = new JcaPGPContentSignerBuilder(
- masterKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1);
-
- // Build key encrypter based on passphrase
- PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
- PGPEncryptedData.CAST5, sha1Calc)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
- newPassphrase.toCharArray());
-
- PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION,
- masterKeyPair, mainUserId, sha1Calc, hashedPacketsGen.generate(),
- unhashedPacketsGen.generate(), certificationSignerBuilder, keyEncryptor);
-
- updateProgress(R.string.progress_adding_sub_keys, 40, 100);
-
- for (int i = 1; i < keys.size(); ++i) {
- updateProgress(40 + 40 * (i - 1) / (keys.size() - 1), 100);
-
- PGPSecretKey subKey = keys.get(i);
- PGPPublicKey subPublicKey = subKey.getPublicKey();
-
- PBESecretKeyDecryptor keyDecryptor2 = new JcePBESecretKeyDecryptorBuilder()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
- oldPassphrase.toCharArray());
- PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(keyDecryptor2);
-
- // TODO: now used without algorithm and creation time?! (APG 1)
- PGPKeyPair subKeyPair = new PGPKeyPair(subPublicKey, subPrivateKey);
-
- hashedPacketsGen = new PGPSignatureSubpacketGenerator();
- unhashedPacketsGen = new PGPSignatureSubpacketGenerator();
-
- usageId = keysUsages.get(i);
- canSign = (usageId & KeyFlags.SIGN_DATA) > 0; //todo - separate function for this
- if (canSign) {
- Date todayDate = new Date(); //both sig times the same
- // cross-certify signing keys
- hashedPacketsGen.setSignatureCreationTime(false, todayDate); //set outer creation time
- PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator();
- subHashedPacketsGen.setSignatureCreationTime(false, todayDate); //set inner creation time
- PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
- subPublicKey.getAlgorithm(), PGPUtil.SHA1)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
- PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
- sGen.init(PGPSignature.PRIMARYKEY_BINDING, subPrivateKey);
- sGen.setHashedSubpackets(subHashedPacketsGen.generate());
- PGPSignature certification = sGen.generateCertification(masterPublicKey,
- subPublicKey);
- unhashedPacketsGen.setEmbeddedSignature(false, certification);
- }
- hashedPacketsGen.setKeyFlags(false, usageId);
-
- if (keysExpiryDates.get(i) != null) {
- GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
- creationDate.setTime(subPublicKey.getCreationTime());
- GregorianCalendar expiryDate = keysExpiryDates.get(i);
- //note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c
- //here we purposefully ignore partial days in each date - long type has no fractional part!
- long numDays = (expiryDate.getTimeInMillis() / 86400000) -
- (creationDate.getTimeInMillis() / 86400000);
- if (numDays <= 0) {
- throw new PgpGeneralMsgIdException(R.string.error_expiry_must_come_after_creation);
- }
- hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400);
- } else {
- hashedPacketsGen.setKeyExpirationTime(false, 0);
- // do this explicitly, although since we're rebuilding,
- // this happens anyway
- }
-
- keyGen.addSubKey(subKeyPair, hashedPacketsGen.generate(), unhashedPacketsGen.generate());
- }
-
- PGPSecretKeyRing secretKeyRing = keyGen.generateSecretKeyRing();
- PGPPublicKeyRing publicKeyRing = keyGen.generatePublicKeyRing();
-
- return new Pair<PGPSecretKeyRing, PGPPublicKeyRing>(secretKeyRing, publicKeyRing);
-
- }
-
- public Pair<PGPSecretKeyRing, PGPPublicKeyRing> buildSecretKey(PGPSecretKeyRing mKR,
- PGPPublicKeyRing pKR,
- SaveKeyringParcel saveParcel)
- throws PgpGeneralMsgIdException, PGPException, SignatureException, IOException {
-
- updateProgress(R.string.progress_building_key, 0, 100);
- PGPSecretKey masterKey = saveParcel.keys.get(0);
-
- if (saveParcel.oldPassphrase == null) {
- saveParcel.oldPassphrase = "";
- }
- if (saveParcel.newPassphrase == null) {
- saveParcel.newPassphrase = "";
- }
-
- if (mKR == null) {
- return buildNewSecretKey(saveParcel.userIDs, saveParcel.keys, saveParcel.keysExpiryDates,
- saveParcel.keysUsages, saveParcel.newPassphrase, saveParcel.oldPassphrase); //new Keyring
- }
-
- /*
- IDs - NB This might not need to happen later, if we change the way the primary ID is chosen
- remove deleted ids
- if the primary ID changed we need to:
- remove all of the IDs from the keyring, saving their certifications
- add them all in again, updating certs of IDs which have changed
- else
- remove changed IDs and add in with new certs
-
- if the master key changed, we need to remove the primary ID certification, so we can add
- the new one when it is generated, and they don't conflict
-
- Keys
- remove deleted keys
- if a key is modified, re-sign it
- do we need to remove and add in?
-
- Todo
- identify more things which need to be preserved - e.g. trust levels?
- user attributes
- */
-
- if (saveParcel.deletedKeys != null) {
- for (PGPSecretKey dKey : saveParcel.deletedKeys) {
- mKR = PGPSecretKeyRing.removeSecretKey(mKR, dKey);
- }
- }
-
- masterKey = mKR.getSecretKey();
- PGPPublicKey masterPublicKey = masterKey.getPublicKey();
-
- int usageId = saveParcel.keysUsages.get(0);
- boolean canSign;
- String mainUserId = saveParcel.userIDs.get(0);
-
- PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
- Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(saveParcel.oldPassphrase.toCharArray());
- PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(keyDecryptor);
-
- updateProgress(R.string.progress_certifying_master_key, 20, 100);
-
- boolean anyIDChanged = false;
- for (String delID : saveParcel.deletedIDs) {
- anyIDChanged = true;
- masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, delID);
- }
-
- int userIDIndex = 0;
-
- PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator();
- PGPSignatureSubpacketGenerator unhashedPacketsGen = new PGPSignatureSubpacketGenerator();
-
- hashedPacketsGen.setKeyFlags(true, usageId);
-
- hashedPacketsGen.setPreferredSymmetricAlgorithms(true, PREFERRED_SYMMETRIC_ALGORITHMS);
- hashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS);
- hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS);
-
- if (saveParcel.keysExpiryDates.get(0) != null) {
- GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
- creationDate.setTime(masterPublicKey.getCreationTime());
- GregorianCalendar expiryDate = saveParcel.keysExpiryDates.get(0);
- //note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c
- //here we purposefully ignore partial days in each date - long type has no fractional part!
- long numDays = (expiryDate.getTimeInMillis() / 86400000) -
- (creationDate.getTimeInMillis() / 86400000);
- if (numDays <= 0) {
- throw new PgpGeneralMsgIdException(R.string.error_expiry_must_come_after_creation);
- }
- hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400);
- } else {
- hashedPacketsGen.setKeyExpirationTime(false, 0);
- // do this explicitly, although since we're rebuilding,
- // this happens anyway
- }
-
- if (saveParcel.primaryIDChanged ||
- !saveParcel.originalIDs.get(0).equals(saveParcel.userIDs.get(0))) {
- anyIDChanged = true;
- ArrayList<Pair<String, PGPSignature>> sigList = new ArrayList<Pair<String, PGPSignature>>();
- for (String userId : saveParcel.userIDs) {
- String origID = saveParcel.originalIDs.get(userIDIndex);
- if (origID.equals(userId) && !saveParcel.newIDs[userIDIndex] &&
- !userId.equals(saveParcel.originalPrimaryID) && userIDIndex != 0) {
- Iterator<PGPSignature> origSigs = masterPublicKey.getSignaturesForID(origID);
- // TODO: make sure this iterator only has signatures we are interested in
- while (origSigs.hasNext()) {
- PGPSignature origSig = origSigs.next();
- sigList.add(new Pair<String, PGPSignature>(origID, origSig));
- }
- } else {
- PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
- masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
- PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
-
- sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey);
- if (userIDIndex == 0) {
- sGen.setHashedSubpackets(hashedPacketsGen.generate());
- sGen.setUnhashedSubpackets(unhashedPacketsGen.generate());
- }
- PGPSignature certification = sGen.generateCertification(userId, masterPublicKey);
- sigList.add(new Pair<String, PGPSignature>(userId, certification));
- }
- if (!saveParcel.newIDs[userIDIndex]) {
- masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, origID);
- }
- userIDIndex++;
- }
- for (Pair<String, PGPSignature> toAdd : sigList) {
- masterPublicKey =
- PGPPublicKey.addCertification(masterPublicKey, toAdd.first, toAdd.second);
- }
- } else {
- for (String userId : saveParcel.userIDs) {
- String origID = saveParcel.originalIDs.get(userIDIndex);
- if (!origID.equals(userId) || saveParcel.newIDs[userIDIndex]) {
- anyIDChanged = true;
- PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
- masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
- PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
-
- sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey);
- if (userIDIndex == 0) {
- sGen.setHashedSubpackets(hashedPacketsGen.generate());
- sGen.setUnhashedSubpackets(unhashedPacketsGen.generate());
- }
- PGPSignature certification = sGen.generateCertification(userId, masterPublicKey);
- if (!saveParcel.newIDs[userIDIndex]) {
- masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, origID);
- }
- masterPublicKey =
- PGPPublicKey.addCertification(masterPublicKey, userId, certification);
- }
- userIDIndex++;
- }
- }
-
- ArrayList<Pair<String, PGPSignature>> sigList = new ArrayList<Pair<String, PGPSignature>>();
- if (saveParcel.moddedKeys[0]) {
- userIDIndex = 0;
- for (String userId : saveParcel.userIDs) {
- String origID = saveParcel.originalIDs.get(userIDIndex);
- if (!(origID.equals(saveParcel.originalPrimaryID) && !saveParcel.primaryIDChanged)) {
- Iterator<PGPSignature> sigs = masterPublicKey.getSignaturesForID(userId);
- // TODO: make sure this iterator only has signatures we are interested in
- while (sigs.hasNext()) {
- PGPSignature sig = sigs.next();
- sigList.add(new Pair<String, PGPSignature>(userId, sig));
- }
- }
- masterPublicKey = PGPPublicKey.removeCertification(masterPublicKey, userId);
- userIDIndex++;
- }
- anyIDChanged = true;
- }
-
- //update the keyring with the new ID information
- if (anyIDChanged) {
- pKR = PGPPublicKeyRing.insertPublicKey(pKR, masterPublicKey);
- mKR = PGPSecretKeyRing.replacePublicKeys(mKR, pKR);
- }
-
- PGPKeyPair masterKeyPair = new PGPKeyPair(masterPublicKey, masterPrivateKey);
-
- updateProgress(R.string.progress_building_master_key, 30, 100);
-
- // define hashing and signing algos
- PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(
- HashAlgorithmTags.SHA1);
- PGPContentSignerBuilder certificationSignerBuilder = new JcaPGPContentSignerBuilder(
- masterKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1);
-
- // Build key encryptor based on old passphrase, as some keys may be unchanged
- PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
- PGPEncryptedData.CAST5, sha1Calc)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
- saveParcel.oldPassphrase.toCharArray());
-
- //this generates one more signature than necessary...
- PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION,
- masterKeyPair, mainUserId, sha1Calc, hashedPacketsGen.generate(),
- unhashedPacketsGen.generate(), certificationSignerBuilder, keyEncryptor);
-
- for (int i = 1; i < saveParcel.keys.size(); ++i) {
- updateProgress(40 + 50 * i / saveParcel.keys.size(), 100);
- if (saveParcel.moddedKeys[i]) {
- PGPSecretKey subKey = saveParcel.keys.get(i);
- PGPPublicKey subPublicKey = subKey.getPublicKey();
-
- PBESecretKeyDecryptor keyDecryptor2;
- if (saveParcel.newKeys[i]) {
- keyDecryptor2 = new JcePBESecretKeyDecryptorBuilder()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
- "".toCharArray());
- } else {
- keyDecryptor2 = new JcePBESecretKeyDecryptorBuilder()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
- saveParcel.oldPassphrase.toCharArray());
- }
- PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(keyDecryptor2);
- PGPKeyPair subKeyPair = new PGPKeyPair(subPublicKey, subPrivateKey);
-
- hashedPacketsGen = new PGPSignatureSubpacketGenerator();
- unhashedPacketsGen = new PGPSignatureSubpacketGenerator();
-
- usageId = saveParcel.keysUsages.get(i);
- canSign = (usageId & KeyFlags.SIGN_DATA) > 0; //todo - separate function for this
- if (canSign) {
- Date todayDate = new Date(); //both sig times the same
- // cross-certify signing keys
- hashedPacketsGen.setSignatureCreationTime(false, todayDate); //set outer creation time
- PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator();
- subHashedPacketsGen.setSignatureCreationTime(false, todayDate); //set inner creation time
- PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
- subPublicKey.getAlgorithm(), PGPUtil.SHA1)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
- PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
- sGen.init(PGPSignature.PRIMARYKEY_BINDING, subPrivateKey);
- sGen.setHashedSubpackets(subHashedPacketsGen.generate());
- PGPSignature certification = sGen.generateCertification(masterPublicKey,
- subPublicKey);
- unhashedPacketsGen.setEmbeddedSignature(false, certification);
- }
- hashedPacketsGen.setKeyFlags(false, usageId);
-
- if (saveParcel.keysExpiryDates.get(i) != null) {
- GregorianCalendar creationDate = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
- creationDate.setTime(subPublicKey.getCreationTime());
- GregorianCalendar expiryDate = saveParcel.keysExpiryDates.get(i);
- // note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c
- // here we purposefully ignore partial days in each date - long type has
- // no fractional part!
- long numDays = (expiryDate.getTimeInMillis() / 86400000) -
- (creationDate.getTimeInMillis() / 86400000);
- if (numDays <= 0) {
- throw new PgpGeneralMsgIdException(R.string.error_expiry_must_come_after_creation);
- }
- hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400);
- } else {
- hashedPacketsGen.setKeyExpirationTime(false, 0);
- // do this explicitly, although since we're rebuilding,
- // this happens anyway
- }
-
- keyGen.addSubKey(subKeyPair, hashedPacketsGen.generate(), unhashedPacketsGen.generate());
- // certifications will be discarded if the key is changed, because I think, for a start,
- // they will be invalid. Binding certs are regenerated anyway, and other certs which
- // need to be kept are on IDs and attributes
- // TODO: don't let revoked keys be edited, other than removed - changing one would
- // result in the revocation being wrong?
- }
- }
-
- PGPSecretKeyRing updatedSecretKeyRing = keyGen.generateSecretKeyRing();
- //finally, update the keyrings
- Iterator<PGPSecretKey> itr = updatedSecretKeyRing.getSecretKeys();
- while (itr.hasNext()) {
- PGPSecretKey theNextKey = itr.next();
- if ((theNextKey.isMasterKey() && saveParcel.moddedKeys[0]) || !theNextKey.isMasterKey()) {
- mKR = PGPSecretKeyRing.insertSecretKey(mKR, theNextKey);
- pKR = PGPPublicKeyRing.insertPublicKey(pKR, theNextKey.getPublicKey());
- }
- }
-
- //replace lost IDs
- if (saveParcel.moddedKeys[0]) {
- masterPublicKey = mKR.getPublicKey();
- for (Pair<String, PGPSignature> toAdd : sigList) {
- masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, toAdd.first, toAdd.second);
- }
- pKR = PGPPublicKeyRing.insertPublicKey(pKR, masterPublicKey);
- mKR = PGPSecretKeyRing.replacePublicKeys(mKR, pKR);
- }
-
- // Build key encryptor based on new passphrase
- PBESecretKeyEncryptor keyEncryptorNew = new JcePBESecretKeyEncryptorBuilder(
- PGPEncryptedData.CAST5, sha1Calc)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
- saveParcel.newPassphrase.toCharArray());
-
- //update the passphrase
- mKR = PGPSecretKeyRing.copyWithNewPassword(mKR, keyDecryptor, keyEncryptorNew);
-
- /* additional handy debug info
-
- Log.d(Constants.TAG, " ------- in private key -------");
-
- for(String uid : new IterableIterator<String>(secretKeyRing.getPublicKey().getUserIDs())) {
- for(PGPSignature sig : new IterableIterator<PGPSignature>(
- secretKeyRing.getPublicKey().getSignaturesForID(uid))) {
- Log.d(Constants.TAG, "sig: " +
- PgpKeyHelper.convertKeyIdToHex(sig.getKeyID()) + " for " + uid);
- }
-
- }
-
- Log.d(Constants.TAG, " ------- in public key -------");
-
- for(String uid : new IterableIterator<String>(publicKeyRing.getPublicKey().getUserIDs())) {
- for(PGPSignature sig : new IterableIterator<PGPSignature>(
- publicKeyRing.getPublicKey().getSignaturesForID(uid))) {
- Log.d(Constants.TAG, "sig: " +
- PgpKeyHelper.convertKeyIdToHex(sig.getKeyID()) + " for " + uid);
- }
- }
-
- */
-
- return new Pair<PGPSecretKeyRing, PGPPublicKeyRing>(mKR, pKR);
-
- }
-
- /**
- * Certify the given pubkeyid with the given masterkeyid.
- *
- * @param certificationKey Certifying key
- * @param publicKey public key to certify
- * @param userIds User IDs to certify, must not be null or empty
- * @param passphrase Passphrase of the secret key
- * @return A keyring with added certifications
- */
- public PGPPublicKey certifyKey(PGPSecretKey certificationKey, PGPPublicKey publicKey,
- List<String> userIds, String passphrase)
- throws PgpGeneralMsgIdException, NoSuchAlgorithmException, NoSuchProviderException,
- PGPException, SignatureException {
-
- // create a signatureGenerator from the supplied masterKeyId and passphrase
- PGPSignatureGenerator signatureGenerator; {
-
- if (certificationKey == null) {
- throw new PgpGeneralMsgIdException(R.string.error_signature_failed);
- }
-
- PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
- Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
- PGPPrivateKey signaturePrivateKey = certificationKey.extractPrivateKey(keyDecryptor);
- if (signaturePrivateKey == null) {
- throw new PgpGeneralMsgIdException(R.string.error_could_not_extract_private_key);
- }
-
- // TODO: SHA256 fixed?
- JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(
- certificationKey.getPublicKey().getAlgorithm(), PGPUtil.SHA256)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
-
- signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder);
- signatureGenerator.init(PGPSignature.DEFAULT_CERTIFICATION, signaturePrivateKey);
- }
-
- { // supply signatureGenerator with a SubpacketVector
- PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
- PGPSignatureSubpacketVector packetVector = spGen.generate();
- signatureGenerator.setHashedSubpackets(packetVector);
- }
-
- // fetch public key ring, add the certification and return it
- for (String userId : new IterableIterator<String>(userIds.iterator())) {
- PGPSignature sig = signatureGenerator.generateCertification(userId, publicKey);
- publicKey = PGPPublicKey.addCertification(publicKey, userId, sig);
- }
-
- return publicKey;
- }
-
- /** Simple static subclass that stores two values.
- *
- * This is only used to return a pair of values in one function above. We specifically don't use
- * com.android.Pair to keep this class free from android dependencies.
- */
- public static class Pair<K, V> {
- public final K first;
- public final V second;
- public Pair(K first, V second) {
- this.first = first;
- this.second = second;
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java
deleted file mode 100644
index a864a165d..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java
+++ /dev/null
@@ -1,607 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.pgp;
-
-import android.content.Context;
-
-import org.spongycastle.bcpg.ArmoredOutputStream;
-import org.spongycastle.bcpg.BCPGOutputStream;
-import org.spongycastle.openpgp.PGPCompressedDataGenerator;
-import org.spongycastle.openpgp.PGPEncryptedDataGenerator;
-import org.spongycastle.openpgp.PGPException;
-import org.spongycastle.openpgp.PGPLiteralData;
-import org.spongycastle.openpgp.PGPLiteralDataGenerator;
-import org.spongycastle.openpgp.PGPPrivateKey;
-import org.spongycastle.openpgp.PGPPublicKey;
-import org.spongycastle.openpgp.PGPSecretKey;
-import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.spongycastle.openpgp.PGPSignature;
-import org.spongycastle.openpgp.PGPSignatureGenerator;
-import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
-import org.spongycastle.openpgp.PGPV3SignatureGenerator;
-import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
-import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
-import org.spongycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator;
-import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
-import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
-import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.util.InputData;
-import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.SignatureException;
-import java.util.Date;
-
-/**
- * This class uses a Builder pattern!
- */
-public class PgpSignEncrypt {
- private Context mContext;
- private InputData mData;
- private OutputStream mOutStream;
-
- private ProgressDialogUpdater mProgress;
- private boolean mEnableAsciiArmorOutput;
- private int mCompressionId;
- private long[] mEncryptionKeyIds;
- private String mSymmetricPassphrase;
- private int mSymmetricEncryptionAlgorithm;
- private long mSignatureKeyId;
- private int mSignatureHashAlgorithm;
- private boolean mSignatureForceV3;
- private String mSignaturePassphrase;
-
- private PgpSignEncrypt(Builder builder) {
- // private Constructor can only be called from Builder
- this.mContext = builder.mContext;
- this.mData = builder.mData;
- this.mOutStream = builder.mOutStream;
-
- this.mProgress = builder.mProgress;
- this.mEnableAsciiArmorOutput = builder.mEnableAsciiArmorOutput;
- this.mCompressionId = builder.mCompressionId;
- this.mEncryptionKeyIds = builder.mEncryptionKeyIds;
- this.mSymmetricPassphrase = builder.mSymmetricPassphrase;
- this.mSymmetricEncryptionAlgorithm = builder.mSymmetricEncryptionAlgorithm;
- this.mSignatureKeyId = builder.mSignatureKeyId;
- this.mSignatureHashAlgorithm = builder.mSignatureHashAlgorithm;
- this.mSignatureForceV3 = builder.mSignatureForceV3;
- this.mSignaturePassphrase = builder.mSignaturePassphrase;
- }
-
- public static class Builder {
- // mandatory parameter
- private Context mContext;
- private InputData mData;
- private OutputStream mOutStream;
-
- // optional
- private ProgressDialogUpdater mProgress = null;
- private boolean mEnableAsciiArmorOutput = false;
- private int mCompressionId = Id.choice.compression.none;
- private long[] mEncryptionKeyIds = null;
- private String mSymmetricPassphrase = null;
- private int mSymmetricEncryptionAlgorithm = 0;
- private long mSignatureKeyId = Id.key.none;
- private int mSignatureHashAlgorithm = 0;
- private boolean mSignatureForceV3 = false;
- private String mSignaturePassphrase = null;
-
- public Builder(Context context, InputData data, OutputStream outStream) {
- this.mContext = context;
- this.mData = data;
- this.mOutStream = outStream;
- }
-
- public Builder progress(ProgressDialogUpdater progress) {
- this.mProgress = progress;
- return this;
- }
-
- public Builder enableAsciiArmorOutput(boolean enableAsciiArmorOutput) {
- this.mEnableAsciiArmorOutput = enableAsciiArmorOutput;
- return this;
- }
-
- public Builder compressionId(int compressionId) {
- this.mCompressionId = compressionId;
- return this;
- }
-
- public Builder encryptionKeyIds(long[] encryptionKeyIds) {
- this.mEncryptionKeyIds = encryptionKeyIds;
- return this;
- }
-
- public Builder symmetricPassphrase(String symmetricPassphrase) {
- this.mSymmetricPassphrase = symmetricPassphrase;
- return this;
- }
-
- public Builder symmetricEncryptionAlgorithm(int symmetricEncryptionAlgorithm) {
- this.mSymmetricEncryptionAlgorithm = symmetricEncryptionAlgorithm;
- return this;
- }
-
- public Builder signatureKeyId(long signatureKeyId) {
- this.mSignatureKeyId = signatureKeyId;
- return this;
- }
-
- public Builder signatureHashAlgorithm(int signatureHashAlgorithm) {
- this.mSignatureHashAlgorithm = signatureHashAlgorithm;
- return this;
- }
-
- public Builder signatureForceV3(boolean signatureForceV3) {
- this.mSignatureForceV3 = signatureForceV3;
- return this;
- }
-
- public Builder signaturePassphrase(String signaturePassphrase) {
- this.mSignaturePassphrase = signaturePassphrase;
- return this;
- }
-
- public PgpSignEncrypt build() {
- return new PgpSignEncrypt(this);
- }
- }
-
- public void updateProgress(int message, int current, int total) {
- if (mProgress != null) {
- mProgress.setProgress(message, current, total);
- }
- }
-
- public void updateProgress(int current, int total) {
- if (mProgress != null) {
- mProgress.setProgress(current, total);
- }
- }
-
- /**
- * Signs and/or encrypts data based on parameters of class
- *
- * @throws IOException
- * @throws PgpGeneralException
- * @throws PGPException
- * @throws NoSuchProviderException
- * @throws NoSuchAlgorithmException
- * @throws SignatureException
- */
- public void execute()
- throws IOException, PgpGeneralException, PGPException, NoSuchProviderException,
- NoSuchAlgorithmException, SignatureException {
-
- boolean enableSignature = mSignatureKeyId != Id.key.none;
- boolean enableEncryption = ((mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0)
- || mSymmetricPassphrase != null);
- boolean enableCompression = (enableEncryption && mCompressionId != Id.choice.compression.none);
-
- Log.d(Constants.TAG, "enableSignature:" + enableSignature
- + "\nenableEncryption:" + enableEncryption
- + "\nenableCompression:" + enableCompression
- + "\nenableAsciiArmorOutput:" + mEnableAsciiArmorOutput);
-
- int signatureType;
- if (mEnableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) {
- // for sign-only ascii text
- signatureType = PGPSignature.CANONICAL_TEXT_DOCUMENT;
- } else {
- signatureType = PGPSignature.BINARY_DOCUMENT;
- }
-
- ArmoredOutputStream armorOut = null;
- OutputStream out;
- if (mEnableAsciiArmorOutput) {
- armorOut = new ArmoredOutputStream(mOutStream);
- armorOut.setHeader("Version", PgpHelper.getFullVersion(mContext));
- out = armorOut;
- } else {
- out = mOutStream;
- }
-
- /* Get keys for signature generation for later usage */
- PGPSecretKey signingKey = null;
- PGPSecretKeyRing signingKeyRing = null;
- PGPPrivateKey signaturePrivateKey = null;
- if (enableSignature) {
- signingKeyRing = ProviderHelper.getPGPSecretKeyRingWithKeyId(mContext, mSignatureKeyId);
- signingKey = PgpKeyHelper.getSigningKey(mContext, mSignatureKeyId);
- if (signingKey == null) {
- throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed));
- }
-
- if (mSignaturePassphrase == null) {
- throw new PgpGeneralException(
- mContext.getString(R.string.error_no_signature_passphrase));
- }
-
- updateProgress(R.string.progress_extracting_signature_key, 0, 100);
-
- PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
- Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(mSignaturePassphrase.toCharArray());
- signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
- if (signaturePrivateKey == null) {
- throw new PgpGeneralException(
- mContext.getString(R.string.error_could_not_extract_private_key));
- }
- }
- updateProgress(R.string.progress_preparing_streams, 5, 100);
-
- /* Initialize PGPEncryptedDataGenerator for later usage */
- PGPEncryptedDataGenerator cPk = null;
- if (enableEncryption) {
- // has Integrity packet enabled!
- JcePGPDataEncryptorBuilder encryptorBuilder =
- new JcePGPDataEncryptorBuilder(mSymmetricEncryptionAlgorithm)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME)
- .setWithIntegrityPacket(true);
-
- cPk = new PGPEncryptedDataGenerator(encryptorBuilder);
-
- if (mSymmetricPassphrase != null) {
- // Symmetric encryption
- Log.d(Constants.TAG, "encryptionKeyIds length is 0 -> symmetric encryption");
-
- JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator =
- new JcePBEKeyEncryptionMethodGenerator(mSymmetricPassphrase.toCharArray());
- cPk.addMethod(symmetricEncryptionGenerator);
- } else {
- // Asymmetric encryption
- for (long id : mEncryptionKeyIds) {
- PGPPublicKey key = PgpKeyHelper.getEncryptPublicKey(mContext, id);
- if (key != null) {
- JcePublicKeyKeyEncryptionMethodGenerator pubKeyEncryptionGenerator =
- new JcePublicKeyKeyEncryptionMethodGenerator(key);
- cPk.addMethod(pubKeyEncryptionGenerator);
- }
- }
- }
- }
-
- /* Initialize signature generator object for later usage */
- PGPSignatureGenerator signatureGenerator = null;
- PGPV3SignatureGenerator signatureV3Generator = null;
- if (enableSignature) {
- updateProgress(R.string.progress_preparing_signature, 10, 100);
-
- // content signer based on signing key algorithm and chosen hash algorithm
- JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(
- signingKey.getPublicKey().getAlgorithm(), mSignatureHashAlgorithm)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
-
- if (mSignatureForceV3) {
- signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder);
- signatureV3Generator.init(signatureType, signaturePrivateKey);
- } else {
- signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder);
- signatureGenerator.init(signatureType, signaturePrivateKey);
-
- String userId = PgpKeyHelper.getMainUserId(signingKeyRing.getSecretKey());
- PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
- spGen.setSignerUserID(false, userId);
- signatureGenerator.setHashedSubpackets(spGen.generate());
- }
- }
-
- PGPCompressedDataGenerator compressGen = null;
- OutputStream pOut;
- OutputStream encryptionOut = null;
- BCPGOutputStream bcpgOut;
- if (enableEncryption) {
- /* actual encryption */
-
- encryptionOut = cPk.open(out, new byte[1 << 16]);
-
- if (enableCompression) {
- compressGen = new PGPCompressedDataGenerator(mCompressionId);
- bcpgOut = new BCPGOutputStream(compressGen.open(encryptionOut));
- } else {
- bcpgOut = new BCPGOutputStream(encryptionOut);
- }
-
- if (enableSignature) {
- if (mSignatureForceV3) {
- signatureV3Generator.generateOnePassVersion(false).encode(bcpgOut);
- } else {
- signatureGenerator.generateOnePassVersion(false).encode(bcpgOut);
- }
- }
-
- PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator();
- // file name not needed, so empty string
- pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "", new Date(),
- new byte[1 << 16]);
- updateProgress(R.string.progress_encrypting, 20, 100);
-
- long progress = 0;
- int n;
- byte[] buffer = new byte[1 << 16];
- InputStream in = mData.getInputStream();
- while ((n = in.read(buffer)) > 0) {
- pOut.write(buffer, 0, n);
-
- // update signature buffer if signature is requested
- if (enableSignature) {
- if (mSignatureForceV3) {
- signatureV3Generator.update(buffer, 0, n);
- } else {
- signatureGenerator.update(buffer, 0, n);
- }
- }
-
- progress += n;
- if (mData.getSize() != 0) {
- updateProgress((int) (20 + (95 - 20) * progress / mData.getSize()), 100);
- }
- }
-
- literalGen.close();
- } else if (mEnableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) {
- /* sign-only of ascii text */
-
- updateProgress(R.string.progress_signing, 40, 100);
-
- // write directly on armor output stream
- armorOut.beginClearText(mSignatureHashAlgorithm);
-
- InputStream in = mData.getInputStream();
- final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
-
- final byte[] newline = "\r\n".getBytes("UTF-8");
-
- if (mSignatureForceV3) {
- processLine(reader.readLine(), armorOut, signatureV3Generator);
- } else {
- processLine(reader.readLine(), armorOut, signatureGenerator);
- }
-
- while (true) {
- String line = reader.readLine();
-
- if (line == null) {
- armorOut.write(newline);
- break;
- }
-
- armorOut.write(newline);
-
- // update signature buffer with input line
- if (mSignatureForceV3) {
- signatureV3Generator.update(newline);
- processLine(line, armorOut, signatureV3Generator);
- } else {
- signatureGenerator.update(newline);
- processLine(line, armorOut, signatureGenerator);
- }
- }
-
- armorOut.endClearText();
-
- pOut = new BCPGOutputStream(armorOut);
- } else {
- // TODO: implement sign-only for files!
- pOut = null;
- Log.e(Constants.TAG, "not supported!");
- }
-
- if (enableSignature) {
- updateProgress(R.string.progress_generating_signature, 95, 100);
- if (mSignatureForceV3) {
- signatureV3Generator.generate().encode(pOut);
- } else {
- signatureGenerator.generate().encode(pOut);
- }
- }
-
- // closing outputs
- // NOTE: closing needs to be done in the correct order!
- // TODO: closing bcpgOut and pOut???
- if (enableEncryption) {
- if (enableCompression) {
- compressGen.close();
- }
-
- encryptionOut.close();
- }
- if (mEnableAsciiArmorOutput) {
- armorOut.close();
- }
-
- out.close();
- mOutStream.close();
-
- updateProgress(R.string.progress_done, 100, 100);
- }
-
- // TODO: merge this into execute method!
- // TODO: allow binary input for this class
- public void generateSignature()
- throws PgpGeneralException, PGPException, IOException, NoSuchAlgorithmException,
- SignatureException {
-
- OutputStream out;
- if (mEnableAsciiArmorOutput) {
- // Ascii Armor (Radix-64)
- ArmoredOutputStream armorOut = new ArmoredOutputStream(mOutStream);
- armorOut.setHeader("Version", PgpHelper.getFullVersion(mContext));
- out = armorOut;
- } else {
- out = mOutStream;
- }
-
- if (mSignatureKeyId == 0) {
- throw new PgpGeneralException(mContext.getString(R.string.error_no_signature_key));
- }
-
- PGPSecretKeyRing signingKeyRing =
- ProviderHelper.getPGPSecretKeyRingWithKeyId(mContext, mSignatureKeyId);
- PGPSecretKey signingKey = PgpKeyHelper.getSigningKey(mContext, mSignatureKeyId);
- if (signingKey == null) {
- throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed));
- }
-
- if (mSignaturePassphrase == null) {
- throw new PgpGeneralException(mContext.getString(R.string.error_no_signature_passphrase));
- }
-
- PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
- Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(mSignaturePassphrase.toCharArray());
- PGPPrivateKey signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
- if (signaturePrivateKey == null) {
- throw new PgpGeneralException(
- mContext.getString(R.string.error_could_not_extract_private_key));
- }
- updateProgress(R.string.progress_preparing_streams, 0, 100);
-
- updateProgress(R.string.progress_preparing_signature, 30, 100);
-
- int type = PGPSignature.CANONICAL_TEXT_DOCUMENT;
-// if (binary) {
-// type = PGPSignature.BINARY_DOCUMENT;
-// }
-
- // content signer based on signing key algorithm and chosen hash algorithm
- JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(signingKey
- .getPublicKey().getAlgorithm(), mSignatureHashAlgorithm)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
-
- PGPSignatureGenerator signatureGenerator = null;
- PGPV3SignatureGenerator signatureV3Generator = null;
- if (mSignatureForceV3) {
- signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder);
- signatureV3Generator.init(type, signaturePrivateKey);
- } else {
- signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder);
- signatureGenerator.init(type, signaturePrivateKey);
-
- PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
- String userId = PgpKeyHelper.getMainUserId(signingKeyRing.getSecretKey());
- spGen.setSignerUserID(false, userId);
- signatureGenerator.setHashedSubpackets(spGen.generate());
- }
-
- updateProgress(R.string.progress_signing, 40, 100);
-
- InputStream inStream = mData.getInputStream();
-// if (binary) {
-// byte[] buffer = new byte[1 << 16];
-// int n = 0;
-// while ((n = inStream.read(buffer)) > 0) {
-// if (signatureForceV3) {
-// signatureV3Generator.update(buffer, 0, n);
-// } else {
-// signatureGenerator.update(buffer, 0, n);
-// }
-// }
-// } else {
- final BufferedReader reader = new BufferedReader(new InputStreamReader(inStream));
- final byte[] newline = "\r\n".getBytes("UTF-8");
-
- String line;
- while ((line = reader.readLine()) != null) {
- if (mSignatureForceV3) {
- processLine(line, null, signatureV3Generator);
- signatureV3Generator.update(newline);
- } else {
- processLine(line, null, signatureGenerator);
- signatureGenerator.update(newline);
- }
- }
-// }
-
- BCPGOutputStream bOut = new BCPGOutputStream(out);
- if (mSignatureForceV3) {
- signatureV3Generator.generate().encode(bOut);
- } else {
- signatureGenerator.generate().encode(bOut);
- }
- out.close();
- mOutStream.close();
-
- updateProgress(R.string.progress_done, 100, 100);
- }
-
-
- private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput,
- final PGPSignatureGenerator pSignatureGenerator)
- throws IOException, SignatureException {
-
- if (pLine == null) {
- return;
- }
-
- final char[] chars = pLine.toCharArray();
- int len = chars.length;
-
- while (len > 0) {
- if (!Character.isWhitespace(chars[len - 1])) {
- break;
- }
- len--;
- }
-
- final byte[] data = pLine.substring(0, len).getBytes("UTF-8");
-
- if (pArmoredOutput != null) {
- pArmoredOutput.write(data);
- }
- pSignatureGenerator.update(data);
- }
-
- private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput,
- final PGPV3SignatureGenerator pSignatureGenerator)
- throws IOException, SignatureException {
-
- if (pLine == null) {
- return;
- }
-
- final char[] chars = pLine.toCharArray();
- int len = chars.length;
-
- while (len > 0) {
- if (!Character.isWhitespace(chars[len - 1])) {
- break;
- }
- len--;
- }
-
- final byte[] data = pLine.substring(0, len).getBytes("UTF-8");
-
- if (pArmoredOutput != null) {
- pArmoredOutput.write(data);
- }
- pSignatureGenerator.update(data);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpToX509.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpToX509.java
deleted file mode 100644
index 5bb1665b6..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpToX509.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.pgp;
-
-import org.spongycastle.asn1.DERObjectIdentifier;
-import org.spongycastle.asn1.x509.AuthorityKeyIdentifier;
-import org.spongycastle.asn1.x509.BasicConstraints;
-import org.spongycastle.asn1.x509.GeneralName;
-import org.spongycastle.asn1.x509.GeneralNames;
-import org.spongycastle.asn1.x509.SubjectKeyIdentifier;
-import org.spongycastle.asn1.x509.X509Extensions;
-import org.spongycastle.asn1.x509.X509Name;
-import org.spongycastle.openpgp.PGPException;
-import org.spongycastle.openpgp.PGPPrivateKey;
-import org.spongycastle.openpgp.PGPPublicKey;
-import org.spongycastle.openpgp.PGPSecretKey;
-import org.spongycastle.x509.X509V3CertificateGenerator;
-import org.spongycastle.x509.extension.AuthorityKeyIdentifierStructure;
-import org.spongycastle.x509.extension.SubjectKeyIdentifierStructure;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.SignatureException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.text.DateFormat;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.Vector;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
-
-public class PgpToX509 {
- public static final String DN_COMMON_PART_O = "OpenPGP to X.509 Bridge";
- public static final String DN_COMMON_PART_OU = "OpenPGP Keychain cert";
-
- /**
- * Creates a self-signed certificate from a public and private key. The (critical) key-usage
- * extension is set up with: digital signature, non-repudiation, key-encipherment, key-agreement
- * and certificate-signing. The (non-critical) Netscape extension is set up with: SSL client and
- * S/MIME. A URI subjectAltName may also be set up.
- *
- * @param pubKey public key
- * @param privKey private key
- * @param subject subject (and issuer) DN for this certificate, RFC 2253 format preferred.
- * @param startDate date from which the certificate will be valid (defaults to current date and time
- * if null)
- * @param endDate date until which the certificate will be valid (defaults to current date and time
- * if null) *
- * @param subjAltNameURI URI to be placed in subjectAltName
- * @return self-signed certificate
- * @throws InvalidKeyException
- * @throws SignatureException
- * @throws NoSuchAlgorithmException
- * @throws IllegalStateException
- * @throws NoSuchProviderException
- * @throws CertificateException
- * @throws Exception
- * @author Bruno Harbulot
- */
- public static X509Certificate createSelfSignedCert(
- PublicKey pubKey, PrivateKey privKey, X509Name subject, Date startDate, Date endDate,
- String subjAltNameURI)
- throws InvalidKeyException, IllegalStateException, NoSuchAlgorithmException,
- SignatureException, CertificateException, NoSuchProviderException {
-
- X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator();
-
- certGenerator.reset();
- /*
- * Sets up the subject distinguished name. Since it's a self-signed certificate, issuer and
- * subject are the same.
- */
- certGenerator.setIssuerDN(subject);
- certGenerator.setSubjectDN(subject);
-
- /*
- * Sets up the validity dates.
- */
- if (startDate == null) {
- startDate = new Date(System.currentTimeMillis());
- }
- certGenerator.setNotBefore(startDate);
- if (endDate == null) {
- endDate = new Date(startDate.getTime() + (365L * 24L * 60L * 60L * 1000L));
- Log.d(Constants.TAG, "end date is=" + DateFormat.getDateInstance().format(endDate));
- }
-
- certGenerator.setNotAfter(endDate);
-
- /*
- * The serial-number of this certificate is 1. It makes sense because it's self-signed.
- */
- certGenerator.setSerialNumber(BigInteger.ONE);
- /*
- * Sets the public-key to embed in this certificate.
- */
- certGenerator.setPublicKey(pubKey);
- /*
- * Sets the signature algorithm.
- */
- String pubKeyAlgorithm = pubKey.getAlgorithm();
- if (pubKeyAlgorithm.equals("DSA")) {
- certGenerator.setSignatureAlgorithm("SHA1WithDSA");
- } else if (pubKeyAlgorithm.equals("RSA")) {
- certGenerator.setSignatureAlgorithm("SHA1WithRSAEncryption");
- } else {
- RuntimeException re = new RuntimeException("Algorithm not recognised: "
- + pubKeyAlgorithm);
- Log.e(Constants.TAG, re.getMessage(), re);
- throw re;
- }
-
- /*
- * Adds the Basic Constraint (CA: true) extension.
- */
- certGenerator.addExtension(X509Extensions.BasicConstraints, true,
- new BasicConstraints(true));
-
- /*
- * Adds the subject key identifier extension.
- */
- SubjectKeyIdentifier subjectKeyIdentifier = new SubjectKeyIdentifierStructure(pubKey);
- certGenerator
- .addExtension(X509Extensions.SubjectKeyIdentifier, false, subjectKeyIdentifier);
-
- /*
- * Adds the authority key identifier extension.
- */
- AuthorityKeyIdentifier authorityKeyIdentifier = new AuthorityKeyIdentifierStructure(pubKey);
- certGenerator.addExtension(X509Extensions.AuthorityKeyIdentifier, false,
- authorityKeyIdentifier);
-
- /*
- * Adds the subject alternative-name extension.
- */
- if (subjAltNameURI != null) {
- GeneralNames subjectAltNames = new GeneralNames(new GeneralName(
- GeneralName.uniformResourceIdentifier, subjAltNameURI));
- certGenerator.addExtension(X509Extensions.SubjectAlternativeName, false,
- subjectAltNames);
- }
-
- /*
- * Creates and sign this certificate with the private key corresponding to the public key of
- * the certificate (hence the name "self-signed certificate").
- */
- X509Certificate cert = certGenerator.generate(privKey);
-
- /*
- * Checks that this certificate has indeed been correctly signed.
- */
- cert.verify(pubKey);
-
- return cert;
- }
-
- /**
- * Creates a self-signed certificate from a PGP Secret Key.
- *
- * @param pgpSecKey PGP Secret Key (from which one can extract the public and private
- * keys and other attributes).
- * @param pgpPrivKey PGP Private Key corresponding to the Secret Key (password callbacks
- * should be done before calling this method)
- * @param subjAltNameURI optional URI to embed in the subject alternative-name
- * @return self-signed certificate
- * @throws PGPException
- * @throws NoSuchProviderException
- * @throws InvalidKeyException
- * @throws NoSuchAlgorithmException
- * @throws SignatureException
- * @throws CertificateException
- * @author Bruno Harbulot
- */
- public static X509Certificate createSelfSignedCert(
- PGPSecretKey pgpSecKey, PGPPrivateKey pgpPrivKey, String subjAltNameURI)
- throws PGPException, NoSuchProviderException, InvalidKeyException, NoSuchAlgorithmException,
- SignatureException, CertificateException {
- // get public key from secret key
- PGPPublicKey pgpPubKey = pgpSecKey.getPublicKey();
-
- // LOGGER.info("Key ID: " + Long.toHexString(pgpPubKey.getKeyID() & 0xffffffffL));
-
- /*
- * The X.509 Name to be the subject DN is prepared. The CN is extracted from the Secret Key
- * user ID.
- */
- Vector<DERObjectIdentifier> x509NameOids = new Vector<DERObjectIdentifier>();
- Vector<String> x509NameValues = new Vector<String>();
-
- x509NameOids.add(X509Name.O);
- x509NameValues.add(DN_COMMON_PART_O);
-
- x509NameOids.add(X509Name.OU);
- x509NameValues.add(DN_COMMON_PART_OU);
-
- for (@SuppressWarnings("unchecked")
- Iterator<Object> it = (Iterator<Object>) pgpSecKey.getUserIDs(); it.hasNext(); ) {
- Object attrib = it.next();
- x509NameOids.add(X509Name.CN);
- x509NameValues.add("CryptoCall");
- // x509NameValues.add(attrib.toString());
- }
-
- /*
- * Currently unused.
- */
- Log.d(Constants.TAG, "User attributes: ");
- for (@SuppressWarnings("unchecked")
- Iterator<Object> it = (Iterator<Object>) pgpSecKey.getUserAttributes(); it.hasNext(); ) {
- Object attrib = it.next();
- Log.d(Constants.TAG, " - " + attrib + " -- " + attrib.getClass());
- }
-
- X509Name x509name = new X509Name(x509NameOids, x509NameValues);
-
- Log.d(Constants.TAG, "Subject DN: " + x509name);
-
- /*
- * To check the signature from the certificate on the recipient side, the creation time
- * needs to be embedded in the certificate. It seems natural to make this creation time be
- * the "not-before" date of the X.509 certificate. Unlimited PGP keys have a validity of 0
- * second. In this case, the "not-after" date will be the same as the not-before date. This
- * is something that needs to be checked by the service receiving this certificate.
- */
- Date creationTime = pgpPubKey.getCreationTime();
- Log.d(Constants.TAG,
- "pgp pub key creation time=" + DateFormat.getDateInstance().format(creationTime));
- Log.d(Constants.TAG, "pgp valid seconds=" + pgpPubKey.getValidSeconds());
- Date validTo = null;
- if (pgpPubKey.getValidSeconds() > 0) {
- validTo = new Date(creationTime.getTime() + 1000L * pgpPubKey.getValidSeconds());
- }
-
- X509Certificate selfSignedCert = createSelfSignedCert(
- pgpPubKey.getKey(Constants.BOUNCY_CASTLE_PROVIDER_NAME), pgpPrivKey.getKey(),
- x509name, creationTime, validTo, subjAltNameURI);
-
- return selfSignedCert;
- }
-
- /**
- * This is a password callback handler that will fill in a password automatically. Useful to
- * configure passwords in advance, but should be used with caution depending on how much you
- * allow passwords to be stored within your application.
- *
- * @author Bruno Harbulot.
- */
- public static final class PredefinedPasswordCallbackHandler implements CallbackHandler {
-
- private char[] mPassword;
- private String mPrompt;
-
- public PredefinedPasswordCallbackHandler(String password) {
- this(password == null ? null : password.toCharArray(), null);
- }
-
- public PredefinedPasswordCallbackHandler(char[] password) {
- this(password, null);
- }
-
- public PredefinedPasswordCallbackHandler(String password, String prompt) {
- this(password == null ? null : password.toCharArray(), prompt);
- }
-
- public PredefinedPasswordCallbackHandler(char[] password, String prompt) {
- this.mPassword = password;
- this.mPrompt = prompt;
- }
-
- public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
- for (Callback callback : callbacks) {
- if (callback instanceof PasswordCallback) {
- PasswordCallback pwCallback = (PasswordCallback) callback;
- if ((this.mPrompt == null) || (this.mPrompt.equals(pwCallback.getPrompt()))) {
- pwCallback.setPassword(this.mPassword);
- }
- } else {
- throw new UnsupportedCallbackException(callback, "Unrecognised callback.");
- }
- }
- }
-
- protected final Object clone() throws CloneNotSupportedException {
- throw new CloneNotSupportedException();
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/NoAsymmetricEncryptionException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/NoAsymmetricEncryptionException.java
deleted file mode 100644
index 23c4bbbd9..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/NoAsymmetricEncryptionException.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.pgp.exception;
-
-public class NoAsymmetricEncryptionException extends Exception {
- static final long serialVersionUID = 0xf812773343L;
-
- public NoAsymmetricEncryptionException() {
- super();
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralException.java
deleted file mode 100644
index 418445367..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.pgp.exception;
-
-public class PgpGeneralException extends Exception {
- static final long serialVersionUID = 0xf812773342L;
-
- public PgpGeneralException(String message) {
- super(message);
- }
- public PgpGeneralException(String message, Throwable cause) {
- super(message, cause);
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralMsgIdException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralMsgIdException.java
deleted file mode 100644
index caa7842db..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralMsgIdException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.pgp.exception;
-
-import android.content.Context;
-
-public class PgpGeneralMsgIdException extends Exception {
- static final long serialVersionUID = 0xf812773343L;
-
- private final int mMessageId;
-
- public PgpGeneralMsgIdException(int messageId) {
- super("msg[" + messageId + "]");
- mMessageId = messageId;
- }
-
- public PgpGeneralException getContextualized(Context context) {
- return new PgpGeneralException(context.getString(mMessageId), this);
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java
deleted file mode 100644
index fc25faecd..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.provider;
-
-import android.net.Uri;
-import android.provider.BaseColumns;
-
-import org.sufficientlysecure.keychain.Constants;
-
-public class KeychainContract {
-
- interface KeyRingsColumns {
- String MASTER_KEY_ID = "master_key_id"; // not a database id
- String KEY_RING_DATA = "key_ring_data"; // PGPPublicKeyRing / PGPSecretKeyRing blob
- }
-
- interface KeysColumns {
- String MASTER_KEY_ID = "master_key_id"; // not a database id
- String RANK = "rank";
-
- String KEY_ID = "key_id"; // not a database id
- String ALGORITHM = "algorithm";
- String FINGERPRINT = "fingerprint";
-
- String KEY_SIZE = "key_size";
- String CAN_SIGN = "can_sign";
- String CAN_ENCRYPT = "can_encrypt";
- String CAN_CERTIFY = "can_certify";
- String IS_REVOKED = "is_revoked";
-
- String CREATION = "creation";
- String EXPIRY = "expiry";
- }
-
- interface UserIdsColumns {
- String MASTER_KEY_ID = "master_key_id"; // foreign key to key_rings._ID
- String USER_ID = "user_id"; // not a database id
- String RANK = "rank"; // ONLY used for sorting! no key, no nothing!
- String IS_PRIMARY = "is_primary";
- String IS_REVOKED = "is_revoked";
- }
-
- interface CertsColumns {
- String MASTER_KEY_ID = "master_key_id";
- String RANK = "rank";
- String KEY_ID_CERTIFIER = "key_id_certifier";
- String TYPE = "type";
- String VERIFIED = "verified";
- String CREATION = "creation";
- String DATA = "data";
- }
-
- interface ApiAppsColumns {
- String PACKAGE_NAME = "package_name";
- String PACKAGE_SIGNATURE = "package_signature";
- }
-
- interface ApiAppsAccountsColumns {
- String ACCOUNT_NAME = "account_name";
- String KEY_ID = "key_id"; // not a database id
- String ENCRYPTION_ALGORITHM = "encryption_algorithm";
- String HASH_ALORITHM = "hash_algorithm";
- String COMPRESSION = "compression";
- String PACKAGE_NAME = "package_name"; // foreign key to api_apps.package_name
- }
-
- public static final class KeyTypes {
- public static final int PUBLIC = 0;
- public static final int SECRET = 1;
- }
-
- public static final String CONTENT_AUTHORITY = Constants.PACKAGE_NAME + ".provider";
-
- private static final Uri BASE_CONTENT_URI_INTERNAL = Uri
- .parse("content://" + CONTENT_AUTHORITY);
-
- public static final String BASE_KEY_RINGS = "key_rings";
- public static final String BASE_DATA = "data";
-
- public static final String PATH_UNIFIED = "unified";
-
- public static final String PATH_FIND = "find";
- public static final String PATH_BY_EMAIL = "email";
- public static final String PATH_BY_SUBKEY = "subkey";
-
- public static final String PATH_PUBLIC = "public";
- public static final String PATH_SECRET = "secret";
- public static final String PATH_USER_IDS = "user_ids";
- public static final String PATH_KEYS = "keys";
- public static final String PATH_CERTS = "certs";
-
- public static final String BASE_API_APPS = "api_apps";
- public static final String PATH_ACCOUNTS = "accounts";
-
- public static class KeyRings implements BaseColumns, KeysColumns, UserIdsColumns {
- public static final String MASTER_KEY_ID = KeysColumns.MASTER_KEY_ID;
- public static final String IS_REVOKED = KeysColumns.IS_REVOKED;
- public static final String VERIFIED = CertsColumns.VERIFIED;
- public static final String HAS_SECRET = "has_secret";
-
- public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
- .appendPath(BASE_KEY_RINGS).build();
-
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.key_ring";
- public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.key_ring";
-
- public static Uri buildUnifiedKeyRingsUri() {
- return CONTENT_URI.buildUpon().appendPath(PATH_UNIFIED).build();
- }
-
- public static Uri buildGenericKeyRingUri(String masterKeyId) {
- return CONTENT_URI.buildUpon().appendPath(masterKeyId).build();
- }
- public static Uri buildUnifiedKeyRingUri(String masterKeyId) {
- return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_UNIFIED).build();
- }
- public static Uri buildUnifiedKeyRingUri(Uri uri) {
- return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_UNIFIED).build();
- }
-
- public static Uri buildUnifiedKeyRingsFindByEmailUri(String email) {
- return CONTENT_URI.buildUpon().appendPath(PATH_FIND).appendPath(PATH_BY_EMAIL).appendPath(email).build();
- }
- public static Uri buildUnifiedKeyRingsFindBySubkeyUri(String subkey) {
- return CONTENT_URI.buildUpon().appendPath(PATH_FIND).appendPath(PATH_BY_SUBKEY).appendPath(subkey).build();
- }
-
- }
-
- public static class KeyRingData implements KeyRingsColumns, BaseColumns {
- public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
- .appendPath(BASE_KEY_RINGS).build();
-
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.key_ring_data";
- public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.key_ring_data";
-
- public static Uri buildPublicKeyRingUri() {
- return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).build();
- }
- public static Uri buildPublicKeyRingUri(String masterKeyId) {
- return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_PUBLIC).build();
- }
- public static Uri buildPublicKeyRingUri(Uri uri) {
- return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_PUBLIC).build();
- }
-
- public static Uri buildSecretKeyRingUri() {
- return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).build();
- }
- public static Uri buildSecretKeyRingUri(String masterKeyId) {
- return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_SECRET).build();
- }
- public static Uri buildSecretKeyRingUri(Uri uri) {
- return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_SECRET).build();
- }
-
- }
-
- public static class Keys implements KeysColumns, BaseColumns {
- public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
- .appendPath(BASE_KEY_RINGS).build();
-
- /**
- * Use if multiple items get returned
- */
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.key";
-
- /**
- * Use if a single item is returned
- */
- public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.key";
-
- public static Uri buildKeysUri(String masterKeyId) {
- return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_KEYS).build();
- }
- public static Uri buildKeysUri(Uri uri) {
- return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_KEYS).build();
- }
-
- }
-
- public static class UserIds implements UserIdsColumns, BaseColumns {
- public static final String VERIFIED = "verified";
- public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
- .appendPath(BASE_KEY_RINGS).build();
-
- /**
- * Use if multiple items get returned
- */
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.user_id";
-
- /**
- * Use if a single item is returned
- */
- public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.user_id";
-
- public static Uri buildUserIdsUri(String masterKeyId) {
- return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_USER_IDS).build();
- }
- public static Uri buildUserIdsUri(Uri uri) {
- return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_USER_IDS).build();
- }
- }
-
- public static class ApiApps implements ApiAppsColumns, BaseColumns {
- public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
- .appendPath(BASE_API_APPS).build();
-
- /**
- * Use if multiple items get returned
- */
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.api_apps";
-
- /**
- * Use if a single item is returned
- */
- public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.api_app";
-
- public static Uri buildByPackageNameUri(String packageName) {
- return CONTENT_URI.buildUpon().appendEncodedPath(packageName).build();
- }
- }
-
- public static class ApiAccounts implements ApiAppsAccountsColumns, BaseColumns {
- public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
- .appendPath(BASE_API_APPS).build();
-
- /**
- * Use if multiple items get returned
- */
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.api_app.accounts";
-
- /**
- * Use if a single item is returned
- */
- public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.api_app.account";
-
- public static Uri buildBaseUri(String packageName) {
- return CONTENT_URI.buildUpon().appendEncodedPath(packageName).appendPath(PATH_ACCOUNTS)
- .build();
- }
-
- public static Uri buildByPackageAndAccountUri(String packageName, String accountName) {
- return CONTENT_URI.buildUpon().appendEncodedPath(packageName).appendPath(PATH_ACCOUNTS)
- .appendEncodedPath(accountName).build();
- }
- }
-
- public static class Certs implements CertsColumns, BaseColumns {
- public static final String USER_ID = UserIdsColumns.USER_ID;
- public static final String SIGNER_UID = "signer_user_id";
-
- public static final int VERIFIED_SECRET = 1;
- public static final int VERIFIED_SELF = 2;
-
- public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
- .appendPath(BASE_KEY_RINGS).build();
-
- public static Uri buildCertsUri(String masterKeyId) {
- return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_CERTS).build();
- }
- public static Uri buildCertsSpecificUri(String masterKeyId, String rank, String certifier) {
- return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_CERTS).appendPath(rank).appendPath(certifier).build();
- }
- public static Uri buildCertsUri(Uri uri) {
- return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_CERTS).build();
- }
-
- }
-
- public static class DataStream {
- public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
- .appendPath(BASE_DATA).build();
-
- public static Uri buildDataStreamUri(String streamFilename) {
- return CONTENT_URI.buildUpon().appendPath(streamFilename).build();
- }
- }
-
- private KeychainContract() {
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java
deleted file mode 100644
index 8674ad94b..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.provider;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.provider.BaseColumns;
-
-import org.spongycastle.openpgp.PGPKeyRing;
-import org.spongycastle.openpgp.PGPPublicKeyRing;
-import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsColumns;
-import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsAccountsColumns;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeysColumns;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIdsColumns;
-import org.sufficientlysecure.keychain.provider.KeychainContract.CertsColumns;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.io.IOException;
-
-public class KeychainDatabase extends SQLiteOpenHelper {
- private static final String DATABASE_NAME = "openkeychain.db";
- private static final int DATABASE_VERSION = 1;
- static Boolean apgHack = false;
-
- public interface Tables {
- String KEY_RINGS_PUBLIC = "keyrings_public";
- String KEY_RINGS_SECRET = "keyrings_secret";
- String KEYS = "keys";
- String USER_IDS = "user_ids";
- String CERTS = "certs";
- String API_APPS = "api_apps";
- String API_ACCOUNTS = "api_accounts";
- }
-
- private static final String CREATE_KEYRINGS_PUBLIC =
- "CREATE TABLE IF NOT EXISTS keyrings_public ("
- + KeyRingsColumns.MASTER_KEY_ID + " INTEGER PRIMARY KEY,"
- + KeyRingsColumns.KEY_RING_DATA + " BLOB"
- + ")";
-
- private static final String CREATE_KEYRINGS_SECRET =
- "CREATE TABLE IF NOT EXISTS keyrings_secret ("
- + KeyRingsColumns.MASTER_KEY_ID + " INTEGER PRIMARY KEY,"
- + KeyRingsColumns.KEY_RING_DATA + " BLOB,"
- + "FOREIGN KEY(" + KeyRingsColumns.MASTER_KEY_ID + ") "
- + "REFERENCES keyrings_public(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE"
- + ")";
-
- private static final String CREATE_KEYS =
- "CREATE TABLE IF NOT EXISTS " + Tables.KEYS + " ("
- + KeysColumns.MASTER_KEY_ID + " INTEGER, "
- + KeysColumns.RANK + " INTEGER, "
-
- + KeysColumns.KEY_ID + " INTEGER, "
- + KeysColumns.KEY_SIZE + " INTEGER, "
- + KeysColumns.ALGORITHM + " INTEGER, "
- + KeysColumns.FINGERPRINT + " BLOB, "
-
- + KeysColumns.CAN_CERTIFY + " BOOLEAN, "
- + KeysColumns.CAN_SIGN + " BOOLEAN, "
- + KeysColumns.CAN_ENCRYPT + " BOOLEAN, "
- + KeysColumns.IS_REVOKED + " BOOLEAN, "
-
- + KeysColumns.CREATION + " INTEGER, "
- + KeysColumns.EXPIRY + " INTEGER, "
-
- + "PRIMARY KEY(" + KeysColumns.MASTER_KEY_ID + ", " + KeysColumns.RANK + "),"
- + "FOREIGN KEY(" + KeysColumns.MASTER_KEY_ID + ") REFERENCES "
- + Tables.KEY_RINGS_PUBLIC + "(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE"
- + ")";
-
- private static final String CREATE_USER_IDS =
- "CREATE TABLE IF NOT EXISTS " + Tables.USER_IDS + "("
- + UserIdsColumns.MASTER_KEY_ID + " INTEGER, "
- + UserIdsColumns.USER_ID + " CHARMANDER, "
-
- + UserIdsColumns.IS_PRIMARY + " BOOLEAN, "
- + UserIdsColumns.IS_REVOKED + " BOOLEAN, "
- + UserIdsColumns.RANK+ " INTEGER, "
-
- + "PRIMARY KEY(" + UserIdsColumns.MASTER_KEY_ID + ", " + UserIdsColumns.USER_ID + "), "
- + "UNIQUE (" + UserIdsColumns.MASTER_KEY_ID + ", " + UserIdsColumns.RANK + "), "
- + "FOREIGN KEY(" + UserIdsColumns.MASTER_KEY_ID + ") REFERENCES "
- + Tables.KEY_RINGS_PUBLIC + "(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE"
- + ")";
-
- private static final String CREATE_CERTS =
- "CREATE TABLE IF NOT EXISTS " + Tables.CERTS + "("
- + CertsColumns.MASTER_KEY_ID + " INTEGER,"
- + CertsColumns.RANK + " INTEGER, " // rank of certified uid
-
- + CertsColumns.KEY_ID_CERTIFIER + " INTEGER, " // certifying key
- + CertsColumns.TYPE + " INTEGER, "
- + CertsColumns.VERIFIED + " INTEGER, "
- + CertsColumns.CREATION + " INTEGER, "
-
- + CertsColumns.DATA + " BLOB, "
-
- + "PRIMARY KEY(" + CertsColumns.MASTER_KEY_ID + ", " + CertsColumns.RANK + ", "
- + CertsColumns.KEY_ID_CERTIFIER + "), "
- + "FOREIGN KEY(" + CertsColumns.MASTER_KEY_ID + ") REFERENCES "
- + Tables.KEY_RINGS_PUBLIC + "(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE,"
- + "FOREIGN KEY(" + CertsColumns.MASTER_KEY_ID + ", " + CertsColumns.RANK + ") REFERENCES "
- + Tables.USER_IDS + "(" + UserIdsColumns.MASTER_KEY_ID + ", " + UserIdsColumns.RANK + ") ON DELETE CASCADE"
- + ")";
-
- private static final String CREATE_API_APPS = "CREATE TABLE IF NOT EXISTS " + Tables.API_APPS
- + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
- + ApiAppsColumns.PACKAGE_NAME + " TEXT NOT NULL UNIQUE, "
- + ApiAppsColumns.PACKAGE_SIGNATURE + " BLOB)";
-
- private static final String CREATE_API_APPS_ACCOUNTS = "CREATE TABLE IF NOT EXISTS " + Tables.API_ACCOUNTS
- + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
- + ApiAppsAccountsColumns.ACCOUNT_NAME + " TEXT NOT NULL, "
- + ApiAppsAccountsColumns.KEY_ID + " INT64, "
- + ApiAppsAccountsColumns.ENCRYPTION_ALGORITHM + " INTEGER, "
- + ApiAppsAccountsColumns.HASH_ALORITHM + " INTEGER, "
- + ApiAppsAccountsColumns.COMPRESSION + " INTEGER, "
- + ApiAppsAccountsColumns.PACKAGE_NAME + " TEXT NOT NULL, "
- + "UNIQUE(" + ApiAppsAccountsColumns.ACCOUNT_NAME + ", "
- + ApiAppsAccountsColumns.PACKAGE_NAME + "), "
- + "FOREIGN KEY(" + ApiAppsAccountsColumns.PACKAGE_NAME + ") REFERENCES "
- + Tables.API_APPS + "(" + ApiAppsColumns.PACKAGE_NAME + ") ON DELETE CASCADE)";
-
- KeychainDatabase(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
-
- // make sure this is only done once, on the first instance!
- boolean iAmIt = false;
- synchronized(apgHack) {
- if(!apgHack) {
- iAmIt = true;
- apgHack = true;
- }
- }
- // if it's us, do the import
- if(iAmIt)
- checkAndImportApg(context);
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- Log.w(Constants.TAG, "Creating database...");
-
- db.execSQL(CREATE_KEYRINGS_PUBLIC);
- db.execSQL(CREATE_KEYRINGS_SECRET);
- db.execSQL(CREATE_KEYS);
- db.execSQL(CREATE_USER_IDS);
- db.execSQL(CREATE_CERTS);
- db.execSQL(CREATE_API_APPS);
- db.execSQL(CREATE_API_APPS_ACCOUNTS);
- }
-
- @Override
- public void onOpen(SQLiteDatabase db) {
- super.onOpen(db);
- if (!db.isReadOnly()) {
- // Enable foreign key constraints
- db.execSQL("PRAGMA foreign_keys=ON;");
- // TODO remove, once we remove the "always migrate" debug stuff
- // db.execSQL("DROP TABLE certs;");
- // db.execSQL("DROP TABLE user_ids;");
- db.execSQL(CREATE_USER_IDS);
- db.execSQL(CREATE_CERTS);
- }
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int old, int nu) {
- // don't care (this is version 1)
- }
-
- /** This method tries to import data from a provided database.
- *
- * The sole assumptions made on this db are that there is a key_rings table
- * with a key_ring_data, a master_key_id and a type column, the latter of
- * which should be 1 for secret keys and 0 for public keys.
- */
- public void checkAndImportApg(Context context) {
-
- boolean hasApgDb = false; {
- // It's the Java way =(
- String[] dbs = context.databaseList();
- for(String db : dbs) {
- if(db.equals("apg.db")) {
- hasApgDb = true;
- break;
- }
- }
- }
-
- if(!hasApgDb)
- return;
-
- Log.d(Constants.TAG, "apg.db exists! Importing...");
-
- SQLiteDatabase db = new SQLiteOpenHelper(context, "apg.db", null, 1) {
- @Override
- public void onCreate(SQLiteDatabase db) {
- // should never happen
- assert false;
- }
- @Override
- public void onDowngrade(SQLiteDatabase db, int old, int nu) {
- // don't care
- }
- @Override
- public void onUpgrade(SQLiteDatabase db, int old, int nu) {
- // don't care either
- }
- }.getReadableDatabase();
-
- // kill current!
- { // TODO don't kill current.
- Log.d(Constants.TAG, "Truncating db...");
- SQLiteDatabase d = getWritableDatabase();
- d.execSQL("DELETE FROM keyrings_public");
- d.close();
- Log.d(Constants.TAG, "Ok.");
- }
-
- Cursor c = null;
- try {
- // we insert in two steps: first, all public keys that have secret keys
- c = db.rawQuery("SELECT key_ring_data FROM key_rings WHERE type = 1 OR EXISTS ("
- + " SELECT 1 FROM key_rings d2 WHERE key_rings.master_key_id = d2.master_key_id"
- + " AND d2.type = 1) ORDER BY type ASC", null);
- Log.d(Constants.TAG, "Importing " + c.getCount() + " secret keyrings from apg.db...");
- for(int i = 0; i < c.getCount(); i++) {
- c.moveToPosition(i);
- byte[] data = c.getBlob(0);
- PGPKeyRing ring = PgpConversionHelper.BytesToPGPKeyRing(data);
- if(ring instanceof PGPPublicKeyRing)
- ProviderHelper.saveKeyRing(context, (PGPPublicKeyRing) ring);
- else if(ring instanceof PGPSecretKeyRing)
- ProviderHelper.saveKeyRing(context, (PGPSecretKeyRing) ring);
- else {
- Log.e(Constants.TAG, "Unknown blob data type!");
- }
- }
-
- // afterwards, insert all keys, starting with public keys that have secret keys, then
- // secret keys, then all others. this order is necessary to ensure all certifications
- // are recognized properly.
- c = db.rawQuery("SELECT key_ring_data FROM key_rings ORDER BY (type = 0 AND EXISTS ("
- + " SELECT 1 FROM key_rings d2 WHERE key_rings.master_key_id = d2.master_key_id AND"
- + " d2.type = 1)) DESC, type DESC", null);
- // import from old database
- Log.d(Constants.TAG, "Importing " + c.getCount() + " keyrings from apg.db...");
- for(int i = 0; i < c.getCount(); i++) {
- c.moveToPosition(i);
- byte[] data = c.getBlob(0);
- PGPKeyRing ring = PgpConversionHelper.BytesToPGPKeyRing(data);
- if(ring instanceof PGPPublicKeyRing)
- ProviderHelper.saveKeyRing(context, (PGPPublicKeyRing) ring);
- else if(ring instanceof PGPSecretKeyRing)
- ProviderHelper.saveKeyRing(context, (PGPSecretKeyRing) ring);
- else {
- Log.e(Constants.TAG, "Unknown blob data type!");
- }
- }
-
- } catch(IOException e) {
- Log.e(Constants.TAG, "Error importing apg db!", e);
- return;
- } finally {
- if(c != null)
- c.close();
- if(db != null)
- db.close();
- }
-
- // TODO delete old db, if we are sure this works
- // context.deleteDatabase("apg.db");
- Log.d(Constants.TAG, "All done, (not) deleting apg.db");
-
-
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
deleted file mode 100644
index 9b9e4991d..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
+++ /dev/null
@@ -1,752 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.provider;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.content.UriMatcher;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteConstraintException;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteQueryBuilder;
-import android.net.Uri;
-import android.text.TextUtils;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAccounts;
-import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
-import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
-import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
-import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.util.Arrays;
-import java.util.HashMap;
-
-public class KeychainProvider extends ContentProvider {
-
- private static final int KEY_RINGS_UNIFIED = 101;
- private static final int KEY_RINGS_PUBLIC = 102;
- private static final int KEY_RINGS_SECRET = 103;
-
- private static final int KEY_RING_UNIFIED = 200;
- private static final int KEY_RING_KEYS = 201;
- private static final int KEY_RING_USER_IDS = 202;
- private static final int KEY_RING_PUBLIC = 203;
- private static final int KEY_RING_SECRET = 204;
- private static final int KEY_RING_CERTS = 205;
- private static final int KEY_RING_CERTS_SPECIFIC = 206;
-
- private static final int API_APPS = 301;
- private static final int API_APPS_BY_PACKAGE_NAME = 303;
- private static final int API_ACCOUNTS = 304;
- private static final int API_ACCOUNTS_BY_ACCOUNT_NAME = 306;
-
- private static final int KEY_RINGS_FIND_BY_EMAIL = 400;
- private static final int KEY_RINGS_FIND_BY_SUBKEY = 401;
-
- // private static final int DATA_STREAM = 501;
-
- protected UriMatcher mUriMatcher;
-
- /**
- * Build and return a {@link UriMatcher} that catches all {@link Uri} variations supported by
- * this {@link ContentProvider}.
- */
- protected UriMatcher buildUriMatcher() {
- final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
-
- String authority = KeychainContract.CONTENT_AUTHORITY;
-
- /**
- * list key_rings
- *
- * <pre>
- * key_rings/unified
- * key_rings/public
- * </pre>
- */
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS
- + "/" + KeychainContract.PATH_UNIFIED,
- KEY_RINGS_UNIFIED);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS
- + "/" + KeychainContract.PATH_PUBLIC,
- KEY_RINGS_PUBLIC);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS
- + "/" + KeychainContract.PATH_SECRET,
- KEY_RINGS_SECRET);
-
- /**
- * find by criteria other than master key id
- *
- * key_rings/find/email/_
- * key_rings/find/subkey/_
- *
- */
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
- + KeychainContract.PATH_FIND + "/" + KeychainContract.PATH_BY_EMAIL + "/*",
- KEY_RINGS_FIND_BY_EMAIL);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
- + KeychainContract.PATH_FIND + "/" + KeychainContract.PATH_BY_SUBKEY + "/*",
- KEY_RINGS_FIND_BY_SUBKEY);
-
- /**
- * list key_ring specifics
- *
- * <pre>
- * key_rings/_/unified
- * key_rings/_/keys
- * key_rings/_/user_ids
- * key_rings/_/public
- * key_rings/_/secret
- * key_rings/_/certs
- * key_rings/_/certs/_/_
- * </pre>
- */
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/"
- + KeychainContract.PATH_UNIFIED,
- KEY_RING_UNIFIED);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/"
- + KeychainContract.PATH_KEYS,
- KEY_RING_KEYS);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/"
- + KeychainContract.PATH_USER_IDS,
- KEY_RING_USER_IDS);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/"
- + KeychainContract.PATH_PUBLIC,
- KEY_RING_PUBLIC);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/"
- + KeychainContract.PATH_SECRET,
- KEY_RING_SECRET);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/"
- + KeychainContract.PATH_CERTS,
- KEY_RING_CERTS);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/"
- + KeychainContract.PATH_CERTS + "/*/*",
- KEY_RING_CERTS_SPECIFIC);
-
- /**
- * API apps
- *
- * <pre>
- * api_apps
- * api_apps/_ (package name)
- *
- * api_apps/_/accounts
- * api_apps/_/accounts/_ (account name)
- * </pre>
- */
- matcher.addURI(authority, KeychainContract.BASE_API_APPS, API_APPS);
- matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/*", API_APPS_BY_PACKAGE_NAME);
-
- matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/*/"
- + KeychainContract.PATH_ACCOUNTS, API_ACCOUNTS);
- matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/*/"
- + KeychainContract.PATH_ACCOUNTS + "/*", API_ACCOUNTS_BY_ACCOUNT_NAME);
-
- /**
- * data stream
- *
- * <pre>
- * data / _
- * </pre>
- */
- // matcher.addURI(authority, KeychainContract.BASE_DATA + "/*", DATA_STREAM);
-
- return matcher;
- }
-
- private KeychainDatabase mKeychainDatabase;
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean onCreate() {
- mUriMatcher = buildUriMatcher();
- return true;
- }
-
- public KeychainDatabase getDb() {
- if(mKeychainDatabase == null)
- mKeychainDatabase = new KeychainDatabase(getContext());
- return mKeychainDatabase;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getType(Uri uri) {
- final int match = mUriMatcher.match(uri);
- switch (match) {
- case KEY_RING_PUBLIC:
- return KeyRings.CONTENT_ITEM_TYPE;
-
- case KEY_RING_KEYS:
- return Keys.CONTENT_TYPE;
-
- case KEY_RING_USER_IDS:
- return UserIds.CONTENT_TYPE;
-
- case KEY_RING_SECRET:
- return KeyRings.CONTENT_ITEM_TYPE;
-
- case API_APPS:
- return ApiApps.CONTENT_TYPE;
-
- case API_APPS_BY_PACKAGE_NAME:
- return ApiApps.CONTENT_ITEM_TYPE;
-
- case API_ACCOUNTS:
- return ApiAccounts.CONTENT_TYPE;
-
- case API_ACCOUNTS_BY_ACCOUNT_NAME:
- return ApiAccounts.CONTENT_ITEM_TYPE;
-
- default:
- throw new UnsupportedOperationException("Unknown uri: " + uri);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
- Log.v(Constants.TAG, "query(uri=" + uri + ", proj=" + Arrays.toString(projection) + ")");
-
- SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
-
- int match = mUriMatcher.match(uri);
-
- // all query() parameters, for good measure
- String groupBy = null, having = null;
-
- switch (match) {
- case KEY_RING_UNIFIED:
- case KEY_RINGS_UNIFIED:
- case KEY_RINGS_FIND_BY_EMAIL:
- case KEY_RINGS_FIND_BY_SUBKEY: {
- HashMap<String, String> projectionMap = new HashMap<String, String>();
- projectionMap.put(KeyRings._ID, Tables.KEYS + ".oid AS _id");
- projectionMap.put(KeyRings.MASTER_KEY_ID, Tables.KEYS + "." + Keys.MASTER_KEY_ID);
- projectionMap.put(KeyRings.KEY_ID, Keys.KEY_ID);
- projectionMap.put(KeyRings.KEY_SIZE, Keys.KEY_SIZE);
- projectionMap.put(KeyRings.IS_REVOKED, Tables.KEYS + "." + Keys.IS_REVOKED);
- projectionMap.put(KeyRings.CAN_CERTIFY, Keys.CAN_CERTIFY);
- projectionMap.put(KeyRings.CAN_ENCRYPT, Keys.CAN_ENCRYPT);
- projectionMap.put(KeyRings.CAN_SIGN, Keys.CAN_SIGN);
- projectionMap.put(KeyRings.CREATION, Tables.KEYS + "." + Keys.CREATION);
- projectionMap.put(KeyRings.EXPIRY, Keys.EXPIRY);
- projectionMap.put(KeyRings.ALGORITHM, Keys.ALGORITHM);
- projectionMap.put(KeyRings.FINGERPRINT, Keys.FINGERPRINT);
- projectionMap.put(KeyRings.USER_ID, UserIds.USER_ID);
- projectionMap.put(KeyRings.VERIFIED, KeyRings.VERIFIED);
- projectionMap.put(KeyRings.HAS_SECRET, "(" + Tables.KEY_RINGS_SECRET + "." + KeyRings.MASTER_KEY_ID + " IS NOT NULL) AS " + KeyRings.HAS_SECRET);
- qb.setProjectionMap(projectionMap);
-
- qb.setTables(
- Tables.KEYS
- + " INNER JOIN " + Tables.USER_IDS + " ON ("
- + Tables.KEYS + "." + Keys.MASTER_KEY_ID
- + " = "
- + Tables.USER_IDS + "." + UserIds.MASTER_KEY_ID
- + " AND " + Tables.USER_IDS + "." + UserIds.RANK + " = 0"
- + ") LEFT JOIN " + Tables.KEY_RINGS_SECRET + " ON ("
- + Tables.KEYS + "." + Keys.MASTER_KEY_ID
- + " = "
- + Tables.KEY_RINGS_SECRET + "." + KeyRings.MASTER_KEY_ID
- + ") LEFT JOIN " + Tables.CERTS + " ON ("
- + Tables.KEYS + "." + Keys.MASTER_KEY_ID
- + " = "
- + Tables.CERTS + "." + KeyRings.MASTER_KEY_ID
- + " AND " + Tables.CERTS + "." + Certs.VERIFIED
- + " = " + Certs.VERIFIED_SECRET
- + ")"
- );
- qb.appendWhere(Tables.KEYS + "." + Keys.RANK + " = 0");
- // in case there are multiple verifying certificates
- groupBy = Tables.KEYS + "." + Keys.MASTER_KEY_ID;
-
- switch(match) {
- case KEY_RING_UNIFIED: {
- qb.appendWhere(" AND " + Tables.KEYS + "." + Keys.MASTER_KEY_ID + " = ");
- qb.appendWhereEscapeString(uri.getPathSegments().get(1));
- break;
- }
- case KEY_RINGS_FIND_BY_SUBKEY: {
- try {
- String subkey = Long.valueOf(uri.getLastPathSegment()).toString();
- qb.appendWhere(" AND EXISTS ("
- + " SELECT 1 FROM " + Tables.KEYS + " AS tmp"
- + " WHERE tmp." + UserIds.MASTER_KEY_ID
- + " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID
- + " AND tmp." + Keys.KEY_ID + " = " + subkey + ""
- + ")");
- } catch(NumberFormatException e) {
- Log.e(Constants.TAG, "Malformed find by subkey query!", e);
- qb.appendWhere(" AND 0");
- }
- break;
- }
- case KEY_RINGS_FIND_BY_EMAIL: {
- String chunks[] = uri.getLastPathSegment().split(" *, *");
- boolean gotCondition = false;
- String emailWhere = "";
- // JAVA ♥
- for (int i = 0; i < chunks.length; ++i) {
- if (chunks[i].length() == 0) {
- continue;
- }
- if (i != 0) {
- emailWhere += " OR ";
- }
- emailWhere += "tmp." + UserIds.USER_ID + " LIKE ";
- // match '*<email>', so it has to be at the *end* of the user id
- emailWhere += DatabaseUtils.sqlEscapeString("%<" + chunks[i] + ">");
- gotCondition = true;
- }
- if(gotCondition) {
- qb.appendWhere(" AND EXISTS ("
- + " SELECT 1 FROM " + Tables.USER_IDS + " AS tmp"
- + " WHERE tmp." + UserIds.MASTER_KEY_ID
- + " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID
- + " AND (" + emailWhere + ")"
- + ")");
- } else {
- // TODO better way to do this?
- Log.e(Constants.TAG, "Malformed find by email query!");
- qb.appendWhere(" AND 0");
- }
- break;
- }
- }
-
- if (TextUtils.isEmpty(sortOrder)) {
- sortOrder =
- Tables.KEY_RINGS_SECRET + "." + KeyRings.MASTER_KEY_ID + " IS NULL ASC, "
- + Tables.USER_IDS + "." + UserIds.USER_ID + " ASC";
- }
-
- // uri to watch is all /key_rings/
- uri = KeyRings.CONTENT_URI;
-
- break;
- }
-
- case KEY_RING_KEYS: {
- HashMap<String, String> projectionMap = new HashMap<String, String>();
- projectionMap.put(Keys._ID, Tables.KEYS + ".oid AS _id");
- projectionMap.put(Keys.MASTER_KEY_ID, Tables.KEYS + "." + Keys.MASTER_KEY_ID);
- projectionMap.put(Keys.RANK, Tables.KEYS + "." + Keys.RANK);
- projectionMap.put(Keys.KEY_ID, Keys.KEY_ID);
- projectionMap.put(Keys.KEY_SIZE, Keys.KEY_SIZE);
- projectionMap.put(Keys.IS_REVOKED, Keys.IS_REVOKED);
- projectionMap.put(Keys.CAN_CERTIFY, Keys.CAN_CERTIFY);
- projectionMap.put(Keys.CAN_ENCRYPT, Keys.CAN_ENCRYPT);
- projectionMap.put(Keys.CAN_SIGN, Keys.CAN_SIGN);
- projectionMap.put(Keys.CREATION, Keys.CREATION);
- projectionMap.put(Keys.EXPIRY, Keys.EXPIRY);
- projectionMap.put(Keys.ALGORITHM, Keys.ALGORITHM);
- projectionMap.put(Keys.FINGERPRINT, Keys.FINGERPRINT);
- qb.setProjectionMap(projectionMap);
-
- qb.setTables(Tables.KEYS);
- qb.appendWhere(Keys.MASTER_KEY_ID + " = ");
- qb.appendWhereEscapeString(uri.getPathSegments().get(1));
-
- break;
- }
-
- case KEY_RING_USER_IDS: {
- HashMap<String, String> projectionMap = new HashMap<String, String>();
- projectionMap.put(UserIds._ID, Tables.USER_IDS + ".oid AS _id");
- projectionMap.put(UserIds.MASTER_KEY_ID, Tables.USER_IDS + "." + UserIds.MASTER_KEY_ID);
- projectionMap.put(UserIds.USER_ID, Tables.USER_IDS + "." + UserIds.USER_ID);
- projectionMap.put(UserIds.RANK, Tables.USER_IDS + "." + UserIds.RANK);
- projectionMap.put(UserIds.IS_PRIMARY, Tables.USER_IDS + "." + UserIds.IS_PRIMARY);
- projectionMap.put(UserIds.IS_REVOKED, Tables.USER_IDS + "." + UserIds.IS_REVOKED);
- // we take the minimum (>0) here, where "1" is "verified by known secret key"
- projectionMap.put(UserIds.VERIFIED, "MIN(" + Certs.VERIFIED + ") AS " + UserIds.VERIFIED);
- qb.setProjectionMap(projectionMap);
-
- qb.setTables(Tables.USER_IDS
- + " LEFT JOIN " + Tables.CERTS + " ON ("
- + Tables.USER_IDS + "." + UserIds.MASTER_KEY_ID + " = "
- + Tables.CERTS + "." + Certs.MASTER_KEY_ID
- + " AND " + Tables.USER_IDS + "." + UserIds.RANK + " = "
- + Tables.CERTS + "." + Certs.RANK
- + " AND " + Tables.CERTS + "." + Certs.VERIFIED + " > 0"
- + ")");
- groupBy = Tables.USER_IDS + "." + UserIds.RANK;
-
- qb.appendWhere(Tables.USER_IDS + "." + UserIds.MASTER_KEY_ID + " = ");
- qb.appendWhereEscapeString(uri.getPathSegments().get(1));
-
- if (TextUtils.isEmpty(sortOrder)) {
- sortOrder = Tables.USER_IDS + "." + UserIds.RANK + " ASC";
- }
-
- break;
-
- }
-
- case KEY_RINGS_PUBLIC:
- case KEY_RING_PUBLIC: {
- HashMap<String, String> projectionMap = new HashMap<String, String>();
- projectionMap.put(KeyRingData._ID, Tables.KEY_RINGS_PUBLIC + ".oid AS _id");
- projectionMap.put(KeyRingData.MASTER_KEY_ID, KeyRingData.MASTER_KEY_ID);
- projectionMap.put(KeyRingData.KEY_RING_DATA, KeyRingData.KEY_RING_DATA);
- qb.setProjectionMap(projectionMap);
-
- qb.setTables(Tables.KEY_RINGS_PUBLIC);
-
- if(match == KEY_RING_PUBLIC) {
- qb.appendWhere(KeyRings.MASTER_KEY_ID + " = ");
- qb.appendWhereEscapeString(uri.getPathSegments().get(1));
- }
-
- break;
- }
-
- case KEY_RINGS_SECRET:
- case KEY_RING_SECRET: {
- HashMap<String, String> projectionMap = new HashMap<String, String>();
- projectionMap.put(KeyRingData._ID, Tables.KEY_RINGS_SECRET + ".oid AS _id");
- projectionMap.put(KeyRingData.MASTER_KEY_ID, KeyRingData.MASTER_KEY_ID);
- projectionMap.put(KeyRingData.KEY_RING_DATA, KeyRingData.KEY_RING_DATA);
- qb.setProjectionMap(projectionMap);
-
- qb.setTables(Tables.KEY_RINGS_SECRET);
-
- if(match == KEY_RING_SECRET) {
- qb.appendWhere(KeyRings.MASTER_KEY_ID + " = ");
- qb.appendWhereEscapeString(uri.getPathSegments().get(1));
- }
-
- break;
- }
-
- case KEY_RING_CERTS:
- case KEY_RING_CERTS_SPECIFIC: {
- HashMap<String, String> projectionMap = new HashMap<String, String>();
- projectionMap.put(Certs._ID, Tables.CERTS + ".oid AS " + Certs._ID);
- projectionMap.put(Certs.MASTER_KEY_ID, Tables.CERTS + "." + Certs.MASTER_KEY_ID);
- projectionMap.put(Certs.RANK, Tables.CERTS + "." + Certs.RANK);
- projectionMap.put(Certs.VERIFIED, Tables.CERTS + "." + Certs.VERIFIED);
- projectionMap.put(Certs.TYPE, Tables.CERTS + "." + Certs.TYPE);
- projectionMap.put(Certs.CREATION, Tables.CERTS + "." + Certs.CREATION);
- projectionMap.put(Certs.KEY_ID_CERTIFIER, Tables.CERTS + "." + Certs.KEY_ID_CERTIFIER);
- projectionMap.put(Certs.DATA, Tables.CERTS + "." + Certs.DATA);
- projectionMap.put(Certs.USER_ID, Tables.USER_IDS + "." + UserIds.USER_ID);
- projectionMap.put(Certs.SIGNER_UID, "signer." + UserIds.USER_ID + " AS " + Certs.SIGNER_UID);
- qb.setProjectionMap(projectionMap);
-
- qb.setTables(Tables.CERTS
- + " JOIN " + Tables.USER_IDS + " ON ("
- + Tables.CERTS + "." + Certs.MASTER_KEY_ID + " = "
- + Tables.USER_IDS + "." + UserIds.MASTER_KEY_ID
- + " AND "
- + Tables.CERTS + "." + Certs.RANK + " = "
- + Tables.USER_IDS + "." + UserIds.RANK
- + ") LEFT JOIN " + Tables.USER_IDS + " AS signer ON ("
- + Tables.CERTS + "." + Certs.KEY_ID_CERTIFIER + " = "
- + "signer." + UserIds.MASTER_KEY_ID
- + " AND "
- + "signer." + Keys.RANK + " = 0"
- + ")");
-
- groupBy = Tables.CERTS + "." + Certs.RANK + ", "
- + Tables.CERTS + "." + Certs.KEY_ID_CERTIFIER;
-
- qb.appendWhere(Tables.CERTS + "." + Certs.MASTER_KEY_ID + " = ");
- qb.appendWhereEscapeString(uri.getPathSegments().get(1));
- if(match == KEY_RING_CERTS_SPECIFIC) {
- qb.appendWhere(" AND " + Tables.CERTS + "." + Certs.RANK + " = ");
- qb.appendWhereEscapeString(uri.getPathSegments().get(3));
- qb.appendWhere(" AND " + Tables.CERTS + "." + Certs.KEY_ID_CERTIFIER+ " = ");
- qb.appendWhereEscapeString(uri.getPathSegments().get(4));
- }
-
- break;
- }
-
- case API_APPS:
- qb.setTables(Tables.API_APPS);
-
- break;
- case API_APPS_BY_PACKAGE_NAME:
- qb.setTables(Tables.API_APPS);
- qb.appendWhere(ApiApps.PACKAGE_NAME + " = ");
- qb.appendWhereEscapeString(uri.getLastPathSegment());
-
- break;
- case API_ACCOUNTS:
- qb.setTables(Tables.API_ACCOUNTS);
- qb.appendWhere(Tables.API_ACCOUNTS + "." + ApiAccounts.PACKAGE_NAME + " = ");
- qb.appendWhereEscapeString(uri.getPathSegments().get(1));
-
- break;
- case API_ACCOUNTS_BY_ACCOUNT_NAME:
- qb.setTables(Tables.API_ACCOUNTS);
- qb.appendWhere(Tables.API_ACCOUNTS + "." + ApiAccounts.PACKAGE_NAME + " = ");
- qb.appendWhereEscapeString(uri.getPathSegments().get(1));
-
- qb.appendWhere(" AND " + Tables.API_ACCOUNTS + "." + ApiAccounts.ACCOUNT_NAME + " = ");
- qb.appendWhereEscapeString(uri.getLastPathSegment());
-
- break;
- default:
- throw new IllegalArgumentException("Unknown URI " + uri + " (" + match + ")");
-
- }
-
- // If no sort order is specified use the default
- String orderBy;
- if (TextUtils.isEmpty(sortOrder)) {
- orderBy = null;
- } else {
- orderBy = sortOrder;
- }
-
- SQLiteDatabase db = getDb().getReadableDatabase();
- Cursor c = qb.query(db, projection, selection, selectionArgs, groupBy, having, orderBy);
-
- // Tell the cursor what uri to watch, so it knows when its source data changes
- c.setNotificationUri(getContext().getContentResolver(), uri);
-
- if (Constants.DEBUG) {
- Log.d(Constants.TAG,
- "Query: "
- + qb.buildQuery(projection, selection, selectionArgs, null, null,
- orderBy, null));
- Log.d(Constants.TAG, "Cursor: " + DatabaseUtils.dumpCursorToString(c));
- }
-
- return c;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- Log.d(Constants.TAG, "insert(uri=" + uri + ", values=" + values.toString() + ")");
-
- final SQLiteDatabase db = getDb().getWritableDatabase();
-
- Uri rowUri = null;
- Long keyId = null;
- try {
- final int match = mUriMatcher.match(uri);
-
- switch (match) {
- case KEY_RING_PUBLIC:
- db.insertOrThrow(Tables.KEY_RINGS_PUBLIC, null, values);
- keyId = values.getAsLong(KeyRings.MASTER_KEY_ID);
- break;
-
- case KEY_RING_SECRET:
- db.insertOrThrow(Tables.KEY_RINGS_SECRET, null, values);
- keyId = values.getAsLong(KeyRings.MASTER_KEY_ID);
- break;
-
- case KEY_RING_KEYS:
- Log.d(Constants.TAG, "keys");
- db.insertOrThrow(Tables.KEYS, null, values);
- keyId = values.getAsLong(Keys.MASTER_KEY_ID);
- break;
-
- case KEY_RING_USER_IDS:
- db.insertOrThrow(Tables.USER_IDS, null, values);
- keyId = values.getAsLong(UserIds.MASTER_KEY_ID);
- break;
-
- case KEY_RING_CERTS:
- // we replace here, keeping only the latest signature
- // TODO this would be better handled in saveKeyRing directly!
- db.replaceOrThrow(Tables.CERTS, null, values);
- keyId = values.getAsLong(Certs.MASTER_KEY_ID);
- break;
-
- case API_APPS:
- db.insertOrThrow(Tables.API_APPS, null, values);
- break;
-
- case API_ACCOUNTS:
- // set foreign key automatically based on given uri
- // e.g., api_apps/com.example.app/accounts/
- String packageName = uri.getPathSegments().get(1);
- values.put(ApiAccounts.PACKAGE_NAME, packageName);
-
- Log.d(Constants.TAG, "provider packageName: " + packageName);
-
- db.insertOrThrow(Tables.API_ACCOUNTS, null, values);
- // TODO: this is wrong:
-// rowUri = ApiAccounts.buildIdUri(Long.toString(rowId));
-
- break;
-
- default:
- throw new UnsupportedOperationException("Unknown uri: " + uri);
- }
-
- if(keyId != null) {
- uri = KeyRings.buildGenericKeyRingUri(keyId.toString());
- rowUri = uri;
- }
-
- // notify of changes in db
- getContext().getContentResolver().notifyChange(uri, null);
-
- } catch (SQLiteConstraintException e) {
- Log.e(Constants.TAG, "Constraint exception on insert! Entry already existing?", e);
- }
-
- return rowUri;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int delete(Uri uri, String additionalSelection, String[] selectionArgs) {
- Log.v(Constants.TAG, "delete(uri=" + uri + ")");
-
- final SQLiteDatabase db = getDb().getWritableDatabase();
-
- int count;
- final int match = mUriMatcher.match(uri);
-
- switch (match) {
- case KEY_RING_PUBLIC: {
- @SuppressWarnings("ConstantConditions") // ensured by uriMatcher above
- String selection = KeyRings.MASTER_KEY_ID + " = " + uri.getPathSegments().get(1);
- if (!TextUtils.isEmpty(additionalSelection)) {
- selection += " AND (" + additionalSelection + ")";
- }
- // corresponding keys and userIds are deleted by ON DELETE CASCADE
- count = db.delete(Tables.KEY_RINGS_PUBLIC, selection, selectionArgs);
- uri = KeyRings.buildGenericKeyRingUri(uri.getPathSegments().get(1));
- break;
- }
- case KEY_RING_SECRET: {
- @SuppressWarnings("ConstantConditions") // ensured by uriMatcher above
- String selection = KeyRings.MASTER_KEY_ID + " = " + uri.getPathSegments().get(1);
- if (!TextUtils.isEmpty(additionalSelection)) {
- selection += " AND (" + additionalSelection + ")";
- }
- count = db.delete(Tables.KEY_RINGS_SECRET, selection, selectionArgs);
- uri = KeyRings.buildGenericKeyRingUri(uri.getPathSegments().get(1));
- break;
- }
-
- case API_APPS_BY_PACKAGE_NAME:
- count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, additionalSelection),
- selectionArgs);
- break;
- case API_ACCOUNTS_BY_ACCOUNT_NAME:
- count = db.delete(Tables.API_ACCOUNTS, buildDefaultApiAccountsSelection(uri, additionalSelection),
- selectionArgs);
- break;
- default:
- throw new UnsupportedOperationException("Unknown uri: " + uri);
- }
-
- // notify of changes in db
- getContext().getContentResolver().notifyChange(uri, null);
-
- return count;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
- Log.v(Constants.TAG, "update(uri=" + uri + ", values=" + values.toString() + ")");
-
- final SQLiteDatabase db = mKeychainDatabase.getWritableDatabase();
-
- String defaultSelection = null;
- int count = 0;
- try {
- final int match = mUriMatcher.match(uri);
- switch (match) {
- case API_APPS_BY_PACKAGE_NAME:
- count = db.update(Tables.API_APPS, values,
- buildDefaultApiAppsSelection(uri, selection), selectionArgs);
- break;
- case API_ACCOUNTS_BY_ACCOUNT_NAME:
- count = db.update(Tables.API_ACCOUNTS, values,
- buildDefaultApiAccountsSelection(uri, selection), selectionArgs);
- break;
- default:
- throw new UnsupportedOperationException("Unknown uri: " + uri);
- }
-
- // notify of changes in db
- getContext().getContentResolver().notifyChange(uri, null);
-
- } catch (SQLiteConstraintException e) {
- Log.e(Constants.TAG, "Constraint exception on update! Entry already existing?");
- }
-
- return count;
- }
-
- /**
- * Build default selection statement for API apps. If no extra selection is specified only build
- * where clause with rowId
- *
- * @param uri
- * @param selection
- * @return
- */
- private String buildDefaultApiAppsSelection(Uri uri, String selection) {
- String packageName = DatabaseUtils.sqlEscapeString(uri.getLastPathSegment());
-
- String andSelection = "";
- if (!TextUtils.isEmpty(selection)) {
- andSelection = " AND (" + selection + ")";
- }
-
- return ApiApps.PACKAGE_NAME + "=" + packageName + andSelection;
- }
-
- private String buildDefaultApiAccountsSelection(Uri uri, String selection) {
- String packageName = DatabaseUtils.sqlEscapeString(uri.getPathSegments().get(1));
- String accountName = DatabaseUtils.sqlEscapeString(uri.getLastPathSegment());
-
- String andSelection = "";
- if (!TextUtils.isEmpty(selection)) {
- andSelection = " AND (" + selection + ")";
- }
-
- return ApiAccounts.PACKAGE_NAME + "=" + packageName + " AND "
- + ApiAccounts.ACCOUNT_NAME + "=" + accountName
- + andSelection;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobContract.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobContract.java
deleted file mode 100644
index 701ffc6af..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobContract.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.provider;
-
-import android.net.Uri;
-import android.provider.BaseColumns;
-import org.sufficientlysecure.keychain.Constants;
-
-public class KeychainServiceBlobContract {
-
- interface BlobsColumns {
- String KEY = "key";
- }
-
- public static final String CONTENT_AUTHORITY = Constants.PACKAGE_NAME + ".blobs";
-
- private static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
-
- public static class Blobs implements BlobsColumns, BaseColumns {
- public static final Uri CONTENT_URI = BASE_CONTENT_URI;
- }
-
- private KeychainServiceBlobContract() {
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobDatabase.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobDatabase.java
deleted file mode 100644
index bc7de0b37..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobDatabase.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2011 Markus Doits <markus.doits@googlemail.com>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.provider;
-
-import android.content.Context;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.provider.BaseColumns;
-import org.sufficientlysecure.keychain.provider.KeychainServiceBlobContract.BlobsColumns;
-
-public class KeychainServiceBlobDatabase extends SQLiteOpenHelper {
- private static final String DATABASE_NAME = "openkeychain_blob.db";
- private static final int DATABASE_VERSION = 2;
-
- public static final String TABLE = "data";
-
- public KeychainServiceBlobDatabase(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- db.execSQL("CREATE TABLE " + TABLE + " ( " + BaseColumns._ID
- + " INTEGER PRIMARY KEY AUTOINCREMENT, " + BlobsColumns.KEY + " TEXT NOT NULL)");
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- // no upgrade necessary yet
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobProvider.java
deleted file mode 100644
index aa30e845d..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainServiceBlobProvider.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2011 Markus Doits <markus.doits@googlemail.com>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.provider;
-
-import android.content.ContentProvider;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.net.Uri;
-import android.os.ParcelFileDescriptor;
-import android.provider.BaseColumns;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.provider.KeychainServiceBlobContract.Blobs;
-import org.sufficientlysecure.keychain.provider.KeychainServiceBlobContract.BlobsColumns;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.List;
-import java.util.UUID;
-
-public class KeychainServiceBlobProvider extends ContentProvider {
- private static final String STORE_PATH = Constants.Path.APP_DIR + "/KeychainBlobs";
-
- private KeychainServiceBlobDatabase mBlobDatabase = null;
-
- public KeychainServiceBlobProvider() {
- File dir = new File(STORE_PATH);
- dir.mkdirs();
- }
-
- @Override
- public boolean onCreate() {
- mBlobDatabase = new KeychainServiceBlobDatabase(getContext());
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Uri insert(Uri uri, ContentValues ignored) {
- // ContentValues are actually ignored, because we want to store a blob with no more
- // information but have to create an record with the password generated here first
- ContentValues vals = new ContentValues();
-
- // Insert a random key in the database. This has to provided by the caller when updating or
- // getting the blob
- String password = UUID.randomUUID().toString();
- vals.put(BlobsColumns.KEY, password);
-
- SQLiteDatabase db = mBlobDatabase.getWritableDatabase();
- long newRowId = db.insert(KeychainServiceBlobDatabase.TABLE, null, vals);
- Uri insertedUri = ContentUris.withAppendedId(Blobs.CONTENT_URI, newRowId);
-
- return Uri.withAppendedPath(insertedUri, password);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ParcelFileDescriptor openFile(Uri uri, String mode) throws SecurityException,
- FileNotFoundException {
- Log.d(Constants.TAG, "openFile() called with uri: " + uri.toString() + " and mode: " + mode);
-
- List<String> segments = uri.getPathSegments();
- if (segments.size() < 2) {
- throw new SecurityException("Password not found in URI");
- }
- String id = segments.get(0);
- String key = segments.get(1);
-
- Log.d(Constants.TAG, "Got id: " + id + " and key: " + key);
-
- // get the data
- SQLiteDatabase db = mBlobDatabase.getReadableDatabase();
- Cursor result = db.query(KeychainServiceBlobDatabase.TABLE, new String[]{BaseColumns._ID},
- BaseColumns._ID + " = ? and " + BlobsColumns.KEY + " = ?",
- new String[]{id, key}, null, null, null);
-
- if (result.getCount() == 0) {
- // either the key is wrong or no id exists
- throw new FileNotFoundException("No file found with that ID and/or password");
- }
-
- File targetFile = new File(STORE_PATH, id);
- if (mode.equals("w")) {
- Log.d(Constants.TAG, "Try to open file w");
- if (!targetFile.exists()) {
- try {
- targetFile.createNewFile();
- } catch (IOException e) {
- Log.e(Constants.TAG, "Got IEOException on creating new file", e);
- throw new FileNotFoundException("Could not create file to write to");
- }
- }
- return ParcelFileDescriptor.open(targetFile, ParcelFileDescriptor.MODE_WRITE_ONLY
- | ParcelFileDescriptor.MODE_TRUNCATE);
- } else if (mode.equals("r")) {
- Log.d(Constants.TAG, "Try to open file r");
- if (!targetFile.exists()) {
- throw new FileNotFoundException("Error: Could not find the file requested");
- }
- return ParcelFileDescriptor.open(targetFile, ParcelFileDescriptor.MODE_READ_ONLY);
- }
-
- return null;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getType(Uri uri) {
- return null;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
- return null;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- return 0;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
- return 0;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
deleted file mode 100644
index 5e6d37237..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
+++ /dev/null
@@ -1,673 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.provider;
-
-import android.content.ContentProviderOperation;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.OperationApplicationException;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.net.Uri;
-import android.os.RemoteException;
-
-import org.spongycastle.bcpg.ArmoredOutputStream;
-import org.spongycastle.openpgp.PGPException;
-import org.spongycastle.openpgp.PGPKeyRing;
-import org.spongycastle.openpgp.PGPPublicKey;
-import org.spongycastle.openpgp.PGPPublicKeyRing;
-import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.spongycastle.openpgp.PGPSignature;
-import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
-import org.sufficientlysecure.keychain.pgp.PgpHelper;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
-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.UserIds;
-import org.sufficientlysecure.keychain.remote.AccountSettings;
-import org.sufficientlysecure.keychain.remote.AppSettings;
-import org.sufficientlysecure.keychain.util.IterableIterator;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.security.SignatureException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-public class ProviderHelper {
-
- // If we ever switch to api level 11, we can ditch this whole mess!
- public static final int FIELD_TYPE_NULL = 1;
- // this is called integer to stay coherent with the constants in Cursor (api level 11)
- public static final int FIELD_TYPE_INTEGER = 2;
- public static final int FIELD_TYPE_FLOAT = 3;
- public static final int FIELD_TYPE_STRING = 4;
- public static final int FIELD_TYPE_BLOB = 5;
-
- public static Object getGenericData(Context context, Uri uri, String column, int type) {
- return getGenericData(context, uri, new String[] { column }, new int[] { type }).get(column);
- }
-
- public static HashMap<String,Object> getGenericData(Context context, Uri uri, String[] proj, int[] types) {
- Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null);
-
- HashMap<String, Object> result = new HashMap<String, Object>(proj.length);
- if (cursor != null && cursor.moveToFirst()) {
- int pos = 0;
- for(String p : proj) {
- switch(types[pos]) {
- case FIELD_TYPE_NULL: result.put(p, cursor.isNull(pos)); break;
- case FIELD_TYPE_INTEGER: result.put(p, cursor.getLong(pos)); break;
- case FIELD_TYPE_FLOAT: result.put(p, cursor.getFloat(pos)); break;
- case FIELD_TYPE_STRING: result.put(p, cursor.getString(pos)); break;
- case FIELD_TYPE_BLOB: result.put(p, cursor.getBlob(pos)); break;
- }
- pos += 1;
- }
- }
-
- if (cursor != null) {
- cursor.close();
- }
-
- return result;
- }
-
- public static Object getUnifiedData(Context context, long masterKeyId, String column, int type) {
- return getUnifiedData(context, masterKeyId, new String[] { column }, new int[] { type }).get(column);
- }
-
- public static HashMap<String,Object> getUnifiedData(Context context, long masterKeyId, String[] proj, int[] types) {
- return getGenericData(context, KeyRings.buildUnifiedKeyRingUri(Long.toString(masterKeyId)), proj, types);
- }
-
- /**
- * Find the master key id related to a given query. The id will either be extracted from the
- * query, which should work for all specific /key_rings/ queries, or will be queried if it can't.
- */
- public static long getMasterKeyId(Context context, Uri queryUri) {
- // try extracting from the uri first
- String firstSegment = queryUri.getPathSegments().get(1);
- if(!firstSegment.equals("find")) try {
- return Long.parseLong(firstSegment);
- } catch(NumberFormatException e) {
- // didn't work? oh well.
- Log.d(Constants.TAG, "Couldn't get masterKeyId from URI, querying...");
- }
- Object data = getGenericData(context, queryUri, KeyRings.MASTER_KEY_ID, FIELD_TYPE_INTEGER);
- if(data != null)
- return (Long) data;
- // TODO better error handling?
- return 0L;
- }
-
- public static Map<Long, PGPKeyRing> getPGPKeyRings(Context context, Uri queryUri) {
- Cursor cursor = context.getContentResolver().query(queryUri,
- new String[]{KeyRingData.MASTER_KEY_ID, KeyRingData.KEY_RING_DATA },
- null, null, null);
-
- Map<Long, PGPKeyRing> result = new HashMap<Long, PGPKeyRing>(cursor.getCount());
- if (cursor != null && cursor.moveToFirst()) do {
- long masterKeyId = cursor.getLong(0);
- byte[] data = cursor.getBlob(1);
- if (data != null) {
- result.put(masterKeyId, PgpConversionHelper.BytesToPGPKeyRing(data));
- }
- } while(cursor.moveToNext());
-
- if (cursor != null) {
- cursor.close();
- }
-
- return result;
- }
- public static PGPKeyRing getPGPKeyRing(Context context, Uri queryUri) {
- Map<Long, PGPKeyRing> result = getPGPKeyRings(context, queryUri);
- if(result.isEmpty())
- return null;
- return result.values().iterator().next();
- }
-
- public static PGPPublicKeyRing getPGPPublicKeyRingWithKeyId(Context context, long keyId) {
- Uri uri = KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(keyId));
- long masterKeyId = getMasterKeyId(context, uri);
- if(masterKeyId != 0)
- return getPGPPublicKeyRing(context, masterKeyId);
- return null;
- }
- public static PGPSecretKeyRing getPGPSecretKeyRingWithKeyId(Context context, long keyId) {
- Uri uri = KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(keyId));
- long masterKeyId = getMasterKeyId(context, uri);
- if(masterKeyId != 0)
- return getPGPSecretKeyRing(context, masterKeyId);
- return null;
- }
-
- /**
- * Retrieves the actual PGPPublicKeyRing object from the database blob based on the masterKeyId
- */
- public static PGPPublicKeyRing getPGPPublicKeyRing(Context context,
- long masterKeyId) {
- Uri queryUri = KeyRingData.buildPublicKeyRingUri(Long.toString(masterKeyId));
- return (PGPPublicKeyRing) getPGPKeyRing(context, queryUri);
- }
-
- /**
- * Retrieves the actual PGPSecretKeyRing object from the database blob based on the maserKeyId
- */
- public static PGPSecretKeyRing getPGPSecretKeyRing(Context context,
- long masterKeyId) {
- Uri queryUri = KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId));
- return (PGPSecretKeyRing) getPGPKeyRing(context, queryUri);
- }
-
- /**
- * Saves PGPPublicKeyRing with its keys and userIds in DB
- */
- @SuppressWarnings("unchecked")
- public static void saveKeyRing(Context context, PGPPublicKeyRing keyRing) throws IOException {
- PGPPublicKey masterKey = keyRing.getPublicKey();
- long masterKeyId = masterKey.getKeyID();
-
- // IF there is a secret key, preserve it!
- PGPSecretKeyRing secretRing = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId);
-
- // delete old version of this keyRing, which also deletes all keys and userIds on cascade
- try {
- context.getContentResolver().delete(KeyRingData.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null);
- } catch (UnsupportedOperationException e) {
- Log.e(Constants.TAG, "Key could not be deleted! Maybe we are creating a new one!", e);
- }
-
- ContentValues values = new ContentValues();
- // use exactly the same _ID again to replace key in-place.
- // NOTE: If we would not use the same _ID again,
- // getting back to the ViewKeyActivity would result in Nullpointer,
- // because the currently loaded key would be gone from the database
- values.put(KeyRingData.MASTER_KEY_ID, masterKeyId);
- values.put(KeyRingData.KEY_RING_DATA, keyRing.getEncoded());
-
- // insert new version of this keyRing
- Uri uri = KeyRingData.buildPublicKeyRingUri(Long.toString(masterKeyId));
- Uri insertedUri = context.getContentResolver().insert(uri, values);
-
- // save all keys and userIds included in keyRing object in database
- ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
-
- int rank = 0;
- for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(keyRing.getPublicKeys())) {
- operations.add(buildPublicKeyOperations(context, masterKeyId, key, rank));
- ++rank;
- }
-
- // get a list of owned secret keys, for verification filtering
- Map<Long, PGPKeyRing> allKeyRings = getPGPKeyRings(context, KeyRingData.buildSecretKeyRingUri());
- // special case: available secret keys verify themselves!
- if(secretRing != null)
- allKeyRings.put(secretRing.getSecretKey().getKeyID(), secretRing);
-
- // classify and order user ids. primary are moved to the front, revoked to the back,
- // otherwise the order in the keyfile is preserved.
- List<UserIdItem> uids = new ArrayList<UserIdItem>();
-
- for (String userId : new IterableIterator<String>(masterKey.getUserIDs())) {
- UserIdItem item = new UserIdItem();
- uids.add(item);
- item.userId = userId;
-
- // look through signatures for this specific key
- for (PGPSignature cert : new IterableIterator<PGPSignature>(
- masterKey.getSignaturesForID(userId))) {
- long certId = cert.getKeyID();
- try {
- // self signature
- if(certId == masterKeyId) {
- cert.init(new JcaPGPContentVerifierBuilderProvider().setProvider(
- Constants.BOUNCY_CASTLE_PROVIDER_NAME), masterKey);
- if(!cert.verifyCertification(userId, masterKey)) {
- // not verified?! dang! TODO notify user? this is kinda serious...
- Log.e(Constants.TAG, "Could not verify self signature for " + userId + "!");
- continue;
- }
- // is this the first, or a more recent certificate?
- if(item.selfCert == null ||
- item.selfCert.getCreationTime().before(cert.getCreationTime())) {
- item.selfCert = cert;
- item.isPrimary = cert.getHashedSubPackets().isPrimaryUserID();
- item.isRevoked =
- cert.getSignatureType() == PGPSignature.CERTIFICATION_REVOCATION;
- }
- }
- // verify signatures from known private keys
- if(allKeyRings.containsKey(certId)) {
- // mark them as verified
- cert.init(new JcaPGPContentVerifierBuilderProvider().setProvider(
- Constants.BOUNCY_CASTLE_PROVIDER_NAME),
- allKeyRings.get(certId).getPublicKey());
- if(cert.verifyCertification(userId, masterKey)) {
- item.trustedCerts.add(cert);
- }
- }
- } catch(SignatureException e) {
- Log.e(Constants.TAG, "Signature verification failed! "
- + PgpKeyHelper.convertKeyIdToHex(masterKey.getKeyID())
- + " from "
- + PgpKeyHelper.convertKeyIdToHex(cert.getKeyID()), e);
- } catch(PGPException e) {
- Log.e(Constants.TAG, "Signature verification failed! "
- + PgpKeyHelper.convertKeyIdToHex(masterKey.getKeyID())
- + " from "
- + PgpKeyHelper.convertKeyIdToHex(cert.getKeyID()), e);
- }
- }
- }
-
- // primary before regular before revoked (see UserIdItem.compareTo)
- // this is a stable sort, so the order of keys is otherwise preserved.
- Collections.sort(uids);
- // iterate and put into db
- for(int userIdRank = 0; userIdRank < uids.size(); userIdRank++) {
- UserIdItem item = uids.get(userIdRank);
- operations.add(buildUserIdOperations(masterKeyId, item, userIdRank));
- // no self cert is bad, but allowed by the rfc...
- if(item.selfCert != null) {
- operations.add(buildCertOperations(
- masterKeyId, userIdRank, item.selfCert, Certs.VERIFIED_SELF));
- }
- // don't bother with trusted certs if the uid is revoked, anyways
- if(item.isRevoked) {
- continue;
- }
- for(int i = 0; i < item.trustedCerts.size(); i++) {
- operations.add(buildCertOperations(
- masterKeyId, userIdRank, item.trustedCerts.get(i), Certs.VERIFIED_SECRET));
- }
- }
-
- try {
- context.getContentResolver().applyBatch(KeychainContract.CONTENT_AUTHORITY, operations);
- } catch (RemoteException e) {
- Log.e(Constants.TAG, "applyBatch failed!", e);
- } catch (OperationApplicationException e) {
- Log.e(Constants.TAG, "applyBatch failed!", e);
- }
-
- // Save the saved keyring (if any)
- if(secretRing != null) {
- saveKeyRing(context, secretRing);
- }
-
- }
-
- private static class UserIdItem implements Comparable<UserIdItem> {
- String userId;
- boolean isPrimary = false;
- boolean isRevoked = false;
- PGPSignature selfCert;
- List<PGPSignature> trustedCerts = new ArrayList<PGPSignature>();
-
- @Override
- public int compareTo(UserIdItem o) {
- // if one key is primary but the other isn't, the primary one always comes first
- if(isPrimary != o.isPrimary)
- return isPrimary ? -1 : 1;
- // revoked keys always come last!
- if(isRevoked != o.isRevoked)
- return isRevoked ? 1 : -1;
- return 0;
- }
- }
-
- /**
- * Saves a PGPSecretKeyRing in the DB. This will only work if a corresponding public keyring
- * is already in the database!
- */
- @SuppressWarnings("unchecked")
- public static void saveKeyRing(Context context, PGPSecretKeyRing keyRing) throws IOException {
- long masterKeyId = keyRing.getPublicKey().getKeyID();
-
- // save secret keyring
- ContentValues values = new ContentValues();
- values.put(KeyRingData.MASTER_KEY_ID, masterKeyId);
- values.put(KeyRingData.KEY_RING_DATA, keyRing.getEncoded());
- // insert new version of this keyRing
- Uri uri = KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId));
- context.getContentResolver().insert(uri, values);
-
- }
-
- /**
- * Saves (or updates) a pair of public and secret KeyRings in the database
- */
- @SuppressWarnings("unchecked")
- public static void saveKeyRing(Context context, PGPPublicKeyRing pubRing, PGPSecretKeyRing privRing) throws IOException {
- long masterKeyId = pubRing.getPublicKey().getKeyID();
-
- // delete secret keyring (so it isn't unnecessarily saved by public-saveKeyRing below)
- context.getContentResolver().delete(KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId)), null, null);
-
- // save public keyring
- saveKeyRing(context, pubRing);
- saveKeyRing(context, privRing);
- }
-
- /**
- * Build ContentProviderOperation to add PGPPublicKey to database corresponding to a keyRing
- */
- private static ContentProviderOperation buildPublicKeyOperations(Context context,
- long masterKeyId, PGPPublicKey key, int rank) throws IOException {
-
- ContentValues values = new ContentValues();
- values.put(Keys.MASTER_KEY_ID, masterKeyId);
- values.put(Keys.RANK, rank);
-
- values.put(Keys.KEY_ID, key.getKeyID());
- values.put(Keys.KEY_SIZE, key.getBitStrength());
- values.put(Keys.ALGORITHM, key.getAlgorithm());
- values.put(Keys.FINGERPRINT, key.getFingerprint());
-
- values.put(Keys.CAN_CERTIFY, (PgpKeyHelper.isCertificationKey(key)));
- values.put(Keys.CAN_SIGN, (PgpKeyHelper.isSigningKey(key)));
- values.put(Keys.CAN_ENCRYPT, PgpKeyHelper.isEncryptionKey(key));
- values.put(Keys.IS_REVOKED, key.isRevoked());
-
- values.put(Keys.CREATION, PgpKeyHelper.getCreationDate(key).getTime() / 1000);
- Date expiryDate = PgpKeyHelper.getExpiryDate(key);
- if (expiryDate != null) {
- values.put(Keys.EXPIRY, expiryDate.getTime() / 1000);
- }
-
- Uri uri = Keys.buildKeysUri(Long.toString(masterKeyId));
-
- return ContentProviderOperation.newInsert(uri).withValues(values).build();
- }
-
- /**
- * Build ContentProviderOperation to add PGPPublicKey to database corresponding to a keyRing
- */
- private static ContentProviderOperation buildCertOperations(long masterKeyId,
- int rank,
- PGPSignature cert,
- int verified)
- throws IOException {
- ContentValues values = new ContentValues();
- values.put(Certs.MASTER_KEY_ID, masterKeyId);
- values.put(Certs.RANK, rank);
- values.put(Certs.KEY_ID_CERTIFIER, cert.getKeyID());
- values.put(Certs.TYPE, cert.getSignatureType());
- values.put(Certs.CREATION, cert.getCreationTime().getTime() / 1000);
- values.put(Certs.VERIFIED, verified);
- values.put(Certs.DATA, cert.getEncoded());
-
- Uri uri = Certs.buildCertsUri(Long.toString(masterKeyId));
-
- return ContentProviderOperation.newInsert(uri).withValues(values).build();
- }
-
- /**
- * Build ContentProviderOperation to add PublicUserIds to database corresponding to a keyRing
- */
- private static ContentProviderOperation buildUserIdOperations(long masterKeyId, UserIdItem item,
- int rank) {
- ContentValues values = new ContentValues();
- values.put(UserIds.MASTER_KEY_ID, masterKeyId);
- values.put(UserIds.USER_ID, item.userId);
- values.put(UserIds.IS_PRIMARY, item.isPrimary);
- values.put(UserIds.IS_REVOKED, item.isRevoked);
- values.put(UserIds.RANK, rank);
-
- Uri uri = UserIds.buildUserIdsUri(Long.toString(masterKeyId));
-
- return ContentProviderOperation.newInsert(uri).withValues(values).build();
- }
-
- public static ArrayList<String> getKeyRingsAsArmoredString(Context context, long[] masterKeyIds) {
- ArrayList<String> output = new ArrayList<String>();
-
- if (masterKeyIds != null && masterKeyIds.length > 0) {
-
- Cursor cursor = getCursorWithSelectedKeyringMasterKeyIds(context, masterKeyIds);
-
- if (cursor != null) {
- int masterIdCol = cursor.getColumnIndex(KeyRingData.MASTER_KEY_ID);
- int dataCol = cursor.getColumnIndex(KeyRingData.KEY_RING_DATA);
- if (cursor.moveToFirst()) {
- do {
- Log.d(Constants.TAG, "masterKeyId: " + cursor.getLong(masterIdCol));
-
- // get actual keyring data blob and write it to ByteArrayOutputStream
- try {
- Object keyRing = null;
- byte[] data = cursor.getBlob(dataCol);
- if (data != null) {
- keyRing = PgpConversionHelper.BytesToPGPKeyRing(data);
- }
-
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- ArmoredOutputStream aos = new ArmoredOutputStream(bos);
- aos.setHeader("Version", PgpHelper.getFullVersion(context));
-
- if (keyRing instanceof PGPSecretKeyRing) {
- aos.write(((PGPSecretKeyRing) keyRing).getEncoded());
- } else if (keyRing instanceof PGPPublicKeyRing) {
- aos.write(((PGPPublicKeyRing) keyRing).getEncoded());
- }
- aos.close();
-
- String armoredKey = bos.toString("UTF-8");
-
- Log.d(Constants.TAG, "armoredKey:" + armoredKey);
-
- output.add(armoredKey);
- } catch (IOException e) {
- Log.e(Constants.TAG, "IOException", e);
- }
- } while (cursor.moveToNext());
- }
- }
-
- if (cursor != null) {
- cursor.close();
- }
-
- } else {
- Log.e(Constants.TAG, "No master keys given!");
- }
-
- if (output.size() > 0) {
- return output;
- } else {
- return null;
- }
- }
-
- private static Cursor getCursorWithSelectedKeyringMasterKeyIds(Context context, long[] masterKeyIds) {
- Cursor cursor = null;
- if (masterKeyIds != null && masterKeyIds.length > 0) {
-
- String inMasterKeyList = KeyRingData.MASTER_KEY_ID + " IN (";
- for (int i = 0; i < masterKeyIds.length; ++i) {
- if (i != 0) {
- inMasterKeyList += ", ";
- }
- inMasterKeyList += DatabaseUtils.sqlEscapeString("" + masterKeyIds[i]);
- }
- inMasterKeyList += ")";
-
- cursor = context.getContentResolver().query(KeyRingData.buildPublicKeyRingUri(), new String[] {
- KeyRingData._ID, KeyRingData.MASTER_KEY_ID, KeyRingData.KEY_RING_DATA
- }, inMasterKeyList, null, null);
- }
-
- return cursor;
- }
-
- public static ArrayList<String> getRegisteredApiApps(Context context) {
- Cursor cursor = context.getContentResolver().query(ApiApps.CONTENT_URI, null, null, null,
- null);
-
- ArrayList<String> packageNames = new ArrayList<String>();
- if (cursor != null) {
- int packageNameCol = cursor.getColumnIndex(ApiApps.PACKAGE_NAME);
- if (cursor.moveToFirst()) {
- do {
- packageNames.add(cursor.getString(packageNameCol));
- } while (cursor.moveToNext());
- }
- }
-
- if (cursor != null) {
- cursor.close();
- }
-
- return packageNames;
- }
-
- private static ContentValues contentValueForApiApps(AppSettings appSettings) {
- ContentValues values = new ContentValues();
- values.put(ApiApps.PACKAGE_NAME, appSettings.getPackageName());
- values.put(ApiApps.PACKAGE_SIGNATURE, appSettings.getPackageSignature());
- return values;
- }
-
- private static ContentValues contentValueForApiAccounts(AccountSettings accSettings) {
- ContentValues values = new ContentValues();
- values.put(KeychainContract.ApiAccounts.ACCOUNT_NAME, accSettings.getAccountName());
- values.put(KeychainContract.ApiAccounts.KEY_ID, accSettings.getKeyId());
- values.put(KeychainContract.ApiAccounts.COMPRESSION, accSettings.getCompression());
- values.put(KeychainContract.ApiAccounts.ENCRYPTION_ALGORITHM, accSettings.getEncryptionAlgorithm());
- values.put(KeychainContract.ApiAccounts.HASH_ALORITHM, accSettings.getHashAlgorithm());
- return values;
- }
-
- public static void insertApiApp(Context context, AppSettings appSettings) {
- context.getContentResolver().insert(KeychainContract.ApiApps.CONTENT_URI,
- contentValueForApiApps(appSettings));
- }
-
- public static void insertApiAccount(Context context, Uri uri, AccountSettings accSettings) {
- context.getContentResolver().insert(uri, contentValueForApiAccounts(accSettings));
- }
-
- public static void updateApiApp(Context context, AppSettings appSettings, Uri uri) {
- if (context.getContentResolver().update(uri, contentValueForApiApps(appSettings), null,
- null) <= 0) {
- throw new RuntimeException();
- }
- }
-
- public static void updateApiAccount(Context context, AccountSettings accSettings, Uri uri) {
- if (context.getContentResolver().update(uri, contentValueForApiAccounts(accSettings), null,
- null) <= 0) {
- throw new RuntimeException();
- }
- }
-
- /**
- * Must be an uri pointing to an account
- *
- * @param context
- * @param uri
- * @return
- */
- public static AppSettings getApiAppSettings(Context context, Uri uri) {
- AppSettings settings = null;
-
- Cursor cur = context.getContentResolver().query(uri, null, null, null, null);
- if (cur != null && cur.moveToFirst()) {
- settings = new AppSettings();
- settings.setPackageName(cur.getString(
- cur.getColumnIndex(KeychainContract.ApiApps.PACKAGE_NAME)));
- settings.setPackageSignature(cur.getBlob(
- cur.getColumnIndex(KeychainContract.ApiApps.PACKAGE_SIGNATURE)));
- }
-
- return settings;
- }
-
- public static AccountSettings getApiAccountSettings(Context context, Uri accountUri) {
- AccountSettings settings = null;
-
- Cursor cur = context.getContentResolver().query(accountUri, null, null, null, null);
- if (cur != null && cur.moveToFirst()) {
- settings = new AccountSettings();
-
- settings.setAccountName(cur.getString(
- cur.getColumnIndex(KeychainContract.ApiAccounts.ACCOUNT_NAME)));
- settings.setKeyId(cur.getLong(
- cur.getColumnIndex(KeychainContract.ApiAccounts.KEY_ID)));
- settings.setCompression(cur.getInt(
- cur.getColumnIndexOrThrow(KeychainContract.ApiAccounts.COMPRESSION)));
- settings.setHashAlgorithm(cur.getInt(
- cur.getColumnIndexOrThrow(KeychainContract.ApiAccounts.HASH_ALORITHM)));
- settings.setEncryptionAlgorithm(cur.getInt(
- cur.getColumnIndexOrThrow(KeychainContract.ApiAccounts.ENCRYPTION_ALGORITHM)));
- }
-
- return settings;
- }
-
- public static Set<Long> getAllKeyIdsForApp(Context context, Uri uri) {
- Set<Long> keyIds = new HashSet<Long>();
-
- Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
- if (cursor != null) {
- int keyIdColumn = cursor.getColumnIndex(KeychainContract.ApiAccounts.KEY_ID);
- while (cursor.moveToNext()) {
- keyIds.add(cursor.getLong(keyIdColumn));
- }
- }
-
- return keyIds;
- }
-
- public static byte[] getApiAppSignature(Context context, String packageName) {
- Uri queryUri = ApiApps.buildByPackageNameUri(packageName);
-
- String[] projection = new String[]{ApiApps.PACKAGE_SIGNATURE};
-
- ContentResolver cr = context.getContentResolver();
- Cursor cursor = cr.query(queryUri, projection, null, null, null);
-
- byte[] signature = null;
- if (cursor != null && cursor.moveToFirst()) {
- int signatureCol = 0;
-
- signature = cursor.getBlob(signatureCol);
- }
-
- if (cursor != null) {
- cursor.close();
- }
-
- return signature;
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AccountSettings.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AccountSettings.java
deleted file mode 100644
index 832cbc752..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AccountSettings.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote;
-
-import org.spongycastle.bcpg.HashAlgorithmTags;
-import org.spongycastle.openpgp.PGPEncryptedData;
-import org.sufficientlysecure.keychain.Id;
-
-public class AccountSettings {
- private String mAccountName;
- private long mKeyId = Id.key.none;
- private int mEncryptionAlgorithm;
- private int mHashAlgorithm;
- private int mCompression;
-
- public AccountSettings() {
-
- }
-
- public AccountSettings(String accountName) {
- super();
- this.mAccountName = accountName;
-
- // defaults:
- this.mEncryptionAlgorithm = PGPEncryptedData.AES_256;
- this.mHashAlgorithm = HashAlgorithmTags.SHA512;
- this.mCompression = Id.choice.compression.zlib;
- }
-
- public String getAccountName() {
- return mAccountName;
- }
-
- public void setAccountName(String mAccountName) {
- this.mAccountName = mAccountName;
- }
-
- public long getKeyId() {
- return mKeyId;
- }
-
- public void setKeyId(long scretKeyId) {
- this.mKeyId = scretKeyId;
- }
-
- public int getEncryptionAlgorithm() {
- return mEncryptionAlgorithm;
- }
-
- public void setEncryptionAlgorithm(int encryptionAlgorithm) {
- this.mEncryptionAlgorithm = encryptionAlgorithm;
- }
-
- public int getHashAlgorithm() {
- return mHashAlgorithm;
- }
-
- public void setHashAlgorithm(int hashAlgorithm) {
- this.mHashAlgorithm = hashAlgorithm;
- }
-
- public int getCompression() {
- return mCompression;
- }
-
- public void setCompression(int compression) {
- this.mCompression = compression;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java
deleted file mode 100644
index a3f9f84c9..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/AppSettings.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote;
-
-public class AppSettings {
- private String mPackageName;
- private byte[] mPackageSignature;
-
- public AppSettings() {
-
- }
-
- public AppSettings(String packageName, byte[] packageSignature) {
- super();
- this.mPackageName = packageName;
- this.mPackageSignature = packageSignature;
- }
-
- public String getPackageName() {
- return mPackageName;
- }
-
- public void setPackageName(String packageName) {
- this.mPackageName = packageName;
- }
-
- public byte[] getPackageSignature() {
- return mPackageSignature;
- }
-
- public void setPackageSignature(byte[] packageSignature) {
- this.mPackageSignature = packageSignature;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
deleted file mode 100644
index b38fea5a9..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote;
-
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-
-import org.openintents.openpgp.IOpenPgpService;
-import org.openintents.openpgp.OpenPgpError;
-import org.openintents.openpgp.OpenPgpSignatureResult;
-import org.openintents.openpgp.util.OpenPgpApi;
-import org.spongycastle.util.Arrays;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
-import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
-import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAccounts;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity;
-import org.sufficientlysecure.keychain.service.PassphraseCacheService;
-import org.sufficientlysecure.keychain.ui.ImportKeysActivity;
-import org.sufficientlysecure.keychain.util.InputData;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Set;
-
-public class OpenPgpService extends RemoteService {
-
- /**
- * Search database for key ids based on emails.
- *
- * @param encryptionUserIds
- * @return
- */
- private Intent getKeyIdsFromEmails(Intent data, String[] encryptionUserIds) {
- // find key ids to given emails in database
- ArrayList<Long> keyIds = new ArrayList<Long>();
-
- boolean missingUserIdsCheck = false;
- boolean duplicateUserIdsCheck = false;
- ArrayList<String> missingUserIds = new ArrayList<String>();
- ArrayList<String> duplicateUserIds = new ArrayList<String>();
-
- for (String email : encryptionUserIds) {
- Uri uri = KeyRings.buildUnifiedKeyRingsFindByEmailUri(email);
- Cursor cur = getContentResolver().query(uri, null, null, null, null);
- if (cur.moveToFirst()) {
- long id = cur.getLong(cur.getColumnIndex(KeyRings.MASTER_KEY_ID));
- keyIds.add(id);
- } else {
- missingUserIdsCheck = true;
- missingUserIds.add(email);
- Log.d(Constants.TAG, "user id missing");
- }
- if (cur.moveToNext()) {
- duplicateUserIdsCheck = true;
- duplicateUserIds.add(email);
- Log.d(Constants.TAG, "more than one user id with the same email");
- }
- }
-
- // convert to long[]
- long[] keyIdsArray = new long[keyIds.size()];
- for (int i = 0; i < keyIdsArray.length; i++) {
- keyIdsArray[i] = keyIds.get(i);
- }
-
- // allow the user to verify pub key selection
- if (missingUserIdsCheck || duplicateUserIdsCheck) {
- // build PendingIntent
- Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
- intent.setAction(RemoteServiceActivity.ACTION_SELECT_PUB_KEYS);
- intent.putExtra(RemoteServiceActivity.EXTRA_SELECTED_MASTER_KEY_IDS, keyIdsArray);
- intent.putExtra(RemoteServiceActivity.EXTRA_MISSING_USER_IDS, missingUserIds);
- intent.putExtra(RemoteServiceActivity.EXTRA_DUBLICATE_USER_IDS, duplicateUserIds);
- intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
-
- PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
- intent,
- PendingIntent.FLAG_CANCEL_CURRENT);
-
- // return PendingIntent to be executed by client
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
- return result;
- }
-
- if (keyIdsArray.length == 0) {
- return null;
- }
-
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.EXTRA_KEY_IDS, keyIdsArray);
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
- return result;
- }
-
- private Intent getPassphraseBundleIntent(Intent data, long keyId) {
- // build PendingIntent for passphrase input
- Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
- intent.setAction(RemoteServiceActivity.ACTION_CACHE_PASSPHRASE);
- intent.putExtra(RemoteServiceActivity.EXTRA_SECRET_KEY_ID, keyId);
- // pass params through to activity that it can be returned again later to repeat pgp operation
- intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
- PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
- intent,
- PendingIntent.FLAG_CANCEL_CURRENT);
-
- // return PendingIntent to be executed by client
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
- return result;
- }
-
- private Intent signImpl(Intent data, ParcelFileDescriptor input,
- ParcelFileDescriptor output, AccountSettings accSettings) {
- try {
- boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
-
- // get passphrase from cache, if key has "no" passphrase, this returns an empty String
- String passphrase;
- if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) {
- passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
- } else {
- passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), accSettings.getKeyId());
- }
- if (passphrase == null) {
- // get PendingIntent for passphrase input, add it to given params and return to client
- Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId());
- return passphraseBundle;
- }
-
- // Get Input- and OutputStream from ParcelFileDescriptor
- InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input);
- OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
- try {
- long inputLength = is.available();
- InputData inputData = new InputData(is, inputLength);
-
- // sign-only
- PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(getContext(), inputData, os);
- builder.enableAsciiArmorOutput(asciiArmor)
- .signatureHashAlgorithm(accSettings.getHashAlgorithm())
- .signatureForceV3(false)
- .signatureKeyId(accSettings.getKeyId())
- .signaturePassphrase(passphrase);
- builder.build().execute();
- } finally {
- is.close();
- os.close();
- }
-
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
- return result;
- } catch (Exception e) {
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_ERROR,
- new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
- return result;
- }
- }
-
- private Intent encryptAndSignImpl(Intent data, ParcelFileDescriptor input,
- ParcelFileDescriptor output, AccountSettings accSettings,
- boolean sign) {
- try {
- boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
-
- long[] keyIds;
- if (data.hasExtra(OpenPgpApi.EXTRA_KEY_IDS)) {
- keyIds = data.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS);
- } else if (data.hasExtra(OpenPgpApi.EXTRA_USER_IDS)) {
- // get key ids based on given user ids
- String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS);
- // give params through to activity...
- Intent result = getKeyIdsFromEmails(data, userIds);
-
- if (result.getIntExtra(OpenPgpApi.RESULT_CODE, 0) == OpenPgpApi.RESULT_CODE_SUCCESS) {
- keyIds = result.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS);
- } else {
- // if not success -> result contains a PendingIntent for user interaction
- return result;
- }
- } else {
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_ERROR,
- new OpenPgpError(OpenPgpError.GENERIC_ERROR,
- "Missing parameter user_ids or key_ids!"));
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
- return result;
- }
-
- // add own key for encryption
- keyIds = Arrays.copyOf(keyIds, keyIds.length + 1);
- keyIds[keyIds.length - 1] = accSettings.getKeyId();
-
- // build InputData and write into OutputStream
- // Get Input- and OutputStream from ParcelFileDescriptor
- InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input);
- OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
- try {
- long inputLength = is.available();
- InputData inputData = new InputData(is, inputLength);
-
- PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(getContext(), inputData, os);
- builder.enableAsciiArmorOutput(asciiArmor)
- .compressionId(accSettings.getCompression())
- .symmetricEncryptionAlgorithm(accSettings.getEncryptionAlgorithm())
- .encryptionKeyIds(keyIds);
-
- if (sign) {
- String passphrase;
- if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) {
- passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
- } else {
- passphrase = PassphraseCacheService.getCachedPassphrase(getContext(),
- accSettings.getKeyId());
- }
- if (passphrase == null) {
- // get PendingIntent for passphrase input, add it to given params and return to client
- Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId());
- return passphraseBundle;
- }
-
- // sign and encrypt
- builder.signatureHashAlgorithm(accSettings.getHashAlgorithm())
- .signatureForceV3(false)
- .signatureKeyId(accSettings.getKeyId())
- .signaturePassphrase(passphrase);
- } else {
- // encrypt only
- builder.signatureKeyId(Id.key.none);
- }
- // execute PGP operation!
- builder.build().execute();
- } finally {
- is.close();
- os.close();
- }
-
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
- return result;
- } catch (Exception e) {
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_ERROR,
- new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
- return result;
- }
- }
-
- private Intent decryptAndVerifyImpl(Intent data, ParcelFileDescriptor input,
- ParcelFileDescriptor output, Set<Long> allowedKeyIds) {
- try {
- // Get Input- and OutputStream from ParcelFileDescriptor
- InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input);
- OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
-
- Intent result = new Intent();
- try {
-
- String passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
- long inputLength = is.available();
- InputData inputData = new InputData(is, inputLength);
-
- PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, os);
- builder.allowSymmetricDecryption(false) // no support for symmetric encryption
- .allowedKeyIds(allowedKeyIds) // allow only private keys associated with
- // accounts of this app
- .passphrase(passphrase);
-
- // TODO: currently does not support binary signed-only content
- PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute();
-
- if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) {
- // get PendingIntent for passphrase input, add it to given params and return to client
- Intent passphraseBundle =
- getPassphraseBundleIntent(data, decryptVerifyResult.getKeyIdPassphraseNeeded());
- return passphraseBundle;
- } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED ==
- decryptVerifyResult.getStatus()) {
- throw new PgpGeneralException("Decryption of symmetric content not supported by API!");
- }
-
- OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult();
- if (signatureResult != null) {
- if (signatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY) {
- // If signature is unknown we return an _additional_ PendingIntent
- // to retrieve the missing key
- Intent intent = new Intent(getBaseContext(), ImportKeysActivity.class);
- intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN);
- intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, signatureResult.getKeyId());
- intent.putExtra(ImportKeysActivity.EXTRA_PENDING_INTENT_DATA, data);
-
- PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
- intent,
- PendingIntent.FLAG_CANCEL_CURRENT);
-
- result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
- }
-
- result.putExtra(OpenPgpApi.RESULT_SIGNATURE, signatureResult);
- }
-
- } finally {
- is.close();
- os.close();
- }
-
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
- return result;
- } catch (Exception e) {
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_ERROR,
- new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
- return result;
- }
- }
-
- private Intent getKeyImpl(Intent data) {
- try {
- long keyId = data.getLongExtra(OpenPgpApi.EXTRA_KEY_ID, 0);
-
- if (ProviderHelper.getPGPPublicKeyRing(this, keyId) == null) {
- Intent result = new Intent();
-
- // If keys are not in db we return an additional PendingIntent
- // to retrieve the missing key
- Intent intent = new Intent(getBaseContext(), ImportKeysActivity.class);
- intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN);
- intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, keyId);
- intent.putExtra(ImportKeysActivity.EXTRA_PENDING_INTENT_DATA, data);
-
- PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
- intent,
- PendingIntent.FLAG_CANCEL_CURRENT);
-
- result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
- return result;
- } else {
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
-
- // TODO: also return PendingIntent that opens the key view activity
-
- return result;
- }
- } catch (Exception e) {
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_ERROR,
- new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
- return result;
- }
- }
-
- private Intent getKeyIdsImpl(Intent data) {
- // get key ids based on given user ids
- String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS);
- Intent result = getKeyIdsFromEmails(data, userIds);
- return result;
- }
-
- /**
- * Check requirements:
- * - params != null
- * - has supported API version
- * - is allowed to call the service (access has been granted)
- *
- * @param data
- * @return null if everything is okay, or a Bundle with an error/PendingIntent
- */
- private Intent checkRequirements(Intent data) {
- // params Bundle is required!
- if (data == null) {
- Intent result = new Intent();
- OpenPgpError error = new OpenPgpError(OpenPgpError.GENERIC_ERROR, "params Bundle required!");
- result.putExtra(OpenPgpApi.RESULT_ERROR, error);
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
- return result;
- }
-
- // version code is required and needs to correspond to version code of service!
- if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != OpenPgpApi.API_VERSION) {
- Intent result = new Intent();
- OpenPgpError error = new OpenPgpError
- (OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!");
- result.putExtra(OpenPgpApi.RESULT_ERROR, error);
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
- return result;
- }
-
- // check if caller is allowed to access openpgp keychain
- Intent result = isAllowed(data);
- if (result != null) {
- return result;
- }
-
- return null;
- }
-
- // TODO: multi-threading
- private final IOpenPgpService.Stub mBinder = new IOpenPgpService.Stub() {
-
- @Override
- public Intent execute(Intent data, ParcelFileDescriptor input, ParcelFileDescriptor output) {
- Intent errorResult = checkRequirements(data);
- if (errorResult != null) {
- return errorResult;
- }
-
- String accName;
- if (data.getStringExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME) != null) {
- accName = data.getStringExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME);
- } else {
- accName = "default";
- }
- final AccountSettings accSettings = getAccSettings(accName);
- if (accSettings == null) {
- return getCreateAccountIntent(data, accName);
- }
-
- String action = data.getAction();
- if (OpenPgpApi.ACTION_SIGN.equals(action)) {
- return signImpl(data, input, output, accSettings);
- } else if (OpenPgpApi.ACTION_ENCRYPT.equals(action)) {
- return encryptAndSignImpl(data, input, output, accSettings, false);
- } else if (OpenPgpApi.ACTION_SIGN_AND_ENCRYPT.equals(action)) {
- return encryptAndSignImpl(data, input, output, accSettings, true);
- } else if (OpenPgpApi.ACTION_DECRYPT_VERIFY.equals(action)) {
- String currentPkg = getCurrentCallingPackage();
- Set<Long> allowedKeyIds =
- ProviderHelper.getAllKeyIdsForApp(mContext,
- ApiAccounts.buildBaseUri(currentPkg));
- return decryptAndVerifyImpl(data, input, output, allowedKeyIds);
- } else if (OpenPgpApi.ACTION_GET_KEY.equals(action)) {
- return getKeyImpl(data);
- } else if (OpenPgpApi.ACTION_GET_KEY_IDS.equals(action)) {
- return getKeyIdsImpl(data);
- } else {
- return null;
- }
- }
-
- };
-
- @Override
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java
deleted file mode 100644
index 16a800022..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/RemoteService.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote;
-
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.Signature;
-import android.net.Uri;
-import android.os.Binder;
-
-import org.openintents.openpgp.OpenPgpError;
-import org.openintents.openpgp.util.OpenPgpApi;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * Abstract service class for remote APIs that handle app registration and user input.
- */
-public abstract class RemoteService extends Service {
- Context mContext;
-
- public Context getContext() {
- return mContext;
- }
-
- protected Intent isAllowed(Intent data) {
- try {
- if (isCallerAllowed(false)) {
- return null;
- } else {
- String packageName = getCurrentCallingPackage();
- Log.d(Constants.TAG, "isAllowed packageName: " + packageName);
-
- byte[] packageSignature;
- try {
- packageSignature = getPackageSignature(packageName);
- } catch (NameNotFoundException e) {
- Log.e(Constants.TAG, "Should not happen, returning!", e);
- // return error
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
- result.putExtra(OpenPgpApi.RESULT_ERROR,
- new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
- return result;
- }
- Log.e(Constants.TAG, "Not allowed to use service! return PendingIntent for registration!");
-
- Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
- intent.setAction(RemoteServiceActivity.ACTION_REGISTER);
- intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
- intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageSignature);
- intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
-
- PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
- intent,
- PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
-
- // return PendingIntent to be executed by client
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
- result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
-
- return result;
- }
- } catch (WrongPackageSignatureException e) {
- Log.e(Constants.TAG, "wrong signature!", e);
-
- Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
- intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE);
- intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE,
- getString(R.string.api_error_wrong_signature));
- intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
-
- PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
- intent,
- PendingIntent.FLAG_CANCEL_CURRENT);
-
- // return PendingIntent to be executed by client
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
- result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
-
- return result;
- }
- }
-
- private byte[] getPackageSignature(String packageName) throws NameNotFoundException {
- PackageInfo pkgInfo = getPackageManager().getPackageInfo(packageName,
- PackageManager.GET_SIGNATURES);
- Signature[] signatures = pkgInfo.signatures;
- // TODO: Only first signature?!
- byte[] packageSignature = signatures[0].toByteArray();
-
- return packageSignature;
- }
-
- /**
- * Returns package name associated with the UID, which is assigned to the process that sent you the
- * current transaction that is being processed :)
- *
- * @return package name
- */
- protected String getCurrentCallingPackage() {
- // TODO:
- // callingPackages contains more than one entry when sharedUserId has been used...
- String[] callingPackages = getPackageManager().getPackagesForUid(Binder.getCallingUid());
- String currentPkg = callingPackages[0];
- Log.d(Constants.TAG, "currentPkg: " + currentPkg);
-
- return currentPkg;
- }
-
- /**
- * Retrieves AccountSettings from database for the application calling this remote service
- *
- * @return
- */
- protected AccountSettings getAccSettings(String accountName) {
- String currentPkg = getCurrentCallingPackage();
- Log.d(Constants.TAG, "accountName: " + accountName);
-
- Uri uri = KeychainContract.ApiAccounts.buildByPackageAndAccountUri(currentPkg, accountName);
-
- AccountSettings settings = ProviderHelper.getApiAccountSettings(this, uri);
-
- return settings; // can be null!
- }
-
- protected Intent getCreateAccountIntent(Intent data, String accountName) {
- String packageName = getCurrentCallingPackage();
- Log.d(Constants.TAG, "accountName: " + accountName);
-
- Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
- intent.setAction(RemoteServiceActivity.ACTION_CREATE_ACCOUNT);
- intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
- intent.putExtra(RemoteServiceActivity.EXTRA_ACC_NAME, accountName);
- intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
-
- PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
- intent,
- PendingIntent.FLAG_CANCEL_CURRENT);
-
- // return PendingIntent to be executed by client
- Intent result = new Intent();
- result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
- result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
-
- return result;
- }
-
- /**
- * Checks if process that binds to this service (i.e. the package name corresponding to the
- * process) is in the list of allowed package names.
- *
- * @param allowOnlySelf allow only Keychain app itself
- * @return true if process is allowed to use this service
- * @throws WrongPackageSignatureException
- */
- private boolean isCallerAllowed(boolean allowOnlySelf) throws WrongPackageSignatureException {
- return isUidAllowed(Binder.getCallingUid(), allowOnlySelf);
- }
-
- private boolean isUidAllowed(int uid, boolean allowOnlySelf)
- throws WrongPackageSignatureException {
- if (android.os.Process.myUid() == uid) {
- return true;
- }
- if (allowOnlySelf) { // barrier
- return false;
- }
-
- String[] callingPackages = getPackageManager().getPackagesForUid(uid);
-
- // is calling package allowed to use this service?
- for (int i = 0; i < callingPackages.length; i++) {
- String currentPkg = callingPackages[i];
-
- if (isPackageAllowed(currentPkg)) {
- return true;
- }
- }
-
- Log.d(Constants.TAG, "Uid is NOT allowed!");
- return false;
- }
-
- /**
- * Checks if packageName is a registered app for the API. Does not return true for own package!
- *
- * @param packageName
- * @return
- * @throws WrongPackageSignatureException
- */
- private boolean isPackageAllowed(String packageName) throws WrongPackageSignatureException {
- Log.d(Constants.TAG, "isPackageAllowed packageName: " + packageName);
-
- ArrayList<String> allowedPkgs = ProviderHelper.getRegisteredApiApps(this);
- Log.d(Constants.TAG, "allowed: " + allowedPkgs);
-
- // check if package is allowed to use our service
- if (allowedPkgs.contains(packageName)) {
- Log.d(Constants.TAG, "Package is allowed! packageName: " + packageName);
-
- // check package signature
- byte[] currentSig;
- try {
- currentSig = getPackageSignature(packageName);
- } catch (NameNotFoundException e) {
- throw new WrongPackageSignatureException(e.getMessage());
- }
-
- byte[] storedSig = ProviderHelper.getApiAppSignature(this, packageName);
- if (Arrays.equals(currentSig, storedSig)) {
- Log.d(Constants.TAG,
- "Package signature is correct! (equals signature from database)");
- return true;
- } else {
- throw new WrongPackageSignatureException(
- "PACKAGE NOT ALLOWED! Signature wrong! (Signature not " +
- "equals signature from database)");
- }
- }
-
- Log.d(Constants.TAG, "Package is NOT allowed! packageName: " + packageName);
- return false;
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- mContext = this;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/WrongPackageSignatureException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/WrongPackageSignatureException.java
deleted file mode 100644
index 6f44a65e9..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/WrongPackageSignatureException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote;
-
-public class WrongPackageSignatureException extends Exception {
-
- private static final long serialVersionUID = -8294642703122196028L;
-
- public WrongPackageSignatureException(String message) {
- super(message);
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java
deleted file mode 100644
index 123ed526f..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote.ui;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v7.app.ActionBarActivity;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.ActionBarHelper;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.remote.AccountSettings;
-import org.sufficientlysecure.keychain.util.Log;
-
-public class AccountSettingsActivity extends ActionBarActivity {
- private Uri mAccountUri;
-
- private AccountSettingsFragment mAccountSettingsFragment;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Inflate a "Done" custom action bar
- ActionBarHelper.setOneButtonView(getSupportActionBar(),
- R.string.api_settings_save, R.drawable.ic_action_done,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // "Done"
- save();
- }
- });
-
- setContentView(R.layout.api_account_settings_activity);
-
- mAccountSettingsFragment = (AccountSettingsFragment) getSupportFragmentManager().findFragmentById(
- R.id.api_account_settings_fragment);
-
- Intent intent = getIntent();
- mAccountUri = intent.getData();
- if (mAccountUri == null) {
- Log.e(Constants.TAG, "Intent data missing. Should be Uri of app!");
- finish();
- return;
- } else {
- Log.d(Constants.TAG, "uri: " + mAccountUri);
- loadData(mAccountUri);
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- super.onCreateOptionsMenu(menu);
- getMenuInflater().inflate(R.menu.api_account_settings, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.menu_account_settings_delete:
- deleteAccount();
- return true;
- case R.id.menu_account_settings_cancel:
- finish();
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- private void loadData(Uri accountUri) {
- AccountSettings settings = ProviderHelper.getApiAccountSettings(this, accountUri);
- mAccountSettingsFragment.setAccSettings(settings);
- }
-
- private void deleteAccount() {
- if (getContentResolver().delete(mAccountUri, null, null) <= 0) {
- throw new RuntimeException();
- }
- finish();
- }
-
- private void save() {
- ProviderHelper.updateApiAccount(this, mAccountSettingsFragment.getAccSettings(), mAccountUri);
- finish();
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java
deleted file mode 100644
index 0a3ec3c3b..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote.ui;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemSelectedListener;
-import android.widget.Spinner;
-import android.widget.TextView;
-
-import com.beardedhen.androidbootstrap.BootstrapButton;
-
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.remote.AccountSettings;
-import org.sufficientlysecure.keychain.ui.EditKeyActivity;
-import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment;
-import org.sufficientlysecure.keychain.ui.adapter.KeyValueSpinnerAdapter;
-import org.sufficientlysecure.keychain.util.AlgorithmNames;
-
-public class AccountSettingsFragment extends Fragment implements
- SelectSecretKeyLayoutFragment.SelectSecretKeyCallback {
-
- private static final int REQUEST_CODE_CREATE_KEY = 0x00008884;
-
- // model
- private AccountSettings mAccSettings;
-
- // view
- private TextView mAccNameView;
- private Spinner mEncryptionAlgorithm;
- private Spinner mHashAlgorithm;
- private Spinner mCompression;
-
- private SelectSecretKeyLayoutFragment mSelectKeyFragment;
- private BootstrapButton mCreateKeyButton;
-
- KeyValueSpinnerAdapter mEncryptionAdapter;
- KeyValueSpinnerAdapter mHashAdapter;
- KeyValueSpinnerAdapter mCompressionAdapter;
-
- public AccountSettings getAccSettings() {
- return mAccSettings;
- }
-
- public void setAccSettings(AccountSettings accountSettings) {
- this.mAccSettings = accountSettings;
-
- mAccNameView.setText(accountSettings.getAccountName());
- mSelectKeyFragment.selectKey(accountSettings.getKeyId());
- mEncryptionAlgorithm.setSelection(mEncryptionAdapter.getPosition(accountSettings
- .getEncryptionAlgorithm()));
- mHashAlgorithm.setSelection(mHashAdapter.getPosition(accountSettings.getHashAlgorithm()));
- mCompression.setSelection(mCompressionAdapter.getPosition(accountSettings.getCompression()));
- }
-
- /**
- * Inflate the layout for this fragment
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.api_account_settings_fragment, container, false);
- initView(view);
- return view;
- }
-
- /**
- * Set error String on key selection
- *
- * @param error
- */
- public void setErrorOnSelectKeyFragment(String error) {
- mSelectKeyFragment.setError(error);
- }
-
- private void initView(View view) {
- mSelectKeyFragment = (SelectSecretKeyLayoutFragment) getFragmentManager().findFragmentById(
- R.id.api_account_settings_select_key_fragment);
- mSelectKeyFragment.setCallback(this);
-
- mAccNameView = (TextView) view.findViewById(R.id.api_account_settings_acc_name);
- mEncryptionAlgorithm = (Spinner) view
- .findViewById(R.id.api_account_settings_encryption_algorithm);
- mHashAlgorithm = (Spinner) view.findViewById(R.id.api_account_settings_hash_algorithm);
- mCompression = (Spinner) view.findViewById(R.id.api_account_settings_compression);
- mCreateKeyButton = (BootstrapButton) view.findViewById(R.id.api_account_settings_create_key);
-
- mCreateKeyButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- createKey();
- }
- });
-
- AlgorithmNames algorithmNames = new AlgorithmNames(getActivity());
-
- mEncryptionAdapter = new KeyValueSpinnerAdapter(getActivity(),
- algorithmNames.getEncryptionNames());
- mEncryptionAlgorithm.setAdapter(mEncryptionAdapter);
- mEncryptionAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() {
-
- @Override
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- mAccSettings.setEncryptionAlgorithm((int) id);
- }
-
- @Override
- public void onNothingSelected(AdapterView<?> parent) {
- }
- });
-
- mHashAdapter = new KeyValueSpinnerAdapter(getActivity(), algorithmNames.getHashNames());
- mHashAlgorithm.setAdapter(mHashAdapter);
- mHashAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() {
-
- @Override
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- mAccSettings.setHashAlgorithm((int) id);
- }
-
- @Override
- public void onNothingSelected(AdapterView<?> parent) {
- }
- });
-
- mCompressionAdapter = new KeyValueSpinnerAdapter(getActivity(),
- algorithmNames.getCompressionNames());
- mCompression.setAdapter(mCompressionAdapter);
- mCompression.setOnItemSelectedListener(new OnItemSelectedListener() {
-
- @Override
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- mAccSettings.setCompression((int) id);
- }
-
- @Override
- public void onNothingSelected(AdapterView<?> parent) {
- }
- });
- }
-
- private void createKey() {
- Intent intent = new Intent(getActivity(), EditKeyActivity.class);
- intent.setAction(EditKeyActivity.ACTION_CREATE_KEY);
- intent.putExtra(EditKeyActivity.EXTRA_GENERATE_DEFAULT_KEYS, true);
- // set default user id to account name
- intent.putExtra(EditKeyActivity.EXTRA_USER_IDS, mAccSettings.getAccountName());
- startActivityForResult(intent, REQUEST_CODE_CREATE_KEY);
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case REQUEST_CODE_CREATE_KEY: {
- if (resultCode == Activity.RESULT_OK) {
- // select newly created key
- long masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), data.getData());
- mSelectKeyFragment.selectKey(masterKeyId);
- }
- break;
- }
-
- default:
- super.onActivityResult(requestCode, resultCode, data);
-
- break;
- }
- }
-
- /**
- * callback from select secret key fragment
- */
- @Override
- public void onKeySelected(long secretKeyId) {
- mAccSettings.setKeyId(secretKeyId);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java
deleted file mode 100644
index 4d99e1923..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountsListFragment.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote.ui;
-
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.ListFragment;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.CursorLoader;
-import android.support.v4.content.Loader;
-import android.support.v4.widget.CursorAdapter;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.ui.widget.FixedListView;
-import org.sufficientlysecure.keychain.util.Log;
-
-public class AccountsListFragment extends ListFragment implements
- LoaderManager.LoaderCallbacks<Cursor> {
-
- private static final String ARG_DATA_URI = "uri";
-
- // This is the Adapter being used to display the list's data.
- AccountsAdapter mAdapter;
-
- private Uri mDataUri;
-
- /**
- * Creates new instance of this fragment
- */
- public static AccountsListFragment newInstance(Uri dataUri) {
- AccountsListFragment frag = new AccountsListFragment();
-
- Bundle args = new Bundle();
- args.putParcelable(ARG_DATA_URI, dataUri);
-
- frag.setArguments(args);
-
- return frag;
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View layout = super.onCreateView(inflater, container,
- savedInstanceState);
- ListView lv = (ListView) layout.findViewById(android.R.id.list);
- ViewGroup parent = (ViewGroup) lv.getParent();
-
- /*
- * http://stackoverflow.com/a/15880684
- * Remove ListView and add FixedListView in its place.
- * This is done here programatically to be still able to use the progressBar of ListFragment.
- *
- * We want FixedListView to be able to put this ListFragment inside a ScrollView
- */
- int lvIndex = parent.indexOfChild(lv);
- parent.removeViewAt(lvIndex);
- FixedListView newLv = new FixedListView(getActivity());
- newLv.setId(android.R.id.list);
- parent.addView(newLv, lvIndex, lv.getLayoutParams());
- return layout;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- mDataUri = getArguments().getParcelable(ARG_DATA_URI);
-
- getListView().setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
- String selectedAccountName = mAdapter.getItemAccountName(position);
- Uri accountUri = mDataUri.buildUpon().appendEncodedPath(selectedAccountName).build();
- Log.d(Constants.TAG, "accountUri: " + accountUri);
-
- // edit account settings
- Intent intent = new Intent(getActivity(), AccountSettingsActivity.class);
- intent.setData(accountUri);
- startActivity(intent);
- }
- });
-
- // Give some text to display if there is no data. In a real
- // application this would come from a resource.
- setEmptyText(getString(R.string.api_settings_accounts_empty));
-
- // We have a menu item to show in action bar.
- setHasOptionsMenu(true);
-
- // Create an empty adapter we will use to display the loaded data.
- mAdapter = new AccountsAdapter(getActivity(), null, 0);
- setListAdapter(mAdapter);
-
- // Prepare the loader. Either re-connect with an existing one,
- // or start a new one.
- getLoaderManager().initLoader(0, null, this);
- }
-
- // These are the Contacts rows that we will retrieve.
- static final String[] PROJECTION = new String[]{
- KeychainContract.ApiAccounts._ID, // 0
- KeychainContract.ApiAccounts.ACCOUNT_NAME // 1
- };
-
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- // This is called when a new Loader needs to be created. This
- // sample only has one Loader, so we don't care about the ID.
-
- // Now create and return a CursorLoader that will take care of
- // creating a Cursor for the data being displayed.
- return new CursorLoader(getActivity(), mDataUri, PROJECTION, null, null,
- KeychainContract.ApiAccounts.ACCOUNT_NAME + " COLLATE LOCALIZED ASC");
- }
-
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- // Swap the new cursor in. (The framework will take care of closing the
- // old cursor once we return.)
- mAdapter.swapCursor(data);
- }
-
- public void onLoaderReset(Loader<Cursor> loader) {
- // This is called when the last Cursor provided to onLoadFinished()
- // above is about to be closed. We need to make sure we are no
- // longer using it.
- mAdapter.swapCursor(null);
- }
-
- private class AccountsAdapter extends CursorAdapter {
- private LayoutInflater mInflater;
-
- public AccountsAdapter(Context context, Cursor c, int flags) {
- super(context, c, flags);
-
- mInflater = LayoutInflater.from(context);
- }
-
- /**
- * Similar to CursorAdapter.getItemId().
- * Required to build Uris for api accounts, which are not based on row ids
- *
- * @param position
- * @return
- */
- public String getItemAccountName(int position) {
- if (mDataValid && mCursor != null) {
- if (mCursor.moveToPosition(position)) {
- return mCursor.getString(1);
- } else {
- return null;
- }
- } else {
- return null;
- }
- }
-
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
- TextView text = (TextView) view.findViewById(R.id.api_accounts_adapter_item_name);
-
- String accountName = cursor.getString(1);
- text.setText(accountName);
- }
-
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(R.layout.api_accounts_adapter_list_item, null);
- }
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java
deleted file mode 100644
index 818c296c1..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote.ui;
-
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
-import android.view.Menu;
-import android.view.MenuItem;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.remote.AppSettings;
-import org.sufficientlysecure.keychain.util.Log;
-
-public class AppSettingsActivity extends ActionBarActivity {
- private Uri mAppUri;
-
- private AppSettingsFragment mSettingsFragment;
- private AccountsListFragment mAccountsListFragment;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // let the actionbar look like Android's contact app
- ActionBar actionBar = getSupportActionBar();
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setIcon(android.R.color.transparent);
- actionBar.setHomeButtonEnabled(true);
-
- setContentView(R.layout.api_app_settings_activity);
-
- mSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById(
- R.id.api_app_settings_fragment);
-
- Intent intent = getIntent();
- mAppUri = intent.getData();
- if (mAppUri == null) {
- Log.e(Constants.TAG, "Intent data missing. Should be Uri of app!");
- finish();
- return;
- } else {
- Log.d(Constants.TAG, "uri: " + mAppUri);
- loadData(savedInstanceState, mAppUri);
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- super.onCreateOptionsMenu(menu);
- getMenuInflater().inflate(R.menu.api_app_settings, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.menu_api_settings_revoke:
- revokeAccess();
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- private void loadData(Bundle savedInstanceState, Uri appUri) {
- AppSettings settings = ProviderHelper.getApiAppSettings(this, appUri);
- mSettingsFragment.setAppSettings(settings);
-
- String appName;
- PackageManager pm = getPackageManager();
- try {
- ApplicationInfo ai = pm.getApplicationInfo(settings.getPackageName(), 0);
- appName = (String) pm.getApplicationLabel(ai);
- } catch (PackageManager.NameNotFoundException e) {
- // fallback
- appName = settings.getPackageName();
- }
- setTitle(appName);
-
- Uri accountsUri = appUri.buildUpon().appendPath(KeychainContract.PATH_ACCOUNTS).build();
- Log.d(Constants.TAG, "accountsUri: " + accountsUri);
- startListFragment(savedInstanceState, accountsUri);
- }
-
- private void startListFragment(Bundle savedInstanceState, Uri dataUri) {
- // However, if we're being restored from a previous state,
- // then we don't need to do anything and should return or else
- // we could end up with overlapping fragments.
- if (savedInstanceState != null) {
- return;
- }
-
- // Create an instance of the fragment
- mAccountsListFragment = AccountsListFragment.newInstance(dataUri);
-
- // Add the fragment to the 'fragment_container' FrameLayout
- // NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
- getSupportFragmentManager().beginTransaction()
- .replace(R.id.api_accounts_list_fragment, mAccountsListFragment)
- .commitAllowingStateLoss();
- // do it immediately!
- getSupportFragmentManager().executePendingTransactions();
- }
-
- private void revokeAccess() {
- if (getContentResolver().delete(mAppUri, null, null) <= 0) {
- throw new RuntimeException();
- }
- finish();
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java
deleted file mode 100644
index a6db02708..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsFragment.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote.ui;
-
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import org.spongycastle.util.encoders.Hex;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.remote.AppSettings;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-public class AppSettingsFragment extends Fragment {
-
- // model
- private AppSettings mAppSettings;
-
- // view
- private TextView mAppNameView;
- private ImageView mAppIconView;
- private TextView mPackageName;
- private TextView mPackageSignature;
-
- public AppSettings getAppSettings() {
- return mAppSettings;
- }
-
- public void setAppSettings(AppSettings appSettings) {
- this.mAppSettings = appSettings;
- updateView(appSettings);
- }
-
- /**
- * Inflate the layout for this fragment
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.api_app_settings_fragment, container, false);
- mAppNameView = (TextView) view.findViewById(R.id.api_app_settings_app_name);
- mAppIconView = (ImageView) view.findViewById(R.id.api_app_settings_app_icon);
- mPackageName = (TextView) view.findViewById(R.id.api_app_settings_package_name);
- mPackageSignature = (TextView) view.findViewById(R.id.api_app_settings_package_signature);
- return view;
- }
-
- private void updateView(AppSettings appSettings) {
- // get application name and icon from package manager
- String appName;
- Drawable appIcon = null;
- PackageManager pm = getActivity().getApplicationContext().getPackageManager();
- try {
- ApplicationInfo ai = pm.getApplicationInfo(appSettings.getPackageName(), 0);
-
- appName = (String) pm.getApplicationLabel(ai);
- appIcon = pm.getApplicationIcon(ai);
- } catch (NameNotFoundException e) {
- // fallback
- appName = appSettings.getPackageName();
- }
- mAppNameView.setText(appName);
- mAppIconView.setImageDrawable(appIcon);
-
- // advanced info: package name
- mPackageName.setText(appSettings.getPackageName());
-
- // advanced info: package signature SHA-256
- try {
- MessageDigest md = MessageDigest.getInstance("SHA-256");
- md.update(appSettings.getPackageSignature());
- byte[] digest = md.digest();
- String signature = new String(Hex.encode(digest));
-
- mPackageSignature.setText(signature);
- } catch (NoSuchAlgorithmException e) {
- Log.e(Constants.TAG, "Should not happen!", e);
- }
- }
-
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java
deleted file mode 100644
index f86d279f0..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListActivity.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote.ui;
-
-import android.os.Bundle;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.ui.DrawerActivity;
-
-public class AppsListActivity extends DrawerActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.api_apps_list_activity);
-
- setupDrawerNavigation(savedInstanceState);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java
deleted file mode 100644
index 9d0e6d3ef..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote.ui;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.ListFragment;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.CursorLoader;
-import android.support.v4.content.Loader;
-import android.support.v4.widget.CursorAdapter;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
-
-public class AppsListFragment extends ListFragment implements
- LoaderManager.LoaderCallbacks<Cursor> {
-
- // This is the Adapter being used to display the list's data.
- RegisteredAppsAdapter mAdapter;
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- getListView().setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
- String selectedPackageName = mAdapter.getItemPackageName(position);
- // edit app settings
- Intent intent = new Intent(getActivity(), AppSettingsActivity.class);
- intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(selectedPackageName));
- startActivity(intent);
- }
- });
-
- // Give some text to display if there is no data. In a real
- // application this would come from a resource.
- setEmptyText(getString(R.string.api_no_apps));
-
- // We have a menu item to show in action bar.
- setHasOptionsMenu(true);
-
- // Create an empty adapter we will use to display the loaded data.
- mAdapter = new RegisteredAppsAdapter(getActivity(), null, 0);
- setListAdapter(mAdapter);
-
- // Prepare the loader. Either re-connect with an existing one,
- // or start a new one.
- getLoaderManager().initLoader(0, null, this);
- }
-
- // These are the Contacts rows that we will retrieve.
- static final String[] PROJECTION = new String[]{
- ApiApps._ID, // 0
- ApiApps.PACKAGE_NAME // 1
- };
-
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- // This is called when a new Loader needs to be created. This
- // sample only has one Loader, so we don't care about the ID.
- // First, pick the base URI to use depending on whether we are
- // currently filtering.
- Uri baseUri = ApiApps.CONTENT_URI;
-
- // Now create and return a CursorLoader that will take care of
- // creating a Cursor for the data being displayed.
- return new CursorLoader(getActivity(), baseUri, PROJECTION, null, null,
- ApiApps.PACKAGE_NAME + " COLLATE LOCALIZED ASC");
- }
-
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- // Swap the new cursor in. (The framework will take care of closing the
- // old cursor once we return.)
- mAdapter.swapCursor(data);
- }
-
- public void onLoaderReset(Loader<Cursor> loader) {
- // This is called when the last Cursor provided to onLoadFinished()
- // above is about to be closed. We need to make sure we are no
- // longer using it.
- mAdapter.swapCursor(null);
- }
-
- private class RegisteredAppsAdapter extends CursorAdapter {
-
- private LayoutInflater mInflater;
- private PackageManager mPM;
-
- public RegisteredAppsAdapter(Context context, Cursor c, int flags) {
- super(context, c, flags);
-
- mInflater = LayoutInflater.from(context);
- mPM = context.getApplicationContext().getPackageManager();
- }
-
- /**
- * Similar to CursorAdapter.getItemId().
- * Required to build Uris for api apps, which are not based on row ids
- *
- * @param position
- * @return
- */
- public String getItemPackageName(int position) {
- if (mDataValid && mCursor != null) {
- if (mCursor.moveToPosition(position)) {
- return mCursor.getString(1);
- } else {
- return null;
- }
- } else {
- return null;
- }
- }
-
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
- TextView text = (TextView) view.findViewById(R.id.api_apps_adapter_item_name);
- ImageView icon = (ImageView) view.findViewById(R.id.api_apps_adapter_item_icon);
-
- String packageName = cursor.getString(cursor.getColumnIndex(ApiApps.PACKAGE_NAME));
- if (packageName != null) {
- // get application name
- try {
- ApplicationInfo ai = mPM.getApplicationInfo(packageName, 0);
-
- text.setText(mPM.getApplicationLabel(ai));
- icon.setImageDrawable(mPM.getApplicationIcon(ai));
- } catch (final PackageManager.NameNotFoundException e) {
- // fallback
- text.setText(packageName);
- }
- } else {
- // fallback
- text.setText(packageName);
- }
-
- }
-
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(R.layout.api_apps_adapter_list_item, null);
- }
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
deleted file mode 100644
index ab95f2691..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.remote.ui;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.support.v7.app.ActionBarActivity;
-import android.view.View;
-
-import org.openintents.openpgp.util.OpenPgpApi;
-import org.sufficientlysecure.htmltextview.HtmlTextView;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.ActionBarHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.remote.AccountSettings;
-import org.sufficientlysecure.keychain.remote.AppSettings;
-import org.sufficientlysecure.keychain.ui.SelectPublicKeyFragment;
-import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.util.ArrayList;
-
-public class RemoteServiceActivity extends ActionBarActivity {
-
- public static final String ACTION_REGISTER = Constants.INTENT_PREFIX + "API_ACTIVITY_REGISTER";
- public static final String ACTION_CREATE_ACCOUNT = Constants.INTENT_PREFIX
- + "API_ACTIVITY_CREATE_ACCOUNT";
- public static final String ACTION_CACHE_PASSPHRASE = Constants.INTENT_PREFIX
- + "API_ACTIVITY_CACHE_PASSPHRASE";
- public static final String ACTION_SELECT_PUB_KEYS = Constants.INTENT_PREFIX
- + "API_ACTIVITY_SELECT_PUB_KEYS";
- public static final String ACTION_ERROR_MESSAGE = Constants.INTENT_PREFIX
- + "API_ACTIVITY_ERROR_MESSAGE";
-
- public static final String EXTRA_MESSENGER = "messenger";
-
- public static final String EXTRA_DATA = "data";
-
- // passphrase action
- public static final String EXTRA_SECRET_KEY_ID = "secret_key_id";
- // register action
- public static final String EXTRA_PACKAGE_NAME = "package_name";
- public static final String EXTRA_PACKAGE_SIGNATURE = "package_signature";
- // create acc action
- public static final String EXTRA_ACC_NAME = "acc_name";
- // select pub keys action
- public static final String EXTRA_SELECTED_MASTER_KEY_IDS = "master_key_ids";
- public static final String EXTRA_MISSING_USER_IDS = "missing_user_ids";
- public static final String EXTRA_DUBLICATE_USER_IDS = "dublicate_user_ids";
- // error message
- public static final String EXTRA_ERROR_MESSAGE = "error_message";
-
- // register view
- private AppSettingsFragment mAppSettingsFragment;
- // create acc view
- private AccountSettingsFragment mAccSettingsFragment;
- // select pub keys view
- private SelectPublicKeyFragment mSelectFragment;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- handleActions(getIntent(), savedInstanceState);
- }
-
- protected void handleActions(Intent intent, Bundle savedInstanceState) {
-
- String action = intent.getAction();
- final Bundle extras = intent.getExtras();
-
-
- if (ACTION_REGISTER.equals(action)) {
- final String packageName = extras.getString(EXTRA_PACKAGE_NAME);
- final byte[] packageSignature = extras.getByteArray(EXTRA_PACKAGE_SIGNATURE);
- Log.d(Constants.TAG, "ACTION_REGISTER packageName: " + packageName);
-
- // Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setTwoButtonView(getSupportActionBar(),
- R.string.api_register_allow, R.drawable.ic_action_done,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // Allow
-
- ProviderHelper.insertApiApp(RemoteServiceActivity.this,
- mAppSettingsFragment.getAppSettings());
-
- // give data through for new service call
- Intent resultData = extras.getParcelable(EXTRA_DATA);
- RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
- RemoteServiceActivity.this.finish();
- }
- }, R.string.api_register_disallow, R.drawable.ic_action_cancel,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // Disallow
- RemoteServiceActivity.this.setResult(RESULT_CANCELED);
- RemoteServiceActivity.this.finish();
- }
- }
- );
-
- setContentView(R.layout.api_remote_register_app);
-
- mAppSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById(
- R.id.api_app_settings_fragment);
-
- AppSettings settings = new AppSettings(packageName, packageSignature);
- mAppSettingsFragment.setAppSettings(settings);
- } else if (ACTION_CREATE_ACCOUNT.equals(action)) {
- final String packageName = extras.getString(EXTRA_PACKAGE_NAME);
- final String accName = extras.getString(EXTRA_ACC_NAME);
-
- // Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setTwoButtonView(getSupportActionBar(),
- R.string.api_settings_save, R.drawable.ic_action_done,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // Save
-
- // user needs to select a key!
- if (mAccSettingsFragment.getAccSettings().getKeyId() == Id.key.none) {
- mAccSettingsFragment.setErrorOnSelectKeyFragment(
- getString(R.string.api_register_error_select_key));
- } else {
- ProviderHelper.insertApiAccount(RemoteServiceActivity.this,
- KeychainContract.ApiAccounts.buildBaseUri(packageName),
- mAccSettingsFragment.getAccSettings());
-
- // give data through for new service call
- Intent resultData = extras.getParcelable(EXTRA_DATA);
- RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
- RemoteServiceActivity.this.finish();
- }
- }
- }, R.string.api_settings_cancel, R.drawable.ic_action_cancel,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // Cancel
- RemoteServiceActivity.this.setResult(RESULT_CANCELED);
- RemoteServiceActivity.this.finish();
- }
- }
- );
-
- setContentView(R.layout.api_remote_create_account);
-
- mAccSettingsFragment = (AccountSettingsFragment) getSupportFragmentManager().findFragmentById(
- R.id.api_account_settings_fragment);
-
- AccountSettings settings = new AccountSettings(accName);
- mAccSettingsFragment.setAccSettings(settings);
- } else if (ACTION_CACHE_PASSPHRASE.equals(action)) {
- long secretKeyId = extras.getLong(EXTRA_SECRET_KEY_ID);
- final Intent resultData = extras.getParcelable(EXTRA_DATA);
-
- PassphraseDialogFragment.show(this, secretKeyId,
- new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
- // return given params again, for calling the service method again
- RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
- } else {
- RemoteServiceActivity.this.setResult(RESULT_CANCELED);
- }
-
- RemoteServiceActivity.this.finish();
- }
- });
-
- } else if (ACTION_SELECT_PUB_KEYS.equals(action)) {
- long[] selectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS);
- ArrayList<String> missingUserIds = intent
- .getStringArrayListExtra(EXTRA_MISSING_USER_IDS);
- ArrayList<String> dublicateUserIds = intent
- .getStringArrayListExtra(EXTRA_DUBLICATE_USER_IDS);
-
- // TODO: do this with spannable instead of HTML to prevent parsing failures with weird user ids
- String text = "<b>" + getString(R.string.api_select_pub_keys_text) + "</b>";
- text += "<br/><br/>";
- if (missingUserIds != null && missingUserIds.size() > 0) {
- text += getString(R.string.api_select_pub_keys_missing_text);
- text += "<br/>";
- text += "<ul>";
- for (String userId : missingUserIds) {
- text += "<li>" + userId + "</li>";
- }
- text += "</ul>";
- text += "<br/>";
- }
- if (dublicateUserIds != null && dublicateUserIds.size() > 0) {
- text += getString(R.string.api_select_pub_keys_dublicates_text);
- text += "<br/>";
- text += "<ul>";
- for (String userId : dublicateUserIds) {
- text += "<li>" + userId + "</li>";
- }
- text += "</ul>";
- }
-
- // Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setTwoButtonView(getSupportActionBar(),
- R.string.btn_okay, R.drawable.ic_action_done,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // add key ids to params Bundle for new request
- Intent resultData = extras.getParcelable(EXTRA_DATA);
- resultData.putExtra(OpenPgpApi.EXTRA_KEY_IDS,
- mSelectFragment.getSelectedMasterKeyIds());
-
- RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
- RemoteServiceActivity.this.finish();
- }
- }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // cancel
- RemoteServiceActivity.this.setResult(RESULT_CANCELED);
- RemoteServiceActivity.this.finish();
- }
- }
- );
-
- setContentView(R.layout.api_remote_select_pub_keys);
-
- // set text on view
- HtmlTextView textView = (HtmlTextView) findViewById(R.id.api_select_pub_keys_text);
- textView.setHtmlFromString(text);
-
- /* Load select pub keys fragment */
- // Check that the activity is using the layout version with
- // the fragment_container FrameLayout
- if (findViewById(R.id.api_select_pub_keys_fragment_container) != null) {
-
- // However, if we're being restored from a previous state,
- // then we don't need to do anything and should return or else
- // we could end up with overlapping fragments.
- if (savedInstanceState != null) {
- return;
- }
-
- // Create an instance of the fragment
- mSelectFragment = SelectPublicKeyFragment.newInstance(selectedMasterKeyIds);
-
- // Add the fragment to the 'fragment_container' FrameLayout
- getSupportFragmentManager().beginTransaction()
- .add(R.id.api_select_pub_keys_fragment_container, mSelectFragment).commit();
- }
- } else if (ACTION_ERROR_MESSAGE.equals(action)) {
- String errorMessage = intent.getStringExtra(EXTRA_ERROR_MESSAGE);
-
- String text = "<font color=\"red\">" + errorMessage + "</font>";
-
- // Inflate a "Done" custom action bar view
- ActionBarHelper.setOneButtonView(getSupportActionBar(),
- R.string.btn_okay, R.drawable.ic_action_done,
- new View.OnClickListener() {
-
- @Override
- public void onClick(View v) {
- RemoteServiceActivity.this.setResult(RESULT_CANCELED);
- RemoteServiceActivity.this.finish();
- }
- });
-
- setContentView(R.layout.api_remote_error_message);
-
- // set text on view
- HtmlTextView textView = (HtmlTextView) findViewById(R.id.api_app_error_message_text);
- textView.setHtmlFromString(text);
- } else {
- Log.e(Constants.TAG, "Action does not exist!");
- setResult(RESULT_CANCELED);
- finish();
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
deleted file mode 100644
index 1c6aa7971..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
+++ /dev/null
@@ -1,905 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.service;
-
-import android.app.IntentService;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-
-import org.spongycastle.bcpg.sig.KeyFlags;
-import org.spongycastle.openpgp.PGPKeyRing;
-import org.spongycastle.openpgp.PGPObjectFactory;
-import org.spongycastle.openpgp.PGPPublicKey;
-import org.spongycastle.openpgp.PGPPublicKeyRing;
-import org.spongycastle.openpgp.PGPSecretKey;
-import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.spongycastle.openpgp.PGPUtil;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.FileHelper;
-import org.sufficientlysecure.keychain.helper.OtherHelper;
-import org.sufficientlysecure.keychain.helper.Preferences;
-import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
-import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
-import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
-import org.sufficientlysecure.keychain.pgp.PgpHelper;
-import org.sufficientlysecure.keychain.pgp.PgpImportExport;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
-import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.KeychainDatabase;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
-import org.sufficientlysecure.keychain.util.HkpKeyServer;
-import org.sufficientlysecure.keychain.util.InputData;
-import org.sufficientlysecure.keychain.util.KeychainServiceListener;
-import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
-import org.sufficientlysecure.keychain.util.ProgressScaler;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This Service contains all important long lasting operations for APG. It receives Intents with
- * data from the activities or other apps, queues these intents, executes them, and stops itself
- * after doing them.
- */
-public class KeychainIntentService extends IntentService
- implements ProgressDialogUpdater, KeychainServiceListener {
-
- /* extras that can be given by intent */
- public static final String EXTRA_MESSENGER = "messenger";
- public static final String EXTRA_DATA = "data";
-
- /* possible actions */
- public static final String ACTION_ENCRYPT_SIGN = Constants.INTENT_PREFIX + "ENCRYPT_SIGN";
-
- public static final String ACTION_DECRYPT_VERIFY = Constants.INTENT_PREFIX + "DECRYPT_VERIFY";
-
- public static final String ACTION_SAVE_KEYRING = Constants.INTENT_PREFIX + "SAVE_KEYRING";
- public static final String ACTION_GENERATE_KEY = Constants.INTENT_PREFIX + "GENERATE_KEY";
- public static final String ACTION_GENERATE_DEFAULT_RSA_KEYS = Constants.INTENT_PREFIX
- + "GENERATE_DEFAULT_RSA_KEYS";
-
- public static final String ACTION_DELETE_FILE_SECURELY = Constants.INTENT_PREFIX
- + "DELETE_FILE_SECURELY";
-
- public static final String ACTION_IMPORT_KEYRING = Constants.INTENT_PREFIX + "IMPORT_KEYRING";
- public static final String ACTION_EXPORT_KEYRING = Constants.INTENT_PREFIX + "EXPORT_KEYRING";
-
- public static final String ACTION_UPLOAD_KEYRING = Constants.INTENT_PREFIX + "UPLOAD_KEYRING";
- public static final String ACTION_DOWNLOAD_AND_IMPORT_KEYS = Constants.INTENT_PREFIX + "QUERY_KEYRING";
-
- public static final String ACTION_CERTIFY_KEYRING = Constants.INTENT_PREFIX + "SIGN_KEYRING";
-
- /* keys for data bundle */
-
- // encrypt, decrypt, import export
- public static final String TARGET = "target";
- // possible targets:
- public static final int TARGET_BYTES = 1;
- public static final int TARGET_URI = 2;
-
- // encrypt
- public static final String ENCRYPT_SIGNATURE_KEY_ID = "secret_key_id";
- public static final String ENCRYPT_USE_ASCII_ARMOR = "use_ascii_armor";
- public static final String ENCRYPT_ENCRYPTION_KEYS_IDS = "encryption_keys_ids";
- public static final String ENCRYPT_COMPRESSION_ID = "compression_id";
- public static final String ENCRYPT_MESSAGE_BYTES = "message_bytes";
- public static final String ENCRYPT_INPUT_FILE = "input_file";
- public static final String ENCRYPT_OUTPUT_FILE = "output_file";
- public static final String ENCRYPT_SYMMETRIC_PASSPHRASE = "passphrase";
-
- // decrypt/verify
- public static final String DECRYPT_CIPHERTEXT_BYTES = "ciphertext_bytes";
- public static final String DECRYPT_PASSPHRASE = "passphrase";
-
- // save keyring
- public static final String SAVE_KEYRING_PARCEL = "save_parcel";
- public static final String SAVE_KEYRING_CAN_SIGN = "can_sign";
-
-
- // generate key
- public static final String GENERATE_KEY_ALGORITHM = "algorithm";
- public static final String GENERATE_KEY_KEY_SIZE = "key_size";
- public static final String GENERATE_KEY_SYMMETRIC_PASSPHRASE = "passphrase";
- public static final String GENERATE_KEY_MASTER_KEY = "master_key";
-
- // delete file securely
- public static final String DELETE_FILE = "deleteFile";
-
- // import key
- public static final String IMPORT_KEY_LIST = "import_key_list";
-
- // export key
- public static final String EXPORT_OUTPUT_STREAM = "export_output_stream";
- public static final String EXPORT_FILENAME = "export_filename";
- public static final String EXPORT_SECRET = "export_secret";
- public static final String EXPORT_ALL = "export_all";
- public static final String EXPORT_KEY_RING_MASTER_KEY_ID = "export_key_ring_id";
-
- // upload key
- public static final String UPLOAD_KEY_SERVER = "upload_key_server";
-
- // query key
- public static final String DOWNLOAD_KEY_SERVER = "query_key_server";
- public static final String DOWNLOAD_KEY_LIST = "query_key_id";
-
- // sign key
- public static final String CERTIFY_KEY_MASTER_KEY_ID = "sign_key_master_key_id";
- public static final String CERTIFY_KEY_PUB_KEY_ID = "sign_key_pub_key_id";
- public static final String CERTIFY_KEY_UIDS = "sign_key_uids";
-
- /*
- * possible data keys as result send over messenger
- */
- // keys
- public static final String RESULT_NEW_KEY = "new_key";
- public static final String RESULT_KEY_USAGES = "new_key_usages";
-
- // encrypt
- public static final String RESULT_BYTES = "encrypted_data";
-
- // decrypt/verify
- public static final String RESULT_DECRYPTED_BYTES = "decrypted_data";
- public static final String RESULT_DECRYPT_VERIFY_RESULT = "signature";
-
- // import
- public static final String RESULT_IMPORT_ADDED = "added";
- public static final String RESULT_IMPORT_UPDATED = "updated";
- public static final String RESULT_IMPORT_BAD = "bad";
-
- // export
- public static final String RESULT_EXPORT = "exported";
-
- Messenger mMessenger;
-
- private boolean mIsCanceled;
-
- public KeychainIntentService() {
- super("KeychainIntentService");
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- this.mIsCanceled = true;
- }
-
- /**
- * The IntentService calls this method from the default worker thread with the intent that
- * started the service. When this method returns, IntentService stops the service, as
- * appropriate.
- */
- @Override
- protected void onHandleIntent(Intent intent) {
- Bundle extras = intent.getExtras();
- if (extras == null) {
- Log.e(Constants.TAG, "Extras bundle is null!");
- return;
- }
-
- if (!(extras.containsKey(EXTRA_MESSENGER) || extras.containsKey(EXTRA_DATA) || (intent
- .getAction() == null))) {
- Log.e(Constants.TAG,
- "Extra bundle must contain a messenger, a data bundle, and an action!");
- return;
- }
-
- Uri dataUri = intent.getData();
-
- mMessenger = (Messenger) extras.get(EXTRA_MESSENGER);
- Bundle data = extras.getBundle(EXTRA_DATA);
-
- OtherHelper.logDebugBundle(data, "EXTRA_DATA");
-
- String action = intent.getAction();
-
- // executeServiceMethod action from extra bundle
- if (ACTION_ENCRYPT_SIGN.equals(action)) {
- try {
- /* Input */
- int target = data.getInt(TARGET);
-
- long signatureKeyId = data.getLong(ENCRYPT_SIGNATURE_KEY_ID);
- String symmetricPassphrase = data.getString(ENCRYPT_SYMMETRIC_PASSPHRASE);
-
- boolean useAsciiArmor = data.getBoolean(ENCRYPT_USE_ASCII_ARMOR);
- long encryptionKeyIds[] = data.getLongArray(ENCRYPT_ENCRYPTION_KEYS_IDS);
- int compressionId = data.getInt(ENCRYPT_COMPRESSION_ID);
- InputStream inStream;
- long inLength;
- InputData inputData;
- OutputStream outStream;
-// String streamFilename = null;
- switch (target) {
- case TARGET_BYTES: /* encrypting bytes directly */
- byte[] bytes = data.getByteArray(ENCRYPT_MESSAGE_BYTES);
-
- inStream = new ByteArrayInputStream(bytes);
- inLength = bytes.length;
-
- inputData = new InputData(inStream, inLength);
- outStream = new ByteArrayOutputStream();
-
- break;
- case TARGET_URI: /* encrypting file */
- String inputFile = data.getString(ENCRYPT_INPUT_FILE);
- String outputFile = data.getString(ENCRYPT_OUTPUT_FILE);
-
- // check if storage is ready
- if (!FileHelper.isStorageMounted(inputFile)
- || !FileHelper.isStorageMounted(outputFile)) {
- throw new PgpGeneralException(
- getString(R.string.error_external_storage_not_ready));
- }
-
- inStream = new FileInputStream(inputFile);
- File file = new File(inputFile);
- inLength = file.length();
- inputData = new InputData(inStream, inLength);
-
- outStream = new FileOutputStream(outputFile);
-
- break;
-
- // TODO: not used currently
-// case TARGET_STREAM: /* Encrypting stream from content uri */
-// Uri providerUri = (Uri) data.getParcelable(ENCRYPT_PROVIDER_URI);
-//
-// // InputStream
-// InputStream in = getContentResolver().openInputStream(providerUri);
-// inLength = PgpHelper.getLengthOfStream(in);
-// inputData = new InputData(in, inLength);
-//
-// // OutputStream
-// try {
-// while (true) {
-// streamFilename = PgpHelper.generateRandomFilename(32);
-// if (streamFilename == null) {
-// throw new PgpGeneralException("couldn't generate random file name");
-// }
-// openFileInput(streamFilename).close();
-// }
-// } catch (FileNotFoundException e) {
-// // found a name that isn't used yet
-// }
-// outStream = openFileOutput(streamFilename, Context.MODE_PRIVATE);
-//
-// break;
-
- default:
- throw new PgpGeneralException("No target choosen!");
-
- }
-
- /* Operation */
- PgpSignEncrypt.Builder builder =
- new PgpSignEncrypt.Builder(this, inputData, outStream);
- builder.progress(this);
-
- builder.enableAsciiArmorOutput(useAsciiArmor)
- .compressionId(compressionId)
- .symmetricEncryptionAlgorithm(
- Preferences.getPreferences(this).getDefaultEncryptionAlgorithm())
- .signatureForceV3(Preferences.getPreferences(this).getForceV3Signatures())
- .encryptionKeyIds(encryptionKeyIds)
- .symmetricPassphrase(symmetricPassphrase)
- .signatureKeyId(signatureKeyId)
- .signatureHashAlgorithm(
- Preferences.getPreferences(this).getDefaultHashAlgorithm())
- .signaturePassphrase(
- PassphraseCacheService.getCachedPassphrase(this, signatureKeyId));
-
- builder.build().execute();
-
- outStream.close();
-
- /* Output */
-
- Bundle resultData = new Bundle();
-
- switch (target) {
- case TARGET_BYTES:
- byte output[] = ((ByteArrayOutputStream) outStream).toByteArray();
-
- resultData.putByteArray(RESULT_BYTES, output);
-
- break;
- case TARGET_URI:
- // nothing, file was written, just send okay
-
- break;
-// case TARGET_STREAM:
-// String uri = DataStream.buildDataStreamUri(streamFilename).toString();
-// resultData.putString(RESULT_URI, uri);
-//
-// break;
- }
-
- OtherHelper.logDebugBundle(resultData, "resultData");
-
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
- } catch (Exception e) {
- sendErrorToHandler(e);
- }
- } else if (ACTION_DECRYPT_VERIFY.equals(action)) {
- try {
- /* Input */
- int target = data.getInt(TARGET);
-
- byte[] bytes = data.getByteArray(DECRYPT_CIPHERTEXT_BYTES);
- String passphrase = data.getString(DECRYPT_PASSPHRASE);
-
- InputStream inStream;
- long inLength;
- InputData inputData;
- OutputStream outStream;
- String streamFilename = null;
- switch (target) {
- case TARGET_BYTES: /* decrypting bytes directly */
- inStream = new ByteArrayInputStream(bytes);
- inLength = bytes.length;
-
- inputData = new InputData(inStream, inLength);
- outStream = new ByteArrayOutputStream();
-
- break;
-
- case TARGET_URI: /* decrypting file */
- String inputFile = data.getString(ENCRYPT_INPUT_FILE);
- String outputFile = data.getString(ENCRYPT_OUTPUT_FILE);
-
- // check if storage is ready
- if (!FileHelper.isStorageMounted(inputFile)
- || !FileHelper.isStorageMounted(outputFile)) {
- throw new PgpGeneralException(
- getString(R.string.error_external_storage_not_ready));
- }
-
- // InputStream
- inLength = -1;
- inStream = new FileInputStream(inputFile);
- File file = new File(inputFile);
- inLength = file.length();
- inputData = new InputData(inStream, inLength);
-
- // OutputStream
- outStream = new FileOutputStream(outputFile);
-
- break;
-
- // TODO: not used, maybe contains code useful for new decrypt method for files?
-// case TARGET_STREAM: /* decrypting stream from content uri */
-// Uri providerUri = (Uri) data.getParcelable(ENCRYPT_PROVIDER_URI);
-//
-// // InputStream
-// InputStream in = getContentResolver().openInputStream(providerUri);
-// inLength = PgpHelper.getLengthOfStream(in);
-// inputData = new InputData(in, inLength);
-//
-// // OutputStream
-// try {
-// while (true) {
-// streamFilename = PgpHelper.generateRandomFilename(32);
-// if (streamFilename == null) {
-// throw new PgpGeneralException("couldn't generate random file name");
-// }
-// openFileInput(streamFilename).close();
-// }
-// } catch (FileNotFoundException e) {
-// // found a name that isn't used yet
-// }
-// outStream = openFileOutput(streamFilename, Context.MODE_PRIVATE);
-//
-// break;
-
- default:
- throw new PgpGeneralException("No target choosen!");
-
- }
-
- /* Operation */
-
- Bundle resultData = new Bundle();
-
- // verifyText and decrypt returning additional resultData values for the
- // verification of signatures
- PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, outStream);
- builder.progressDialogUpdater(this);
-
- builder.allowSymmetricDecryption(true)
- .passphrase(passphrase);
-
- PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute();
-
- outStream.close();
-
- resultData.putParcelable(RESULT_DECRYPT_VERIFY_RESULT, decryptVerifyResult);
-
- /* Output */
-
- switch (target) {
- case TARGET_BYTES:
- byte output[] = ((ByteArrayOutputStream) outStream).toByteArray();
- resultData.putByteArray(RESULT_DECRYPTED_BYTES, output);
- break;
- case TARGET_URI:
- // nothing, file was written, just send okay and verification bundle
-
- break;
-// case TARGET_STREAM:
-// String uri = DataStream.buildDataStreamUri(streamFilename).toString();
-// resultData.putString(RESULT_URI, uri);
-//
-// break;
- }
-
- OtherHelper.logDebugBundle(resultData, "resultData");
-
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
- } catch (Exception e) {
- sendErrorToHandler(e);
- }
- } else if (ACTION_SAVE_KEYRING.equals(action)) {
- try {
- /* Input */
- SaveKeyringParcel saveParams = data.getParcelable(SAVE_KEYRING_PARCEL);
- String oldPassphrase = saveParams.oldPassphrase;
- String newPassphrase = saveParams.newPassphrase;
- boolean canSign = true;
-
- if (data.containsKey(SAVE_KEYRING_CAN_SIGN)) {
- canSign = data.getBoolean(SAVE_KEYRING_CAN_SIGN);
- }
-
- if (newPassphrase == null) {
- newPassphrase = oldPassphrase;
- }
-
- long masterKeyId = saveParams.keys.get(0).getKeyID();
-
- /* Operation */
- if (!canSign) {
- PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 50, 100));
- PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRing(this, masterKeyId);
- keyRing = keyOperations.changeSecretKeyPassphrase(keyRing,
- oldPassphrase, newPassphrase);
- setProgress(R.string.progress_saving_key_ring, 50, 100);
- ProviderHelper.saveKeyRing(this, keyRing);
- setProgress(R.string.progress_done, 100, 100);
- } else {
- PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 90, 100));
- PGPSecretKeyRing privkey = ProviderHelper.getPGPSecretKeyRing(this, masterKeyId);
- PGPPublicKeyRing pubkey = ProviderHelper.getPGPPublicKeyRing(this, masterKeyId);
- PgpKeyOperation.Pair<PGPSecretKeyRing,PGPPublicKeyRing> pair =
- keyOperations.buildSecretKey(privkey, pubkey, saveParams);
- setProgress(R.string.progress_saving_key_ring, 90, 100);
- // save the pair
- ProviderHelper.saveKeyRing(this, pair.second, pair.first);
- setProgress(R.string.progress_done, 100, 100);
- }
- PassphraseCacheService.addCachedPassphrase(this, masterKeyId, newPassphrase);
-
- /* Output */
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY);
- } catch (Exception e) {
- sendErrorToHandler(e);
- }
- } else if (ACTION_GENERATE_KEY.equals(action)) {
- try {
- /* Input */
- int algorithm = data.getInt(GENERATE_KEY_ALGORITHM);
- String passphrase = data.getString(GENERATE_KEY_SYMMETRIC_PASSPHRASE);
- int keysize = data.getInt(GENERATE_KEY_KEY_SIZE);
- boolean masterKey = data.getBoolean(GENERATE_KEY_MASTER_KEY);
-
- /* Operation */
- PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 100, 100));
- PGPSecretKey newKey = keyOperations.createKey(algorithm, keysize,
- passphrase, masterKey);
-
- /* Output */
- Bundle resultData = new Bundle();
- resultData.putByteArray(RESULT_NEW_KEY,
- PgpConversionHelper.PGPSecretKeyToBytes(newKey));
-
- OtherHelper.logDebugBundle(resultData, "resultData");
-
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
- } catch (Exception e) {
- sendErrorToHandler(e);
- }
- } else if (ACTION_GENERATE_DEFAULT_RSA_KEYS.equals(action)) {
- // generate one RSA 4096 key for signing and one subkey for encrypting!
- try {
- /* Input */
- String passphrase = data.getString(GENERATE_KEY_SYMMETRIC_PASSPHRASE);
- ArrayList<PGPSecretKey> newKeys = new ArrayList<PGPSecretKey>();
- ArrayList<Integer> keyUsageList = new ArrayList<Integer>();
-
- /* Operation */
- int keysTotal = 3;
- int keysCreated = 0;
- setProgress(
- getApplicationContext().getResources().
- getQuantityString(R.plurals.progress_generating, keysTotal),
- keysCreated,
- keysTotal);
- PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 100, 100));
-
- PGPSecretKey masterKey = keyOperations.createKey(Id.choice.algorithm.rsa,
- 4096, passphrase, true);
- newKeys.add(masterKey);
- keyUsageList.add(KeyFlags.CERTIFY_OTHER);
- keysCreated++;
- setProgress(keysCreated, keysTotal);
-
- PGPSecretKey subKey = keyOperations.createKey(Id.choice.algorithm.rsa,
- 4096, passphrase, false);
- newKeys.add(subKey);
- keyUsageList.add(KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE);
- keysCreated++;
- setProgress(keysCreated, keysTotal);
-
- subKey = keyOperations.createKey(Id.choice.algorithm.rsa,
- 4096, passphrase, false);
- newKeys.add(subKey);
- keyUsageList.add(KeyFlags.SIGN_DATA);
- keysCreated++;
- setProgress(keysCreated, keysTotal);
-
- // TODO: default to one master for cert, one sub for encrypt and one sub
- // for sign
-
- /* Output */
-
- Bundle resultData = new Bundle();
- resultData.putByteArray(RESULT_NEW_KEY,
- PgpConversionHelper.PGPSecretKeyArrayListToBytes(newKeys));
- resultData.putIntegerArrayList(RESULT_KEY_USAGES, keyUsageList);
-
- OtherHelper.logDebugBundle(resultData, "resultData");
-
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
- } catch (Exception e) {
- sendErrorToHandler(e);
- }
- } else if (ACTION_DELETE_FILE_SECURELY.equals(action)) {
- try {
- /* Input */
- String deleteFile = data.getString(DELETE_FILE);
-
- /* Operation */
- try {
- PgpHelper.deleteFileSecurely(this, this, new File(deleteFile));
- } catch (FileNotFoundException e) {
- throw new PgpGeneralException(
- getString(R.string.error_file_not_found, deleteFile));
- } catch (IOException e) {
- throw new PgpGeneralException(getString(R.string.error_file_delete_failed,
- deleteFile));
- }
-
- /* Output */
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY);
- } catch (Exception e) {
- sendErrorToHandler(e);
- }
- } else if (ACTION_IMPORT_KEYRING.equals(action)) {
- try {
- List<ImportKeysListEntry> entries = data.getParcelableArrayList(IMPORT_KEY_LIST);
-
- Bundle resultData = new Bundle();
-
- PgpImportExport pgpImportExport = new PgpImportExport(this, this);
- resultData = pgpImportExport.importKeyRings(entries);
-
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
- } catch (Exception e) {
- sendErrorToHandler(e);
- }
- } else if (ACTION_EXPORT_KEYRING.equals(action)) {
- try {
-
- boolean exportSecret = data.getBoolean(EXPORT_SECRET, false);
- long[] masterKeyIds = data.getLongArray(EXPORT_KEY_RING_MASTER_KEY_ID);
- String outputFile = data.getString(EXPORT_FILENAME);
-
- // If not exporting all keys get the masterKeyIds of the keys to export from the intent
- boolean exportAll = data.getBoolean(EXPORT_ALL);
-
- // check if storage is ready
- if (!FileHelper.isStorageMounted(outputFile)) {
- throw new PgpGeneralException(getString(R.string.error_external_storage_not_ready));
- }
-
- ArrayList<Long> publicMasterKeyIds = new ArrayList<Long>();
- ArrayList<Long> secretMasterKeyIds = new ArrayList<Long>();
-
- String selection = null;
- if(!exportAll) {
- selection = KeychainDatabase.Tables.KEYS + "." + KeyRings.MASTER_KEY_ID + " IN( ";
- for(long l : masterKeyIds) {
- selection += Long.toString(l) + ",";
- }
- selection = selection.substring(0, selection.length()-1) + " )";
- }
-
- Cursor cursor = getContentResolver().query(KeyRings.buildUnifiedKeyRingsUri(),
- new String[]{ KeyRings.MASTER_KEY_ID, KeyRings.HAS_SECRET },
- selection, null, null);
- try {
- cursor.moveToFirst();
- do {
- // export public either way
- publicMasterKeyIds.add(cursor.getLong(0));
- // add secret if available (and requested)
- if(exportSecret && cursor.getInt(1) != 0)
- secretMasterKeyIds.add(cursor.getLong(0));
- } while(cursor.moveToNext());
- } finally {
- cursor.close();
- }
-
- PgpImportExport pgpImportExport = new PgpImportExport(this, this, this);
- Bundle resultData = pgpImportExport
- .exportKeyRings(publicMasterKeyIds, secretMasterKeyIds,
- new FileOutputStream(outputFile));
-
- if (mIsCanceled) {
- boolean isDeleted = new File(outputFile).delete();
- }
-
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
- } catch (Exception e) {
- sendErrorToHandler(e);
- }
- } else if (ACTION_UPLOAD_KEYRING.equals(action)) {
- try {
-
- /* Input */
- String keyServer = data.getString(UPLOAD_KEY_SERVER);
- // and dataUri!
-
- /* Operation */
- HkpKeyServer server = new HkpKeyServer(keyServer);
-
- PGPPublicKeyRing keyring = (PGPPublicKeyRing) ProviderHelper.getPGPKeyRing(this, dataUri);
- if (keyring != null) {
- PgpImportExport pgpImportExport = new PgpImportExport(this, null);
-
- boolean uploaded = pgpImportExport.uploadKeyRingToServer(server,
- (PGPPublicKeyRing) keyring);
- if (!uploaded) {
- throw new PgpGeneralException("Unable to export key to selected server");
- }
- }
-
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY);
- } catch (Exception e) {
- sendErrorToHandler(e);
- }
- } else if (ACTION_DOWNLOAD_AND_IMPORT_KEYS.equals(action)) {
- try {
- ArrayList<ImportKeysListEntry> entries = data.getParcelableArrayList(DOWNLOAD_KEY_LIST);
- String keyServer = data.getString(DOWNLOAD_KEY_SERVER);
-
- // this downloads the keys and places them into the ImportKeysListEntry entries
- HkpKeyServer server = new HkpKeyServer(keyServer);
-
- for (ImportKeysListEntry entry : entries) {
- // if available use complete fingerprint for get request
- byte[] downloadedKeyBytes;
- if (entry.getFingerPrintHex() != null) {
- downloadedKeyBytes = server.get("0x" + entry.getFingerPrintHex()).getBytes();
- } else {
- downloadedKeyBytes = server.get(entry.getKeyIdHex()).getBytes();
- }
-
- // create PGPKeyRing object based on downloaded armored key
- PGPKeyRing downloadedKey = null;
- BufferedInputStream bufferedInput =
- new BufferedInputStream(new ByteArrayInputStream(downloadedKeyBytes));
- if (bufferedInput.available() > 0) {
- InputStream in = PGPUtil.getDecoderStream(bufferedInput);
- PGPObjectFactory objectFactory = new PGPObjectFactory(in);
-
- // get first object in block
- Object obj;
- if ((obj = objectFactory.nextObject()) != null) {
- Log.d(Constants.TAG, "Found class: " + obj.getClass());
-
- if (obj instanceof PGPKeyRing) {
- downloadedKey = (PGPKeyRing) obj;
- } else {
- throw new PgpGeneralException("Object not recognized as PGPKeyRing!");
- }
- }
- }
-
- // verify downloaded key by comparing fingerprints
- if (entry.getFingerPrintHex() != null) {
- String downloadedKeyFp = PgpKeyHelper.convertFingerprintToHex(
- downloadedKey.getPublicKey().getFingerprint());
- if (downloadedKeyFp.equals(entry.getFingerPrintHex())) {
- Log.d(Constants.TAG, "fingerprint of downloaded key is the same as " +
- "the requested fingerprint!");
- } else {
- throw new PgpGeneralException("fingerprint of downloaded key is " +
- "NOT the same as the requested fingerprint!");
- }
- }
-
- // save key bytes in entry object for doing the
- // actual import afterwards
- entry.setBytes(downloadedKey.getEncoded());
- }
-
-
- Intent importIntent = new Intent(this, KeychainIntentService.class);
- importIntent.setAction(ACTION_IMPORT_KEYRING);
- Bundle importData = new Bundle();
- importData.putParcelableArrayList(IMPORT_KEY_LIST, entries);
- importIntent.putExtra(EXTRA_DATA, importData);
- importIntent.putExtra(EXTRA_MESSENGER, mMessenger);
-
- // now import it with this service
- onHandleIntent(importIntent);
-
- // result is handled in ACTION_IMPORT_KEYRING
- } catch (Exception e) {
- sendErrorToHandler(e);
- }
- } else if (ACTION_CERTIFY_KEYRING.equals(action)) {
- try {
-
- /* Input */
- long masterKeyId = data.getLong(CERTIFY_KEY_MASTER_KEY_ID);
- long pubKeyId = data.getLong(CERTIFY_KEY_PUB_KEY_ID);
- ArrayList<String> userIds = data.getStringArrayList(CERTIFY_KEY_UIDS);
-
- /* Operation */
- String signaturePassphrase = PassphraseCacheService.getCachedPassphrase(this,
- masterKeyId);
- if (signaturePassphrase == null) {
- throw new PgpGeneralException("Unable to obtain passphrase");
- }
-
- PgpKeyOperation keyOperation = new PgpKeyOperation(new ProgressScaler(this, 0, 100, 100));
- PGPPublicKeyRing publicRing = ProviderHelper.getPGPPublicKeyRing(this, pubKeyId);
- PGPPublicKey publicKey = publicRing.getPublicKey(pubKeyId);
- PGPSecretKey certificationKey = PgpKeyHelper.getCertificationKey(this,
- masterKeyId);
- publicKey = keyOperation.certifyKey(certificationKey, publicKey,
- userIds, signaturePassphrase);
- publicRing = PGPPublicKeyRing.insertPublicKey(publicRing, publicKey);
-
- // store the signed key in our local cache
- PgpImportExport pgpImportExport = new PgpImportExport(this, null);
- int retval = pgpImportExport.storeKeyRingInCache(publicRing);
- if (retval != Id.return_value.ok && retval != Id.return_value.updated) {
- throw new PgpGeneralException("Failed to store signed key in local cache");
- }
-
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY);
- } catch (Exception e) {
- sendErrorToHandler(e);
- }
- }
- }
-
- private void sendErrorToHandler(Exception e) {
- // Service was canceled. Do not send error to handler.
- if (this.mIsCanceled) {
- return;
- }
- // contextualize the exception, if necessary
- if (e instanceof PgpGeneralMsgIdException) {
- e = ((PgpGeneralMsgIdException) e).getContextualized(this);
- }
- Log.e(Constants.TAG, "ApgService Exception: ", e);
- e.printStackTrace();
-
- Bundle data = new Bundle();
- data.putString(KeychainIntentServiceHandler.DATA_ERROR, e.getMessage());
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_EXCEPTION, null, data);
- }
-
- private void sendMessageToHandler(Integer arg1, Integer arg2, Bundle data) {
- // Service was canceled. Do not send message to handler.
- if (this.mIsCanceled) {
- return;
- }
- Message msg = Message.obtain();
- msg.arg1 = arg1;
- if (arg2 != null) {
- msg.arg2 = arg2;
- }
- if (data != null) {
- msg.setData(data);
- }
-
- try {
- mMessenger.send(msg);
- } catch (RemoteException e) {
- Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
- } catch (NullPointerException e) {
- Log.w(Constants.TAG, "Messenger is null!", e);
- }
- }
-
- private void sendMessageToHandler(Integer arg1, Bundle data) {
- sendMessageToHandler(arg1, null, data);
- }
-
- private void sendMessageToHandler(Integer arg1) {
- sendMessageToHandler(arg1, null, null);
- }
-
- /**
- * Set progressDialogUpdater of ProgressDialog by sending message to handler on UI thread
- */
- public void setProgress(String message, int progress, int max) {
- Log.d(Constants.TAG, "Send message by setProgress with progressDialogUpdater=" + progress + ", max="
- + max);
-
- Bundle data = new Bundle();
- if (message != null) {
- data.putString(KeychainIntentServiceHandler.DATA_MESSAGE, message);
- }
- data.putInt(KeychainIntentServiceHandler.DATA_PROGRESS, progress);
- data.putInt(KeychainIntentServiceHandler.DATA_PROGRESS_MAX, max);
-
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_UPDATE_PROGRESS, null, data);
- }
-
- public void setProgress(int resourceId, int progress, int max) {
- setProgress(getString(resourceId), progress, max);
- }
-
- public void setProgress(int progress, int max) {
- setProgress(null, progress, max);
- }
-
- @Override
- public boolean hasServiceStopped() {
- return mIsCanceled;
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java
deleted file mode 100644
index 92d012c80..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.service;
-
-import android.app.Activity;
-import android.content.DialogInterface.OnCancelListener;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.FragmentManager;
-import android.widget.Toast;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
-
-public class KeychainIntentServiceHandler extends Handler {
-
- // possible messages send from this service to handler on ui
- public static final int MESSAGE_OKAY = 1;
- public static final int MESSAGE_EXCEPTION = 2;
- public static final int MESSAGE_UPDATE_PROGRESS = 3;
-
- // possible data keys for messages
- public static final String DATA_ERROR = "error";
- public static final String DATA_PROGRESS = "progress";
- public static final String DATA_PROGRESS_MAX = "max";
- public static final String DATA_MESSAGE = "message";
- public static final String DATA_MESSAGE_ID = "message_id";
-
- Activity mActivity;
- ProgressDialogFragment mProgressDialogFragment;
-
- public KeychainIntentServiceHandler(Activity activity) {
- this.mActivity = activity;
- }
-
- public KeychainIntentServiceHandler(Activity activity,
- ProgressDialogFragment progressDialogFragment) {
- this.mActivity = activity;
- this.mProgressDialogFragment = progressDialogFragment;
- }
-
- public KeychainIntentServiceHandler(Activity activity, String progressDialogMessage,
- int progressDialogStyle) {
- this(activity, progressDialogMessage, progressDialogStyle, false, null);
- }
-
- public KeychainIntentServiceHandler(Activity activity, String progressDialogMessage,
- int progressDialogStyle, boolean cancelable,
- OnCancelListener onCancelListener) {
- this.mActivity = activity;
- this.mProgressDialogFragment = ProgressDialogFragment.newInstance(
- progressDialogMessage,
- progressDialogStyle,
- cancelable,
- onCancelListener);
- }
-
- public void showProgressDialog(FragmentActivity activity) {
- // TODO: This is a hack!, see
- // http://stackoverflow.com/questions/10114324/show-dialogfragment-from-onactivityresult
- final FragmentManager manager = activity.getSupportFragmentManager();
- Handler handler = new Handler();
- handler.post(new Runnable() {
- public void run() {
- mProgressDialogFragment.show(manager, "progressDialog");
- }
- });
- }
-
- @Override
- public void handleMessage(Message message) {
- Bundle data = message.getData();
-
- switch (message.arg1) {
- case MESSAGE_OKAY:
- mProgressDialogFragment.dismissAllowingStateLoss();
-
- break;
-
- case MESSAGE_EXCEPTION:
- mProgressDialogFragment.dismissAllowingStateLoss();
-
- // show error from service
- if (data.containsKey(DATA_ERROR)) {
- Toast.makeText(mActivity,
- mActivity.getString(R.string.error_message, data.getString(DATA_ERROR)),
- Toast.LENGTH_SHORT).show();
- }
-
- break;
-
- case MESSAGE_UPDATE_PROGRESS:
- if (data.containsKey(DATA_PROGRESS) && data.containsKey(DATA_PROGRESS_MAX)) {
-
- // update progress from service
- if (data.containsKey(DATA_MESSAGE)) {
- mProgressDialogFragment.setProgress(data.getString(DATA_MESSAGE),
- data.getInt(DATA_PROGRESS), data.getInt(DATA_PROGRESS_MAX));
- } else if (data.containsKey(DATA_MESSAGE_ID)) {
- mProgressDialogFragment.setProgress(data.getInt(DATA_MESSAGE_ID),
- data.getInt(DATA_PROGRESS), data.getInt(DATA_PROGRESS_MAX));
- } else {
- mProgressDialogFragment.setProgress(data.getInt(DATA_PROGRESS),
- data.getInt(DATA_PROGRESS_MAX));
- }
- }
-
- break;
-
- default:
- break;
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
deleted file mode 100644
index 962b304c7..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.service;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.support.v4.util.LongSparseArray;
-import android.util.Log;
-
-import org.spongycastle.openpgp.PGPException;
-import org.spongycastle.openpgp.PGPPrivateKey;
-import org.spongycastle.openpgp.PGPSecretKey;
-import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
-import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.helper.Preferences;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-
-import java.util.Date;
-import java.util.Iterator;
-
-/**
- * This service runs in its own process, but is available to all other processes as the main
- * passphrase cache. Use the static methods addCachedPassphrase and getCachedPassphrase for
- * convenience.
- */
-public class PassphraseCacheService extends Service {
- public static final String TAG = Constants.TAG + ": PassphraseCacheService";
-
- public static final String ACTION_PASSPHRASE_CACHE_ADD = Constants.INTENT_PREFIX
- + "PASSPHRASE_CACHE_ADD";
- public static final String ACTION_PASSPHRASE_CACHE_GET = Constants.INTENT_PREFIX
- + "PASSPHRASE_CACHE_GET";
-
- public static final String BROADCAST_ACTION_PASSPHRASE_CACHE_SERVICE = Constants.INTENT_PREFIX
- + "PASSPHRASE_CACHE_BROADCAST";
-
- public static final String EXTRA_TTL = "ttl";
- public static final String EXTRA_KEY_ID = "key_id";
- public static final String EXTRA_PASSPHRASE = "passphrase";
- public static final String EXTRA_MESSENGER = "messenger";
-
- private static final int REQUEST_ID = 0;
- private static final long DEFAULT_TTL = 15;
-
- private BroadcastReceiver mIntentReceiver;
-
- private LongSparseArray<String> mPassphraseCache = new LongSparseArray<String>();
-
- Context mContext;
-
- /**
- * This caches a new passphrase in memory by sending a new command to the service. An android
- * service is only run once. Thus, when the service is already started, new commands just add
- * new events to the alarm manager for new passphrases to let them timeout in the future.
- *
- * @param context
- * @param keyId
- * @param passphrase
- */
- public static void addCachedPassphrase(Context context, long keyId, String passphrase) {
- Log.d(TAG, "cacheNewPassphrase() for " + keyId);
-
- Intent intent = new Intent(context, PassphraseCacheService.class);
- intent.setAction(ACTION_PASSPHRASE_CACHE_ADD);
- intent.putExtra(EXTRA_TTL, Preferences.getPreferences(context).getPassphraseCacheTtl());
- intent.putExtra(EXTRA_PASSPHRASE, passphrase);
- intent.putExtra(EXTRA_KEY_ID, keyId);
-
- context.startService(intent);
- }
-
- /**
- * Gets a cached passphrase from memory by sending an intent to the service. This method is
- * designed to wait until the service returns the passphrase.
- *
- * @param context
- * @param keyId
- * @return passphrase or null (if no passphrase is cached for this keyId)
- */
- public static String getCachedPassphrase(Context context, long keyId) {
- Log.d(TAG, "getCachedPassphrase() get masterKeyId for " + keyId);
-
- Intent intent = new Intent(context, PassphraseCacheService.class);
- intent.setAction(ACTION_PASSPHRASE_CACHE_GET);
-
- final Object mutex = new Object();
- final Bundle returnBundle = new Bundle();
-
- HandlerThread handlerThread = new HandlerThread("getPassphraseThread");
- handlerThread.start();
- Handler returnHandler = new Handler(handlerThread.getLooper()) {
- @Override
- public void handleMessage(Message message) {
- if (message.obj != null) {
- String passphrase = ((Bundle) message.obj).getString(EXTRA_PASSPHRASE);
- returnBundle.putString(EXTRA_PASSPHRASE, passphrase);
- }
- synchronized (mutex) {
- mutex.notify();
- }
- // quit handlerThread
- getLooper().quit();
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(returnHandler);
- intent.putExtra(EXTRA_KEY_ID, keyId);
- intent.putExtra(EXTRA_MESSENGER, messenger);
- // send intent to this service
- context.startService(intent);
-
- // Wait on mutex until passphrase is returned to handlerThread
- synchronized (mutex) {
- try {
- mutex.wait(3000);
- } catch (InterruptedException e) {
- }
- }
-
- if (returnBundle.containsKey(EXTRA_PASSPHRASE)) {
- return returnBundle.getString(EXTRA_PASSPHRASE);
- } else {
- return null;
- }
- }
-
- /**
- * Internal implementation to get cached passphrase.
- *
- * @param keyId
- * @return
- */
- private String getCachedPassphraseImpl(long keyId) {
- Log.d(TAG, "getCachedPassphraseImpl() get masterKeyId for " + keyId);
-
- // try to get master key id which is used as an identifier for cached passphrases
- long masterKeyId = keyId;
- if (masterKeyId != Id.key.symmetric) {
- masterKeyId = ProviderHelper.getMasterKeyId(this,
- KeychainContract.KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(keyId)));
- // Failure
- if(masterKeyId == 0)
- return null;
- }
- Log.d(TAG, "getCachedPassphraseImpl() for masterKeyId " + masterKeyId);
-
- // get cached passphrase
- String cachedPassphrase = mPassphraseCache.get(masterKeyId);
- if (cachedPassphrase == null) {
- // if key has no passphrase -> cache and return empty passphrase
- if (!hasPassphrase(this, masterKeyId)) {
- Log.d(Constants.TAG, "Key has no passphrase! Caches and returns empty passphrase!");
-
- addCachedPassphrase(this, masterKeyId, "");
- return "";
- } else {
- return null;
- }
- }
- // set it again to reset the cache life cycle
- Log.d(TAG, "Cache passphrase again when getting it!");
- addCachedPassphrase(this, masterKeyId, cachedPassphrase);
-
- return cachedPassphrase;
- }
-
- /**
- * Checks if key has a passphrase.
- *
- * @param secretKeyId
- * @return true if it has a passphrase
- */
- public static boolean hasPassphrase(Context context, long secretKeyId) {
- // check if the key has no passphrase
- try {
- PGPSecretKeyRing secRing = ProviderHelper.getPGPSecretKeyRing(context, secretKeyId);
- PGPSecretKey secretKey = null;
- boolean foundValidKey = false;
- for (Iterator keys = secRing.getSecretKeys(); keys.hasNext(); ) {
- secretKey = (PGPSecretKey) keys.next();
- if (!secretKey.isPrivateKeyEmpty()) {
- foundValidKey = true;
- break;
- }
- }
-
- if (!foundValidKey) {
- return false;
- }
- PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
- "SC").build("".toCharArray());
- PGPPrivateKey testKey = secretKey.extractPrivateKey(keyDecryptor);
- if (testKey != null) {
- return false;
- }
- } catch (PGPException e) {
- // silently catch
- }
-
- return true;
- }
-
- /**
- * Register BroadcastReceiver that is unregistered when service is destroyed. This
- * BroadcastReceiver hears on intents with ACTION_PASSPHRASE_CACHE_SERVICE to then timeout
- * specific passphrases in memory.
- */
- private void registerReceiver() {
- if (mIntentReceiver == null) {
- mIntentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
-
- Log.d(TAG, "Received broadcast...");
-
- if (action.equals(BROADCAST_ACTION_PASSPHRASE_CACHE_SERVICE)) {
- long keyId = intent.getLongExtra(EXTRA_KEY_ID, -1);
- timeout(context, keyId);
- }
- }
- };
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(BROADCAST_ACTION_PASSPHRASE_CACHE_SERVICE);
- registerReceiver(mIntentReceiver, filter);
- }
- }
-
- /**
- * Build pending intent that is executed by alarm manager to time out a specific passphrase
- *
- * @param context
- * @param keyId
- * @return
- */
- private static PendingIntent buildIntent(Context context, long keyId) {
- Intent intent = new Intent(BROADCAST_ACTION_PASSPHRASE_CACHE_SERVICE);
- intent.putExtra(EXTRA_KEY_ID, keyId);
- PendingIntent sender = PendingIntent.getBroadcast(context, REQUEST_ID, intent,
- PendingIntent.FLAG_CANCEL_CURRENT);
-
- return sender;
- }
-
- /**
- * Executed when service is started by intent
- */
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- Log.d(TAG, "onStartCommand()");
-
- // register broadcastreceiver
- registerReceiver();
-
- if (intent != null && intent.getAction() != null) {
- if (ACTION_PASSPHRASE_CACHE_ADD.equals(intent.getAction())) {
- long ttl = intent.getLongExtra(EXTRA_TTL, DEFAULT_TTL);
- long keyId = intent.getLongExtra(EXTRA_KEY_ID, -1);
- String passphrase = intent.getStringExtra(EXTRA_PASSPHRASE);
-
- Log.d(TAG,
- "Received ACTION_PASSPHRASE_CACHE_ADD intent in onStartCommand() with keyId: "
- + keyId + ", ttl: " + ttl);
-
- // add keyId and passphrase to memory
- mPassphraseCache.put(keyId, passphrase);
-
- if (ttl > 0) {
- // register new alarm with keyId for this passphrase
- long triggerTime = new Date().getTime() + (ttl * 1000);
- AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
- am.set(AlarmManager.RTC_WAKEUP, triggerTime, buildIntent(this, keyId));
- }
- } else if (ACTION_PASSPHRASE_CACHE_GET.equals(intent.getAction())) {
- long keyId = intent.getLongExtra(EXTRA_KEY_ID, -1);
- Messenger messenger = intent.getParcelableExtra(EXTRA_MESSENGER);
-
- String passphrase = getCachedPassphraseImpl(keyId);
-
- Message msg = Message.obtain();
- Bundle bundle = new Bundle();
- bundle.putString(EXTRA_PASSPHRASE, passphrase);
- msg.obj = bundle;
- try {
- messenger.send(msg);
- } catch (RemoteException e) {
- Log.e(Constants.TAG, "Sending message failed", e);
- }
- } else {
- Log.e(Constants.TAG, "Intent or Intent Action not supported!");
- }
- }
-
- return START_STICKY;
- }
-
- /**
- * Called when one specific passphrase for keyId timed out
- *
- * @param context
- * @param keyId
- */
- private void timeout(Context context, long keyId) {
- // remove passphrase corresponding to keyId from memory
- mPassphraseCache.remove(keyId);
-
- Log.d(TAG, "Timeout of keyId " + keyId + ", removed from memory!");
-
- // stop whole service if no cached passphrases remaining
- if (mPassphraseCache.size() == 0) {
- Log.d(TAG, "No passphrases remaining in memory, stopping service!");
- stopSelf();
- }
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- mContext = this;
- Log.d(Constants.TAG, "PassphraseCacheService, onCreate()");
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- Log.d(Constants.TAG, "PassphraseCacheService, onDestroy()");
-
- unregisterReceiver(mIntentReceiver);
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
-
- public class PassphraseCacheBinder extends Binder {
- public PassphraseCacheService getService() {
- return PassphraseCacheService.this;
- }
- }
-
- private final IBinder mBinder = new PassphraseCacheBinder();
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java
deleted file mode 100644
index 7c2dcf2c1..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2014 Ash Hughes <ashes-iontach@hotmail.com>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-
-package org.sufficientlysecure.keychain.service;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import org.spongycastle.openpgp.PGPSecretKey;
-import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
-
-import java.util.ArrayList;
-import java.util.GregorianCalendar;
-
-public class SaveKeyringParcel implements Parcelable {
-
- public ArrayList<String> userIDs;
- public ArrayList<String> originalIDs;
- public ArrayList<String> deletedIDs;
- public boolean[] newIDs;
- public boolean primaryIDChanged;
- public boolean[] moddedKeys;
- public ArrayList<PGPSecretKey> deletedKeys;
- public ArrayList<GregorianCalendar> keysExpiryDates;
- public ArrayList<Integer> keysUsages;
- public String newPassphrase;
- public String oldPassphrase;
- public boolean[] newKeys;
- public ArrayList<PGPSecretKey> keys;
- public String originalPrimaryID;
-
- public SaveKeyringParcel() {}
-
- private SaveKeyringParcel(Parcel source) {
- userIDs = (ArrayList<String>) source.readSerializable();
- originalIDs = (ArrayList<String>) source.readSerializable();
- deletedIDs = (ArrayList<String>) source.readSerializable();
- newIDs = source.createBooleanArray();
- primaryIDChanged = source.readByte() != 0;
- moddedKeys = source.createBooleanArray();
- byte[] tmp = source.createByteArray();
- if (tmp == null) {
- deletedKeys = null;
- } else {
- deletedKeys = PgpConversionHelper.BytesToPGPSecretKeyList(tmp);
- }
- keysExpiryDates = (ArrayList<GregorianCalendar>) source.readSerializable();
- keysUsages = source.readArrayList(Integer.class.getClassLoader());
- newPassphrase = source.readString();
- oldPassphrase = source.readString();
- newKeys = source.createBooleanArray();
- keys = PgpConversionHelper.BytesToPGPSecretKeyList(source.createByteArray());
- originalPrimaryID = source.readString();
- }
-
- @Override
- public void writeToParcel(Parcel destination, int flags) {
- destination.writeSerializable(userIDs); //might not be the best method to store.
- destination.writeSerializable(originalIDs);
- destination.writeSerializable(deletedIDs);
- destination.writeBooleanArray(newIDs);
- destination.writeByte((byte) (primaryIDChanged ? 1 : 0));
- destination.writeBooleanArray(moddedKeys);
- byte[] tmp = null;
- if (deletedKeys.size() != 0) {
- tmp = PgpConversionHelper.PGPSecretKeyArrayListToBytes(deletedKeys);
- }
- destination.writeByteArray(tmp);
- destination.writeSerializable(keysExpiryDates);
- destination.writeList(keysUsages);
- destination.writeString(newPassphrase);
- destination.writeString(oldPassphrase);
- destination.writeBooleanArray(newKeys);
- destination.writeByteArray(PgpConversionHelper.PGPSecretKeyArrayListToBytes(keys));
- destination.writeString(originalPrimaryID);
- }
-
- public static final Creator<SaveKeyringParcel> CREATOR = new Creator<SaveKeyringParcel>() {
- public SaveKeyringParcel createFromParcel(final Parcel source) {
- return new SaveKeyringParcel(source);
- }
-
- public SaveKeyringParcel[] newArray(final int size) {
- return new SaveKeyringParcel[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
deleted file mode 100644
index 7027c114e..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2011 Senecaso
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.app.ProgressDialog;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.CursorLoader;
-import android.support.v4.content.Loader;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.ArrayAdapter;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.widget.ListView;
-import android.widget.Spinner;
-import android.widget.TextView;
-import android.widget.Toast;
-import com.beardedhen.androidbootstrap.BootstrapButton;
-import org.spongycastle.openpgp.PGPPublicKeyRing;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.Preferences;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.service.PassphraseCacheService;
-import org.sufficientlysecure.keychain.ui.adapter.ViewKeyUserIdsAdapter;
-import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.util.ArrayList;
-
-/**
- * Signs the specified public key with the specified secret master key
- */
-public class CertifyKeyActivity extends ActionBarActivity implements
- SelectSecretKeyLayoutFragment.SelectSecretKeyCallback, LoaderManager.LoaderCallbacks<Cursor> {
- private BootstrapButton mSignButton;
- private CheckBox mUploadKeyCheckbox;
- private Spinner mSelectKeyserverSpinner;
-
- private SelectSecretKeyLayoutFragment mSelectKeyFragment;
-
- private Uri mDataUri;
- private long mPubKeyId = 0;
- private long mMasterKeyId = 0;
-
- private ListView mUserIds;
- private ViewKeyUserIdsAdapter mUserIdsAdapter;
-
- private static final int LOADER_ID_KEYRING = 0;
- private static final int LOADER_ID_USER_IDS = 1;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.certify_key_activity);
-
- final ActionBar actionBar = getSupportActionBar();
- actionBar.setDisplayShowTitleEnabled(true);
- actionBar.setDisplayHomeAsUpEnabled(false);
- actionBar.setHomeButtonEnabled(false);
-
- mSelectKeyFragment = (SelectSecretKeyLayoutFragment) getSupportFragmentManager()
- .findFragmentById(R.id.sign_key_select_key_fragment);
- mSelectKeyFragment.setCallback(this);
- mSelectKeyFragment.setFilterCertify(true);
-
- mSelectKeyserverSpinner = (Spinner) findViewById(R.id.sign_key_keyserver);
- ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
- android.R.layout.simple_spinner_item, Preferences.getPreferences(this)
- .getKeyServers());
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- mSelectKeyserverSpinner.setAdapter(adapter);
-
- mUploadKeyCheckbox = (CheckBox) findViewById(R.id.sign_key_upload_checkbox);
- if (!mUploadKeyCheckbox.isChecked()) {
- mSelectKeyserverSpinner.setEnabled(false);
- } else {
- mSelectKeyserverSpinner.setEnabled(true);
- }
-
- mUploadKeyCheckbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
-
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if (!isChecked) {
- mSelectKeyserverSpinner.setEnabled(false);
- } else {
- mSelectKeyserverSpinner.setEnabled(true);
- }
- }
- });
-
- mSignButton = (BootstrapButton) findViewById(R.id.sign_key_sign_button);
- mSignButton.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- if (mPubKeyId != 0) {
- if (mMasterKeyId == 0) {
- mSelectKeyFragment.setError(getString(R.string.select_key_to_sign));
- } else {
- initiateSigning();
- }
- }
- }
- });
-
- mDataUri = getIntent().getData();
- if (mDataUri == null) {
- Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!");
- finish();
- return;
- }
- Log.e(Constants.TAG, "uri: " + mDataUri);
-
- mUserIds = (ListView) findViewById(R.id.user_ids);
-
- mUserIdsAdapter = new ViewKeyUserIdsAdapter(this, null, 0, true);
- mUserIds.setAdapter(mUserIdsAdapter);
- mUserIds.setOnItemClickListener(mUserIdsAdapter);
-
- getSupportLoaderManager().initLoader(LOADER_ID_KEYRING, null, this);
- getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
-
- }
-
- static final String USER_IDS_SELECTION = UserIds.IS_REVOKED + " = 0";
-
- static final String[] KEYRING_PROJECTION =
- new String[] {
- KeyRings._ID,
- KeyRings.MASTER_KEY_ID,
- KeyRings.FINGERPRINT,
- KeyRings.USER_ID,
- };
- static final int INDEX_MASTER_KEY_ID = 1;
- static final int INDEX_FINGERPRINT = 2;
- static final int INDEX_USER_ID = 3;
-
- @Override
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- switch(id) {
- case LOADER_ID_KEYRING: {
- Uri uri = KeyRings.buildUnifiedKeyRingUri(mDataUri);
- return new CursorLoader(this, uri, KEYRING_PROJECTION, null, null, null);
- }
- case LOADER_ID_USER_IDS: {
- Uri uri = UserIds.buildUserIdsUri(mDataUri);
- return new CursorLoader(this, uri,
- ViewKeyUserIdsAdapter.USER_IDS_PROJECTION, USER_IDS_SELECTION, null, null);
- }
- }
- return null;
- }
-
- @Override
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- switch(loader.getId()) {
- case LOADER_ID_KEYRING:
- // the first key here is our master key
- if (data.moveToFirst()) {
- // TODO: put findViewById in onCreate!
- mPubKeyId = data.getLong(INDEX_MASTER_KEY_ID);
- String keyIdStr = PgpKeyHelper.convertKeyIdToHexShort(mPubKeyId);
- ((TextView) findViewById(R.id.key_id)).setText(keyIdStr);
-
- String mainUserId = data.getString(INDEX_USER_ID);
- ((TextView) findViewById(R.id.main_user_id)).setText(mainUserId);
-
- byte[] fingerprintBlob = data.getBlob(INDEX_FINGERPRINT);
- String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob);
- ((TextView) findViewById(R.id.fingerprint))
- .setText(PgpKeyHelper.colorizeFingerprint(fingerprint));
- }
- break;
- case LOADER_ID_USER_IDS:
- mUserIdsAdapter.swapCursor(data);
- break;
- }
- }
-
- @Override
- public void onLoaderReset(Loader<Cursor> loader) {
- switch(loader.getId()) {
- case LOADER_ID_USER_IDS:
- mUserIdsAdapter.swapCursor(null);
- break;
- }
- }
-
- /**
- * handles the UI bits of the signing process on the UI thread
- */
- private void initiateSigning() {
- PGPPublicKeyRing pubring = ProviderHelper.getPGPPublicKeyRing(this, mPubKeyId);
- if (pubring != null) {
- // if we have already signed this key, dont bother doing it again
- boolean alreadySigned = false;
-
- /* todo: reconsider this at a later point when certs are in the db
- @SuppressWarnings("unchecked")
- Iterator<PGPSignature> itr = pubring.getPublicKey(mPubKeyId).getSignatures();
- while (itr.hasNext()) {
- PGPSignature sig = itr.next();
- if (sig.getKeyID() == mMasterKeyId) {
- alreadySigned = true;
- break;
- }
- }
- */
-
- if (!alreadySigned) {
- /*
- * get the user's passphrase for this key (if required)
- */
- String passphrase = PassphraseCacheService.getCachedPassphrase(this, mMasterKeyId);
- if (passphrase == null) {
- PassphraseDialogFragment.show(this, mMasterKeyId,
- new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
- startSigning();
- }
- }
- });
- // bail out; need to wait until the user has entered the passphrase before trying again
- return;
- } else {
- startSigning();
- }
- } else {
- Toast.makeText(this, R.string.key_has_already_been_signed, Toast.LENGTH_SHORT)
- .show();
-
- setResult(RESULT_CANCELED);
- finish();
- }
- }
- }
-
- /**
- * kicks off the actual signing process on a background thread
- */
- private void startSigning() {
-
- // Bail out if there is not at least one user id selected
- ArrayList<String> userIds = mUserIdsAdapter.getSelectedUserIds();
- if (userIds.isEmpty()) {
- Toast.makeText(CertifyKeyActivity.this, "No User IDs to sign selected!",
- Toast.LENGTH_SHORT).show();
- return;
- }
-
- // Send all information needed to service to sign key in other thread
- Intent intent = new Intent(this, KeychainIntentService.class);
-
- intent.setAction(KeychainIntentService.ACTION_CERTIFY_KEYRING);
-
- // fill values for this action
- Bundle data = new Bundle();
-
- data.putLong(KeychainIntentService.CERTIFY_KEY_MASTER_KEY_ID, mMasterKeyId);
- data.putLong(KeychainIntentService.CERTIFY_KEY_PUB_KEY_ID, mPubKeyId);
- data.putStringArrayList(KeychainIntentService.CERTIFY_KEY_UIDS, userIds);
-
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
-
- // Message is received after signing is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- getString(R.string.progress_signing), ProgressDialog.STYLE_SPINNER) {
- public void handleMessage(Message message) {
- // handle messages by standard KeychainIntentServiceHandler first
- super.handleMessage(message);
-
- if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
-
- Toast.makeText(CertifyKeyActivity.this, R.string.key_sign_success,
- Toast.LENGTH_SHORT).show();
-
- // check if we need to send the key to the server or not
- if (mUploadKeyCheckbox.isChecked()) {
- // upload the newly signed key to the keyserver
- uploadKey();
- } else {
- setResult(RESULT_OK);
- finish();
- }
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
-
- // show progress dialog
- saveHandler.showProgressDialog(this);
-
- // start service with intent
- startService(intent);
- }
-
- private void uploadKey() {
- // Send all information needed to service to upload key in other thread
- Intent intent = new Intent(this, KeychainIntentService.class);
-
- intent.setAction(KeychainIntentService.ACTION_UPLOAD_KEYRING);
-
- // set data uri as path to keyring
- intent.setData(mDataUri);
-
- // fill values for this action
- Bundle data = new Bundle();
-
- Spinner keyServer = (Spinner) findViewById(R.id.sign_key_keyserver);
- String server = (String) keyServer.getSelectedItem();
- data.putString(KeychainIntentService.UPLOAD_KEY_SERVER, server);
-
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
-
- // Message is received after uploading is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL) {
- public void handleMessage(Message message) {
- // handle messages by standard KeychainIntentServiceHandler first
- super.handleMessage(message);
-
- if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- Toast.makeText(CertifyKeyActivity.this, R.string.key_send_success,
- Toast.LENGTH_SHORT).show();
-
- setResult(RESULT_OK);
- finish();
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
-
- // show progress dialog
- saveHandler.showProgressDialog(this);
-
- // start service with intent
- startService(intent);
- }
-
- /**
- * callback from select key fragment
- */
- @Override
- public void onKeySelected(long secretKeyId) {
- mMasterKeyId = secretKeyId;
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
deleted file mode 100644
index 8533e9072..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.view.PagerTabStrip;
-import android.support.v4.view.ViewPager;
-import android.widget.Toast;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.ActionBarHelper;
-import org.sufficientlysecure.keychain.helper.FileHelper;
-import org.sufficientlysecure.keychain.pgp.PgpHelper;
-import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.util.regex.Matcher;
-
-public class DecryptActivity extends DrawerActivity {
-
- /* Intents */
- public static final String ACTION_DECRYPT = Constants.INTENT_PREFIX + "DECRYPT";
-
- /* EXTRA keys for input */
- public static final String EXTRA_TEXT = "text";
-
- ViewPager mViewPager;
- PagerTabStrip mPagerTabStrip;
- PagerTabStripAdapter mTabsAdapter;
-
- Bundle mMessageFragmentBundle = new Bundle();
- Bundle mFileFragmentBundle = new Bundle();
- int mSwitchToTab = PAGER_TAB_MESSAGE;
-
- private static final int PAGER_TAB_MESSAGE = 0;
- private static final int PAGER_TAB_FILE = 1;
-
- private void initView() {
- mViewPager = (ViewPager) findViewById(R.id.decrypt_pager);
- mPagerTabStrip = (PagerTabStrip) findViewById(R.id.decrypt_pager_tab_strip);
-
- mTabsAdapter = new PagerTabStripAdapter(this);
- mViewPager.setAdapter(mTabsAdapter);
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.decrypt_activity);
-
- // set actionbar without home button if called from another app
- ActionBarHelper.setBackButton(this);
-
- initView();
-
- setupDrawerNavigation(savedInstanceState);
-
- // Handle intent actions, maybe changes the bundles
- handleActions(getIntent());
-
- mTabsAdapter.addTab(DecryptMessageFragment.class,
- mMessageFragmentBundle, getString(R.string.label_message));
- mTabsAdapter.addTab(DecryptFileFragment.class,
- mFileFragmentBundle, getString(R.string.label_file));
- mViewPager.setCurrentItem(mSwitchToTab);
- }
-
-
- /**
- * Handles all actions with this intent
- *
- * @param intent
- */
- private void handleActions(Intent intent) {
- String action = intent.getAction();
- Bundle extras = intent.getExtras();
- String type = intent.getType();
- Uri uri = intent.getData();
-
- if (extras == null) {
- extras = new Bundle();
- }
-
- /*
- * Android's Action
- */
- if (Intent.ACTION_SEND.equals(action) && type != null) {
- // When sending to Keychain Decrypt via share menu
- if ("text/plain".equals(type)) {
- // Plain text
- String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
- if (sharedText != null) {
- // handle like normal text decryption, override action and extras to later
- // executeServiceMethod ACTION_DECRYPT in main actions
- extras.putString(EXTRA_TEXT, sharedText);
- action = ACTION_DECRYPT;
- }
- } else {
- // Binary via content provider (could also be files)
- // override uri to get stream from send
- uri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
- action = ACTION_DECRYPT;
- }
- } else if (Intent.ACTION_VIEW.equals(action)) {
- // Android's Action when opening file associated to Keychain (see AndroidManifest.xml)
-
- // override action
- action = ACTION_DECRYPT;
- }
-
- String textData = extras.getString(EXTRA_TEXT);
-
- /**
- * Main Actions
- */
- if (ACTION_DECRYPT.equals(action) && textData != null) {
- Log.d(Constants.TAG, "textData not null, matching text ...");
- Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(textData);
- if (matcher.matches()) {
- Log.d(Constants.TAG, "PGP_MESSAGE matched");
- textData = matcher.group(1);
- // replace non breakable spaces
- textData = textData.replaceAll("\\xa0", " ");
-
- mMessageFragmentBundle.putString(DecryptMessageFragment.ARG_CIPHERTEXT, textData);
- mSwitchToTab = PAGER_TAB_MESSAGE;
- } else {
- matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(textData);
- if (matcher.matches()) {
- Log.d(Constants.TAG, "PGP_CLEARTEXT_SIGNATURE matched");
- textData = matcher.group(1);
- // replace non breakable spaces
- textData = textData.replaceAll("\\xa0", " ");
-
- mMessageFragmentBundle.putString(DecryptMessageFragment.ARG_CIPHERTEXT, textData);
- mSwitchToTab = PAGER_TAB_MESSAGE;
- } else {
- Log.d(Constants.TAG, "Nothing matched!");
- }
- }
- } else if (ACTION_DECRYPT.equals(action) && uri != null) {
- // get file path from uri
- String path = FileHelper.getPath(this, uri);
-
- if (path != null) {
- mFileFragmentBundle.putString(DecryptFileFragment.ARG_FILENAME, path);
- mSwitchToTab = PAGER_TAB_FILE;
- } else {
- Log.e(Constants.TAG,
- "Direct binary data without actual file in filesystem is not supported. " +
- "Please use the Remote Service API!");
- Toast.makeText(this, R.string.error_only_files_are_supported, Toast.LENGTH_LONG)
- .show();
- // end activity
- finish();
- }
- } else {
- Log.e(Constants.TAG,
- "Include the extra 'text' or an Uri with setData() in your Intent!");
- }
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java
deleted file mode 100644
index 492c0cf29..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.app.Activity;
-import android.app.ProgressDialog;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CheckBox;
-import android.widget.EditText;
-
-import com.beardedhen.androidbootstrap.BootstrapButton;
-import com.devspark.appmsg.AppMsg;
-
-import org.openintents.openpgp.OpenPgpSignatureResult;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.FileHelper;
-import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment;
-import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.io.File;
-
-public class DecryptFileFragment extends DecryptFragment {
- public static final String ARG_FILENAME = "filename";
-
- private static final int RESULT_CODE_FILE = 0x00007003;
-
- // view
- private EditText mFilename;
- private CheckBox mDeleteAfter;
- private BootstrapButton mBrowse;
- private BootstrapButton mDecryptButton;
-
- private String mInputFilename = null;
- private String mOutputFilename = null;
-
- private FileDialogFragment mFileDialog;
-
- /**
- * Inflate the layout for this fragment
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.decrypt_file_fragment, container, false);
-
- mFilename = (EditText) view.findViewById(R.id.decrypt_file_filename);
- mBrowse = (BootstrapButton) view.findViewById(R.id.decrypt_file_browse);
- mDeleteAfter = (CheckBox) view.findViewById(R.id.decrypt_file_delete_after_decryption);
- mDecryptButton = (BootstrapButton) view.findViewById(R.id.decrypt_file_action_decrypt);
- mBrowse.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- FileHelper.openFile(DecryptFileFragment.this, mFilename.getText().toString(), "*/*",
- RESULT_CODE_FILE);
- }
- });
- mDecryptButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- decryptAction();
- }
- });
-
- return view;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- String filename = getArguments().getString(ARG_FILENAME);
- if (filename != null) {
- mFilename.setText(filename);
- }
- }
-
- private void guessOutputFilename() {
- mInputFilename = mFilename.getText().toString();
- File file = new File(mInputFilename);
- String filename = file.getName();
- if (filename.endsWith(".asc") || filename.endsWith(".gpg") || filename.endsWith(".pgp")) {
- filename = filename.substring(0, filename.length() - 4);
- }
- mOutputFilename = Constants.Path.APP_DIR + "/" + filename;
- }
-
- private void decryptAction() {
- String currentFilename = mFilename.getText().toString();
- if (mInputFilename == null || !mInputFilename.equals(currentFilename)) {
- guessOutputFilename();
- }
-
- if (mInputFilename.equals("")) {
- AppMsg.makeText(getActivity(), R.string.no_file_selected, AppMsg.STYLE_ALERT).show();
- return;
- }
-
- if (mInputFilename.startsWith("file")) {
- File file = new File(mInputFilename);
- if (!file.exists() || !file.isFile()) {
- AppMsg.makeText(
- getActivity(),
- getString(R.string.error_message,
- getString(R.string.error_file_not_found)), AppMsg.STYLE_ALERT)
- .show();
- return;
- }
- }
-
- askForOutputFilename();
- }
-
- private void askForOutputFilename() {
- // Message is received after passphrase is cached
- Handler returnHandler = new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.what == FileDialogFragment.MESSAGE_OKAY) {
- Bundle data = message.getData();
- mOutputFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME);
- decryptStart(null);
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(returnHandler);
-
- mFileDialog = FileDialogFragment.newInstance(messenger,
- getString(R.string.title_decrypt_to_file),
- getString(R.string.specify_file_to_decrypt_to), mOutputFilename, null);
-
- mFileDialog.show(getActivity().getSupportFragmentManager(), "fileDialog");
- }
-
- @Override
- protected void decryptStart(String passphrase) {
- Log.d(Constants.TAG, "decryptStart");
-
- // Send all information needed to service to decrypt in other thread
- Intent intent = new Intent(getActivity(), KeychainIntentService.class);
-
- // fill values for this action
- Bundle data = new Bundle();
-
- intent.setAction(KeychainIntentService.ACTION_DECRYPT_VERIFY);
-
- // data
- data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_URI);
-
- Log.d(Constants.TAG, "mInputFilename=" + mInputFilename + ", mOutputFilename="
- + mOutputFilename);
-
- data.putString(KeychainIntentService.ENCRYPT_INPUT_FILE, mInputFilename);
- data.putString(KeychainIntentService.ENCRYPT_OUTPUT_FILE, mOutputFilename);
-
- data.putString(KeychainIntentService.DECRYPT_PASSPHRASE, passphrase);
-
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
-
- // Message is received after encrypting is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(),
- getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) {
- public void handleMessage(Message message) {
- // handle messages by standard KeychainIntentServiceHandler first
- super.handleMessage(message);
-
- if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- // get returned data bundle
- Bundle returnData = message.getData();
-
- PgpDecryptVerifyResult decryptVerifyResult =
- returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT);
-
- if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) {
- showPassphraseDialog(decryptVerifyResult.getKeyIdPassphraseNeeded());
- } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED ==
- decryptVerifyResult.getStatus()) {
- showPassphraseDialog(Id.key.symmetric);
- } else {
- AppMsg.makeText(getActivity(), R.string.decryption_successful,
- AppMsg.STYLE_INFO).show();
-
- if (mDeleteAfter.isChecked()) {
- // Create and show dialog to delete original file
- DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment
- .newInstance(mInputFilename);
- deleteFileDialog.show(getActivity().getSupportFragmentManager(), "deleteDialog");
- }
-
- OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult();
-
- // display signature result in activity
- onSignatureResult(signatureResult);
- }
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
-
- // show progress dialog
- saveHandler.showProgressDialog(getActivity());
-
- // start service with intent
- getActivity().startService(intent);
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case RESULT_CODE_FILE: {
- if (resultCode == Activity.RESULT_OK && data != null) {
- try {
- String path = FileHelper.getPath(getActivity(), data.getData());
- Log.d(Constants.TAG, "path=" + path);
-
- mFilename.setText(path);
- } catch (NullPointerException e) {
- Log.e(Constants.TAG, "Nullpointer while retrieving path!");
- }
- }
- return;
- }
-
- default: {
- super.onActivityResult(requestCode, resultCode, data);
-
- break;
- }
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
deleted file mode 100644
index 1c465f55c..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.support.v4.app.Fragment;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.ImageView;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-
-import com.beardedhen.androidbootstrap.BootstrapButton;
-import com.devspark.appmsg.AppMsg;
-
-import org.openintents.openpgp.OpenPgpSignatureResult;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
-
-public class DecryptFragment extends Fragment {
- private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006;
-
- protected long mSignatureKeyId = 0;
-
- protected RelativeLayout mSignatureLayout = null;
- protected ImageView mSignatureStatusImage = null;
- protected TextView mUserId = null;
- protected TextView mUserIdRest = null;
-
- protected BootstrapButton mLookupKey = null;
-
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- mSignatureLayout = (RelativeLayout) getView().findViewById(R.id.signature);
- mSignatureStatusImage = (ImageView) getView().findViewById(R.id.ic_signature_status);
- mUserId = (TextView) getView().findViewById(R.id.mainUserId);
- mUserIdRest = (TextView) getView().findViewById(R.id.mainUserIdRest);
- mLookupKey = (BootstrapButton) getView().findViewById(R.id.lookup_key);
- mLookupKey.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- lookupUnknownKey(mSignatureKeyId);
- }
- });
- mSignatureLayout.setVisibility(View.GONE);
- mSignatureLayout.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- lookupUnknownKey(mSignatureKeyId);
- }
- });
- }
-
- private void lookupUnknownKey(long unknownKeyId) {
- Intent intent = new Intent(getActivity(), ImportKeysActivity.class);
- intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER);
- intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, unknownKeyId);
- startActivityForResult(intent, RESULT_CODE_LOOKUP_KEY);
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
-
- case RESULT_CODE_LOOKUP_KEY: {
- if (resultCode == Activity.RESULT_OK) {
- // TODO: generate new OpenPgpSignatureResult and display it
- }
- return;
- }
-
- default: {
- super.onActivityResult(requestCode, resultCode, data);
-
- break;
- }
- }
- }
-
- protected void onSignatureResult(OpenPgpSignatureResult signatureResult) {
- mSignatureKeyId = 0;
- mSignatureLayout.setVisibility(View.GONE);
- if (signatureResult != null) {
-
- mSignatureKeyId = signatureResult.getKeyId();
-
- String userId = signatureResult.getUserId();
- String[] userIdSplit = PgpKeyHelper.splitUserId(userId);
- if (userIdSplit[0] != null) {
- mUserId.setText(userId);
- } else {
- mUserId.setText(R.string.user_id_no_name);
- }
- if (userIdSplit[1] != null) {
- mUserIdRest.setText(userIdSplit[1]);
- } else {
- mUserIdRest.setText(getString(R.string.label_key_id) + ": "
- + PgpKeyHelper.convertKeyIdToHex(mSignatureKeyId));
- }
-
- switch (signatureResult.getStatus()) {
- case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: {
- mSignatureStatusImage.setImageResource(R.drawable.overlay_ok);
- mLookupKey.setVisibility(View.GONE);
- break;
- }
-
- // TODO!
-// case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: {
-// break;
-// }
-
- case OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY: {
- mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
- mLookupKey.setVisibility(View.VISIBLE);
- AppMsg.makeText(getActivity(),
- R.string.unknown_signature,
- AppMsg.STYLE_ALERT).show();
- break;
- }
-
- default: {
- mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
- mLookupKey.setVisibility(View.GONE);
- break;
- }
- }
- mSignatureLayout.setVisibility(View.VISIBLE);
- }
- }
-
- protected void showPassphraseDialog(long keyId) {
- PassphraseDialogFragment.show(getActivity(), keyId,
- new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
- String passphrase =
- message.getData().getString(PassphraseDialogFragment.MESSAGE_DATA_PASSPHRASE);
- decryptStart(passphrase);
- }
- }
- });
- }
-
- /**
- * Should be overridden by MessageFragment and FileFragment to start actual decryption
- *
- * @param passphrase
- */
- protected void decryptStart(String passphrase) {
-
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java
deleted file mode 100644
index 2169bbd77..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.app.ProgressDialog;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Message;
-import android.os.Messenger;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.EditText;
-
-import com.beardedhen.androidbootstrap.BootstrapButton;
-import com.devspark.appmsg.AppMsg;
-
-import org.openintents.openpgp.OpenPgpSignatureResult;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
-import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
-import org.sufficientlysecure.keychain.pgp.PgpHelper;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.util.regex.Matcher;
-
-public class DecryptMessageFragment extends DecryptFragment {
- public static final String ARG_CIPHERTEXT = "ciphertext";
-
- // view
- private EditText mMessage;
- private BootstrapButton mDecryptButton;
- private BootstrapButton mDecryptFromCLipboardButton;
-
- // model
- private String mCiphertext;
-
- /**
- * Inflate the layout for this fragment
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.decrypt_message_fragment, container, false);
-
- mMessage = (EditText) view.findViewById(R.id.message);
- mDecryptButton = (BootstrapButton) view.findViewById(R.id.action_decrypt);
- mDecryptFromCLipboardButton = (BootstrapButton) view.findViewById(R.id.action_decrypt_from_clipboard);
- mDecryptButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- decryptClicked();
- }
- });
- mDecryptFromCLipboardButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- decryptFromClipboardClicked();
- }
- });
-
- return view;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- String ciphertext = getArguments().getString(ARG_CIPHERTEXT);
- if (ciphertext != null) {
- mMessage.setText(ciphertext);
- decryptStart(null);
- }
- }
-
- private void decryptClicked() {
- mCiphertext = mMessage.getText().toString();
- decryptStart(null);
- }
-
- private void decryptFromClipboardClicked() {
- CharSequence clipboardText = ClipboardReflection.getClipboardText(getActivity());
-
- // only decrypt if clipboard content is available and a pgp message or cleartext signature
- if (clipboardText != null) {
- Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(clipboardText);
- if (!matcher.matches()) {
- matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(clipboardText);
- }
- if (matcher.matches()) {
- mCiphertext = matcher.group(1);
- decryptStart(null);
- } else {
- AppMsg.makeText(getActivity(), R.string.error_invalid_data, AppMsg.STYLE_INFO)
- .show();
- }
- } else {
- AppMsg.makeText(getActivity(), R.string.error_invalid_data, AppMsg.STYLE_INFO)
- .show();
- }
- }
-
- @Override
- protected void decryptStart(String passphrase) {
- Log.d(Constants.TAG, "decryptStart");
-
- // Send all information needed to service to decrypt in other thread
- Intent intent = new Intent(getActivity(), KeychainIntentService.class);
-
- // fill values for this action
- Bundle data = new Bundle();
-
- intent.setAction(KeychainIntentService.ACTION_DECRYPT_VERIFY);
-
- // data
- data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES);
- data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, mCiphertext.getBytes());
- data.putString(KeychainIntentService.DECRYPT_PASSPHRASE, passphrase);
-
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
-
- // Message is received after encrypting is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(),
- getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) {
- public void handleMessage(Message message) {
- // handle messages by standard KeychainIntentServiceHandler first
- super.handleMessage(message);
-
- if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- // get returned data bundle
- Bundle returnData = message.getData();
-
- PgpDecryptVerifyResult decryptVerifyResult =
- returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT);
-
- if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) {
- showPassphraseDialog(decryptVerifyResult.getKeyIdPassphraseNeeded());
- } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED ==
- decryptVerifyResult.getStatus()) {
- showPassphraseDialog(Id.key.symmetric);
- } else {
- AppMsg.makeText(getActivity(), R.string.decryption_successful,
- AppMsg.STYLE_INFO).show();
-
- byte[] decryptedMessage = returnData
- .getByteArray(KeychainIntentService.RESULT_DECRYPTED_BYTES);
- mMessage.setText(new String(decryptedMessage));
- mMessage.setHorizontallyScrolling(false);
-
- OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult();
-
- // display signature result in activity
- onSignatureResult(signatureResult);
- }
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
-
- // show progress dialog
- saveHandler.showProgressDialog(getActivity());
-
- // start service with intent
- getActivity().startService(intent);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java
deleted file mode 100644
index c875818e3..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DrawerActivity.java
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.graphics.Color;
-import android.os.Bundle;
-import android.support.v4.app.ActionBarDrawerToggle;
-import android.support.v4.view.GravityCompat;
-import android.support.v4.widget.DrawerLayout;
-import android.support.v7.app.ActionBarActivity;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import com.beardedhen.androidbootstrap.FontAwesomeText;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-
-public class DrawerActivity extends ActionBarActivity {
- private DrawerLayout mDrawerLayout;
- private ListView mDrawerList;
- private ActionBarDrawerToggle mDrawerToggle;
-
- private CharSequence mDrawerTitle;
- private CharSequence mTitle;
- private boolean mIsDrawerLocked = false;
-
- private Class mSelectedItem;
-
- private static final int MENU_ID_PREFERENCE = 222;
- private static final int MENU_ID_HELP = 223;
-
- protected void setupDrawerNavigation(Bundle savedInstanceState) {
- mDrawerTitle = getString(R.string.app_name);
- mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
- mDrawerList = (ListView) findViewById(R.id.left_drawer);
- ViewGroup viewGroup = (ViewGroup) findViewById(R.id.content_frame);
- int leftMarginLoaded = ((ViewGroup.MarginLayoutParams) viewGroup.getLayoutParams()).leftMargin;
- int leftMarginInTablets = (int) getResources().getDimension(R.dimen.drawer_size);
- int errorInMarginAllowed = 5;
-
- // if the left margin of the loaded layout is close to the
- // one used in tablets then set drawer as open and locked
- if (Math.abs(leftMarginLoaded - leftMarginInTablets) < errorInMarginAllowed) {
- mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN, mDrawerList);
- mDrawerLayout.setScrimColor(Color.TRANSPARENT);
- mIsDrawerLocked = true;
- } else {
- // set a custom shadow that overlays the main content when the drawer opens
- mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
- mIsDrawerLocked = false;
- }
-
- NavItem mItemIconTexts[] = new NavItem[]{
- new NavItem("fa-user", getString(R.string.nav_contacts)),
- new NavItem("fa-lock", getString(R.string.nav_encrypt)),
- new NavItem("fa-unlock", getString(R.string.nav_decrypt)),
- new NavItem("fa-android", getString(R.string.nav_apps))};
-
- mDrawerList.setAdapter(new NavigationDrawerAdapter(this, R.layout.drawer_list_item,
- mItemIconTexts));
-
- mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
-
- // enable ActionBar app icon to behave as action to toggle nav drawer
- // if the drawer is not locked
- if (!mIsDrawerLocked) {
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- getSupportActionBar().setHomeButtonEnabled(true);
- }
-
- // ActionBarDrawerToggle ties together the the proper interactions
- // between the sliding drawer and the action bar app icon
- mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
- mDrawerLayout, /* DrawerLayout object */
- R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
- R.string.drawer_open, /* "open drawer" description for accessibility */
- R.string.drawer_close /* "close drawer" description for accessibility */
- ) {
- public void onDrawerClosed(View view) {
- getSupportActionBar().setTitle(mTitle);
-
- callIntentForDrawerItem(mSelectedItem);
- }
-
- public void onDrawerOpened(View drawerView) {
- mTitle = getSupportActionBar().getTitle();
- getSupportActionBar().setTitle(mDrawerTitle);
- // creates call to onPrepareOptionsMenu()
- supportInvalidateOptionsMenu();
- }
- };
-
- if (!mIsDrawerLocked) {
- mDrawerLayout.setDrawerListener(mDrawerToggle);
- } else {
- // If the drawer is locked open make it un-focusable
- // so that it doesn't consume all the Back button presses
- mDrawerLayout.setFocusableInTouchMode(false);
- }
- }
-
- /**
- * Uses startActivity to call the Intent of the given class
- *
- * @param drawerItem the class of the drawer item you want to load. Based on Constants.DrawerItems.*
- */
- public void callIntentForDrawerItem(Class drawerItem) {
- // creates call to onPrepareOptionsMenu()
- supportInvalidateOptionsMenu();
-
- // call intent activity if selected
- if (drawerItem != null) {
- finish();
- overridePendingTransition(0, 0);
-
- Intent intent = new Intent(this, drawerItem);
- startActivity(intent);
-
- // disable animation of activity start
- overridePendingTransition(0, 0);
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- if (mDrawerToggle == null) {
- return super.onCreateOptionsMenu(menu);
- }
-
- menu.add(42, MENU_ID_PREFERENCE, 100, R.string.menu_preferences);
- menu.add(42, MENU_ID_HELP, 101, R.string.menu_help);
-
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (mDrawerToggle == null) {
- return super.onOptionsItemSelected(item);
- }
-
- // The action bar home/up action should open or close the drawer.
- // ActionBarDrawerToggle will take care of this.
- if (mDrawerToggle.onOptionsItemSelected(item)) {
- return true;
- }
-
- switch (item.getItemId()) {
- case MENU_ID_PREFERENCE: {
- Intent intent = new Intent(this, PreferencesActivity.class);
- startActivity(intent);
- return true;
- }
- case MENU_ID_HELP: {
- Intent intent = new Intent(this, HelpActivity.class);
- startActivity(intent);
- return true;
- }
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-
- /**
- * The click listener for ListView in the navigation drawer
- */
- private class DrawerItemClickListener implements ListView.OnItemClickListener {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- selectItem(position);
- }
- }
-
- private void selectItem(int position) {
- // update selected item and title, then close the drawer
- mDrawerList.setItemChecked(position, true);
- // set selected class
- mSelectedItem = Constants.DrawerItems.ARRAY[position];
-
- // setTitle(mDrawerTitles[position]);
- // If drawer isn't locked just close the drawer and
- // it will move to the selected item by itself (via drawer toggle listener)
- if (!mIsDrawerLocked) {
- mDrawerLayout.closeDrawer(mDrawerList);
- // else move to the selected item yourself
- } else {
- callIntentForDrawerItem(mSelectedItem);
- }
- }
-
- /**
- * When using the ActionBarDrawerToggle, you must call it during onPostCreate() and
- * onConfigurationChanged()...
- */
- @Override
- protected void onPostCreate(Bundle savedInstanceState) {
- super.onPostCreate(savedInstanceState);
- // Sync the toggle state after onRestoreInstanceState has occurred.
- if (mDrawerToggle != null) {
- mDrawerToggle.syncState();
- }
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- // Pass any configuration change to the drawer toggles
- if (mDrawerToggle != null) {
- mDrawerToggle.onConfigurationChanged(newConfig);
- }
- }
-
- private class NavItem {
- public String icon;
- public String title;
-
- public NavItem(String icon, String title) {
- super();
- this.icon = icon;
- this.title = title;
- }
- }
-
- private class NavigationDrawerAdapter extends ArrayAdapter<NavItem> {
- Context mContext;
- int mLayoutResourceId;
- NavItem mData[] = null;
-
- public NavigationDrawerAdapter(Context context, int layoutResourceId, NavItem[] data) {
- super(context, layoutResourceId, data);
- this.mLayoutResourceId = layoutResourceId;
- this.mContext = context;
- this.mData = data;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- View row = convertView;
- NavItemHolder holder;
-
- if (row == null) {
- LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
- row = inflater.inflate(mLayoutResourceId, parent, false);
-
- holder = new NavItemHolder();
- holder.mImg = (FontAwesomeText) row.findViewById(R.id.drawer_item_icon);
- holder.mTxtTitle = (TextView) row.findViewById(R.id.drawer_item_text);
-
- row.setTag(holder);
- } else {
- holder = (NavItemHolder) row.getTag();
- }
-
- NavItem item = mData[position];
- holder.mTxtTitle.setText(item.title);
- holder.mImg.setIcon(item.icon);
-
- return row;
- }
-
- }
-
- static class NavItemHolder {
- FontAwesomeText mImg;
- TextView mTxtTitle;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
deleted file mode 100644
index 93d5688b9..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
+++ /dev/null
@@ -1,760 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
-import android.support.v4.app.ActivityCompat;
-import android.support.v7.app.ActionBarActivity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.widget.LinearLayout;
-
-import com.beardedhen.androidbootstrap.BootstrapButton;
-import com.devspark.appmsg.AppMsg;
-
-import org.spongycastle.openpgp.PGPSecretKey;
-import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.ActionBarHelper;
-import org.sufficientlysecure.keychain.helper.ExportHelper;
-import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.service.PassphraseCacheService;
-import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
-import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
-import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment;
-import org.sufficientlysecure.keychain.ui.widget.Editor;
-import org.sufficientlysecure.keychain.ui.widget.Editor.EditorListener;
-import org.sufficientlysecure.keychain.ui.widget.KeyEditor;
-import org.sufficientlysecure.keychain.ui.widget.SectionView;
-import org.sufficientlysecure.keychain.ui.widget.UserIdEditor;
-import org.sufficientlysecure.keychain.util.IterableIterator;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.util.ArrayList;
-import java.util.GregorianCalendar;
-import java.util.List;
-import java.util.Vector;
-
-public class EditKeyActivity extends ActionBarActivity implements EditorListener {
-
- // Actions for internal use only:
- public static final String ACTION_CREATE_KEY = Constants.INTENT_PREFIX + "CREATE_KEY";
- public static final String ACTION_EDIT_KEY = Constants.INTENT_PREFIX + "EDIT_KEY";
-
- // possible extra keys
- public static final String EXTRA_USER_IDS = "user_ids";
- public static final String EXTRA_NO_PASSPHRASE = "no_passphrase";
- public static final String EXTRA_GENERATE_DEFAULT_KEYS = "generate_default_keys";
-
- // EDIT
- private Uri mDataUri;
-
- private PGPSecretKeyRing mKeyRing = null;
-
- private SectionView mUserIdsView;
- private SectionView mKeysView;
-
- private String mCurrentPassphrase = null;
- private String mNewPassphrase = null;
- private String mSavedNewPassphrase = null;
- private boolean mIsPassphraseSet;
- private boolean mNeedsSaving;
- private boolean mIsBrandNewKeyring = false;
-
- private BootstrapButton mChangePassphrase;
-
- private CheckBox mNoPassphrase;
-
- Vector<String> mUserIds;
- Vector<PGPSecretKey> mKeys;
- Vector<Integer> mKeysUsages;
- boolean mMasterCanSign = true;
-
- ExportHelper mExportHelper;
-
- public boolean needsSaving() {
- mNeedsSaving = (mUserIdsView == null) ? false : mUserIdsView.needsSaving();
- mNeedsSaving |= (mKeysView == null) ? false : mKeysView.needsSaving();
- mNeedsSaving |= hasPassphraseChanged();
- mNeedsSaving |= mIsBrandNewKeyring;
- return mNeedsSaving;
- }
-
-
- public void somethingChanged() {
- ActivityCompat.invalidateOptionsMenu(this);
- }
-
- public void onDeleted(Editor e, boolean wasNewItem) {
- somethingChanged();
- }
-
- public void onEdited() {
- somethingChanged();
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- mExportHelper = new ExportHelper(this);
-
- // Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setTwoButtonView(getSupportActionBar(),
- R.string.btn_save, R.drawable.ic_action_save,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // Save
- saveClicked();
- }
- }, R.string.menu_key_edit_cancel, R.drawable.ic_action_cancel,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // Cancel
- cancelClicked();
- }
- }
- );
-
- mUserIds = new Vector<String>();
- mKeys = new Vector<PGPSecretKey>();
- mKeysUsages = new Vector<Integer>();
-
- // Catch Intents opened from other apps
- Intent intent = getIntent();
- String action = intent.getAction();
- if (ACTION_CREATE_KEY.equals(action)) {
- handleActionCreateKey(intent);
- } else if (ACTION_EDIT_KEY.equals(action)) {
- handleActionEditKey(intent);
- }
- }
-
- /**
- * Handle intent action to create new key
- *
- * @param intent
- */
- private void handleActionCreateKey(Intent intent) {
- Bundle extras = intent.getExtras();
-
- mCurrentPassphrase = "";
- mIsBrandNewKeyring = true;
-
- if (extras != null) {
- // if userId is given, prefill the fields
- if (extras.containsKey(EXTRA_USER_IDS)) {
- Log.d(Constants.TAG, "UserIds are given!");
- mUserIds.add(extras.getString(EXTRA_USER_IDS));
- }
-
- // if no passphrase is given
- if (extras.containsKey(EXTRA_NO_PASSPHRASE)) {
- boolean noPassphrase = extras.getBoolean(EXTRA_NO_PASSPHRASE);
- if (noPassphrase) {
- // check "no passphrase" checkbox and remove button
- mNoPassphrase.setChecked(true);
- mChangePassphrase.setVisibility(View.GONE);
- }
- }
-
- // generate key
- if (extras.containsKey(EXTRA_GENERATE_DEFAULT_KEYS)) {
- boolean generateDefaultKeys = extras.getBoolean(EXTRA_GENERATE_DEFAULT_KEYS);
- if (generateDefaultKeys) {
-
- // Send all information needed to service generate keys in other thread
- final Intent serviceIntent = new Intent(this, KeychainIntentService.class);
- serviceIntent.setAction(KeychainIntentService.ACTION_GENERATE_DEFAULT_RSA_KEYS);
-
- // fill values for this action
- Bundle data = new Bundle();
- data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE,
- mCurrentPassphrase);
-
- serviceIntent.putExtra(KeychainIntentService.EXTRA_DATA, data);
-
- // Message is received after generating is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
- this, getResources().getQuantityString(R.plurals.progress_generating, 1),
- ProgressDialog.STYLE_HORIZONTAL, true,
-
- new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- // Stop key generation on cancel
- stopService(serviceIntent);
- EditKeyActivity.this.setResult(Activity.RESULT_CANCELED);
- EditKeyActivity.this.finish();
- }
- }) {
-
- @Override
- public void handleMessage(Message message) {
- // handle messages by standard KeychainIntentServiceHandler first
- super.handleMessage(message);
-
- if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- // get new key from data bundle returned from service
- Bundle data = message.getData();
-
- ArrayList<PGPSecretKey> newKeys =
- PgpConversionHelper.BytesToPGPSecretKeyList(data
- .getByteArray(KeychainIntentService.RESULT_NEW_KEY));
-
- ArrayList<Integer> keyUsageFlags = data.getIntegerArrayList(
- KeychainIntentService.RESULT_KEY_USAGES);
-
- if (newKeys.size() == keyUsageFlags.size()) {
- for (int i = 0; i < newKeys.size(); ++i) {
- mKeys.add(newKeys.get(i));
- mKeysUsages.add(keyUsageFlags.get(i));
- }
- }
-
- buildLayout(true);
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- serviceIntent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
-
- saveHandler.showProgressDialog(this);
-
- // start service with intent
- startService(serviceIntent);
- }
- }
- } else {
- buildLayout(false);
- }
- }
-
- /**
- * Handle intent action to edit existing key
- *
- * @param intent
- */
- private void handleActionEditKey(Intent intent) {
- mDataUri = intent.getData();
- if (mDataUri == null) {
- Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!");
- finish();
- } else {
- Log.d(Constants.TAG, "uri: " + mDataUri);
-
- // get master key id using row id
- long masterKeyId = ProviderHelper.getMasterKeyId(this, mDataUri);
- finallyEdit(masterKeyId);
- }
- }
-
- @SuppressWarnings("unchecked")
- private void finallyEdit(final long masterKeyId) {
- if (masterKeyId != 0) {
- PGPSecretKey masterKey = null;
- mKeyRing = ProviderHelper.getPGPSecretKeyRing(this, masterKeyId);
- if (mKeyRing != null) {
- masterKey = mKeyRing.getSecretKey();
- mMasterCanSign = PgpKeyHelper.isCertificationKey(mKeyRing.getSecretKey());
- for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(mKeyRing.getSecretKeys())) {
- mKeys.add(key);
- mKeysUsages.add(-1); // get usage when view is created
- }
- } else {
- Log.e(Constants.TAG, "Keyring not found with masterKeyId: " + masterKeyId);
- AppMsg.makeText(this, R.string.error_no_secret_key_found, AppMsg.STYLE_ALERT).show();
- // TODO
- }
- if (masterKey != null) {
- boolean isSet = false;
- for (String userId : new IterableIterator<String>(masterKey.getUserIDs())) {
- Log.d(Constants.TAG, "Added userId " + userId);
- if (!isSet) {
- isSet = true;
- String[] parts = PgpKeyHelper.splitUserId(userId);
- if (parts[0] != null) {
- setTitle(parts[0]);
- }
- }
- mUserIds.add(userId);
- }
- }
- }
-
- mCurrentPassphrase = "";
- buildLayout(false);
-
- mIsPassphraseSet = PassphraseCacheService.hasPassphrase(this, masterKeyId);
- if (!mIsPassphraseSet) {
- // check "no passphrase" checkbox and remove button
- mNoPassphrase.setChecked(true);
- mChangePassphrase.setVisibility(View.GONE);
- }
- }
-
- /**
- * Shows the dialog to set a new passphrase
- */
- private void showSetPassphraseDialog() {
- // Message is received after passphrase is cached
- Handler returnHandler = new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.what == SetPassphraseDialogFragment.MESSAGE_OKAY) {
- Bundle data = message.getData();
-
- // set new returned passphrase!
- mNewPassphrase = data
- .getString(SetPassphraseDialogFragment.MESSAGE_NEW_PASSPHRASE);
-
- updatePassphraseButtonText();
- somethingChanged();
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(returnHandler);
-
- // set title based on isPassphraseSet()
- int title;
- if (isPassphraseSet()) {
- title = R.string.title_change_passphrase;
- } else {
- title = R.string.title_set_passphrase;
- }
-
- SetPassphraseDialogFragment setPassphraseDialog = SetPassphraseDialogFragment.newInstance(
- messenger, title);
-
- setPassphraseDialog.show(getSupportFragmentManager(), "setPassphraseDialog");
- }
-
- /**
- * Build layout based on mUserId, mKeys and mKeysUsages Vectors. It creates Views for every user
- * id and key.
- *
- * @param newKeys
- */
- private void buildLayout(boolean newKeys) {
- setContentView(R.layout.edit_key_activity);
-
- // find views
- mChangePassphrase = (BootstrapButton) findViewById(R.id.edit_key_btn_change_passphrase);
- mNoPassphrase = (CheckBox) findViewById(R.id.edit_key_no_passphrase);
- // Build layout based on given userIds and keys
-
- LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- LinearLayout container = (LinearLayout) findViewById(R.id.edit_key_container);
- if (mIsPassphraseSet) {
- mChangePassphrase.setText(getString(R.string.btn_change_passphrase));
- }
- mUserIdsView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false);
- mUserIdsView.setType(Id.type.user_id);
- mUserIdsView.setCanBeEdited(mMasterCanSign);
- mUserIdsView.setUserIds(mUserIds);
- mUserIdsView.setEditorListener(this);
- container.addView(mUserIdsView);
- mKeysView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false);
- mKeysView.setType(Id.type.key);
- mKeysView.setCanBeEdited(mMasterCanSign);
- mKeysView.setKeys(mKeys, mKeysUsages, newKeys);
- mKeysView.setEditorListener(this);
- container.addView(mKeysView);
-
- updatePassphraseButtonText();
-
- mChangePassphrase.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- showSetPassphraseDialog();
- }
- });
-
- // disable passphrase when no passphrase checkbox is checked!
- mNoPassphrase.setOnCheckedChangeListener(new OnCheckedChangeListener() {
-
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if (isChecked) {
- // remove passphrase
- mSavedNewPassphrase = mNewPassphrase;
- mNewPassphrase = "";
- mChangePassphrase.setVisibility(View.GONE);
- } else {
- mNewPassphrase = mSavedNewPassphrase;
- mChangePassphrase.setVisibility(View.VISIBLE);
- }
- somethingChanged();
- }
- });
- }
-
- private long getMasterKeyId() {
- if (mKeysView.getEditors().getChildCount() == 0) {
- return 0;
- }
- return ((KeyEditor) mKeysView.getEditors().getChildAt(0)).getValue().getKeyID();
- }
-
- public boolean isPassphraseSet() {
- if (mNoPassphrase.isChecked()) {
- return true;
- } else if ((mIsPassphraseSet)
- || (mNewPassphrase != null && !mNewPassphrase.equals(""))) {
- return true;
- } else {
- return false;
- }
- }
-
- public boolean hasPassphraseChanged() {
- if (mNoPassphrase != null) {
- if (mNoPassphrase.isChecked()) {
- return mIsPassphraseSet;
- } else {
- return (mNewPassphrase != null && !mNewPassphrase.equals(""));
- }
- } else {
- return false;
- }
- }
-
- private void saveClicked() {
- final long masterKeyId = getMasterKeyId();
- if (needsSaving()) { //make sure, as some versions don't support invalidateOptionsMenu
- try {
- if (!isPassphraseSet()) {
- throw new PgpGeneralException(this.getString(R.string.set_a_passphrase));
- }
-
- String passphrase;
- if (mIsPassphraseSet) {
- passphrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId);
- } else {
- passphrase = "";
- }
- if (passphrase == null) {
- PassphraseDialogFragment.show(this, masterKeyId,
- new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
- mCurrentPassphrase = PassphraseCacheService.getCachedPassphrase(
- EditKeyActivity.this, masterKeyId);
- checkEmptyIDsWanted();
- }
- }
- });
- } else {
- mCurrentPassphrase = passphrase;
- checkEmptyIDsWanted();
- }
- } catch (PgpGeneralException e) {
- AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()),
- AppMsg.STYLE_ALERT).show();
- }
- } else {
- AppMsg.makeText(this, R.string.error_change_something_first, AppMsg.STYLE_ALERT).show();
- }
- }
-
- private void checkEmptyIDsWanted() {
- try {
- ArrayList<String> userIDs = getUserIds(mUserIdsView);
- List<Boolean> newIDs = mUserIdsView.getNewIDFlags();
- ArrayList<String> originalIDs = mUserIdsView.getOriginalIDs();
- int curID = 0;
- for (String userID : userIDs) {
- if (userID.equals("") && (!userID.equals(originalIDs.get(curID)) || newIDs.get(curID))) {
- AlertDialog.Builder alert = new AlertDialog.Builder(
- EditKeyActivity.this);
-
- alert.setIcon(R.drawable.ic_dialog_alert_holo_light);
- alert.setTitle(R.string.warning);
- alert.setMessage(EditKeyActivity.this.getString(R.string.ask_empty_id_ok));
-
- alert.setPositiveButton(EditKeyActivity.this.getString(android.R.string.yes),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.dismiss();
- finallySaveClicked();
- }
- }
- );
- alert.setNegativeButton(this.getString(android.R.string.no),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.dismiss();
- }
- }
- );
- alert.setCancelable(false);
- alert.create().show();
- return;
- }
- curID++;
- }
- } catch (PgpGeneralException e) {
- Log.e(Constants.TAG, getString(R.string.error_message, e.getMessage()));
- AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()), AppMsg.STYLE_ALERT).show();
- }
- finallySaveClicked();
- }
-
- private boolean[] toPrimitiveArray(final List<Boolean> booleanList) {
- final boolean[] primitives = new boolean[booleanList.size()];
- int index = 0;
- for (Boolean object : booleanList) {
- primitives[index++] = object;
- }
- return primitives;
- }
-
- private void finallySaveClicked() {
- try {
- // Send all information needed to service to edit key in other thread
- Intent intent = new Intent(this, KeychainIntentService.class);
-
- intent.setAction(KeychainIntentService.ACTION_SAVE_KEYRING);
-
- SaveKeyringParcel saveParams = new SaveKeyringParcel();
- saveParams.userIDs = getUserIds(mUserIdsView);
- saveParams.originalIDs = mUserIdsView.getOriginalIDs();
- saveParams.deletedIDs = mUserIdsView.getDeletedIDs();
- saveParams.newIDs = toPrimitiveArray(mUserIdsView.getNewIDFlags());
- saveParams.primaryIDChanged = mUserIdsView.primaryChanged();
- saveParams.moddedKeys = toPrimitiveArray(mKeysView.getNeedsSavingArray());
- saveParams.deletedKeys = mKeysView.getDeletedKeys();
- saveParams.keysExpiryDates = getKeysExpiryDates(mKeysView);
- saveParams.keysUsages = getKeysUsages(mKeysView);
- saveParams.newPassphrase = mNewPassphrase;
- saveParams.oldPassphrase = mCurrentPassphrase;
- saveParams.newKeys = toPrimitiveArray(mKeysView.getNewKeysArray());
- saveParams.keys = getKeys(mKeysView);
- saveParams.originalPrimaryID = mUserIdsView.getOriginalPrimaryID();
-
-
- // fill values for this action
- Bundle data = new Bundle();
- data.putBoolean(KeychainIntentService.SAVE_KEYRING_CAN_SIGN, mMasterCanSign);
- data.putParcelable(KeychainIntentService.SAVE_KEYRING_PARCEL, saveParams);
-
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
-
- // Message is received after saving is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- getString(R.string.progress_saving), ProgressDialog.STYLE_HORIZONTAL) {
- public void handleMessage(Message message) {
- // handle messages by standard KeychainIntentServiceHandler first
- super.handleMessage(message);
-
- if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- Intent data = new Intent();
-
- // return uri pointing to new created key
- Uri uri = KeychainContract.KeyRings.buildGenericKeyRingUri(
- String.valueOf(getMasterKeyId()));
- data.setData(uri);
-
- setResult(RESULT_OK, data);
- finish();
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
-
- saveHandler.showProgressDialog(this);
-
- // start service with intent
- startService(intent);
- } catch (PgpGeneralException e) {
- Log.e(Constants.TAG, getString(R.string.error_message, e.getMessage()));
- AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()),
- AppMsg.STYLE_ALERT).show();
- }
- }
-
- private void cancelClicked() {
- if (needsSaving()) { //ask if we want to save
- AlertDialog.Builder alert = new AlertDialog.Builder(
- EditKeyActivity.this);
-
- alert.setIcon(R.drawable.ic_dialog_alert_holo_light);
- alert.setTitle(R.string.warning);
- alert.setMessage(EditKeyActivity.this.getString(R.string.ask_save_changed_key));
-
- alert.setPositiveButton(EditKeyActivity.this.getString(android.R.string.yes),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.dismiss();
- saveClicked();
- }
- });
- alert.setNegativeButton(this.getString(android.R.string.no),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.dismiss();
- setResult(RESULT_CANCELED);
- finish();
- }
- });
- alert.setCancelable(false);
- alert.create().show();
- } else {
- setResult(RESULT_CANCELED);
- finish();
- }
- }
-
- /**
- * Returns user ids from the SectionView
- *
- * @param userIdsView
- * @return
- */
- private ArrayList<String> getUserIds(SectionView userIdsView) throws PgpGeneralException {
- ArrayList<String> userIds = new ArrayList<String>();
-
- ViewGroup userIdEditors = userIdsView.getEditors();
-
- boolean gotMainUserId = false;
- for (int i = 0; i < userIdEditors.getChildCount(); ++i) {
- UserIdEditor editor = (UserIdEditor) userIdEditors.getChildAt(i);
- String userId;
- userId = editor.getValue();
-
- if (editor.isMainUserId()) {
- userIds.add(0, userId);
- gotMainUserId = true;
- } else {
- userIds.add(userId);
- }
- }
-
- if (userIds.size() == 0) {
- throw new PgpGeneralException(getString(R.string.error_key_needs_a_user_id));
- }
-
- if (!gotMainUserId) {
- throw new PgpGeneralException(getString(R.string.error_main_user_id_must_not_be_empty));
- }
-
- return userIds;
- }
-
- /**
- * Returns keys from the SectionView
- *
- * @param keysView
- * @return
- */
- private ArrayList<PGPSecretKey> getKeys(SectionView keysView) throws PgpGeneralException {
- ArrayList<PGPSecretKey> keys = new ArrayList<PGPSecretKey>();
-
- ViewGroup keyEditors = keysView.getEditors();
-
- if (keyEditors.getChildCount() == 0) {
- throw new PgpGeneralException(getString(R.string.error_key_needs_master_key));
- }
-
- for (int i = 0; i < keyEditors.getChildCount(); ++i) {
- KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
- keys.add(editor.getValue());
- }
-
- return keys;
- }
-
- /**
- * Returns usage selections of keys from the SectionView
- *
- * @param keysView
- * @return
- */
- private ArrayList<Integer> getKeysUsages(SectionView keysView) throws PgpGeneralException {
- ArrayList<Integer> keysUsages = new ArrayList<Integer>();
-
- ViewGroup keyEditors = keysView.getEditors();
-
- if (keyEditors.getChildCount() == 0) {
- throw new PgpGeneralException(getString(R.string.error_key_needs_master_key));
- }
-
- for (int i = 0; i < keyEditors.getChildCount(); ++i) {
- KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
- keysUsages.add(editor.getUsage());
- }
-
- return keysUsages;
- }
-
- private ArrayList<GregorianCalendar> getKeysExpiryDates(SectionView keysView) throws PgpGeneralException {
- ArrayList<GregorianCalendar> keysExpiryDates = new ArrayList<GregorianCalendar>();
-
- ViewGroup keyEditors = keysView.getEditors();
-
- if (keyEditors.getChildCount() == 0) {
- throw new PgpGeneralException(getString(R.string.error_key_needs_master_key));
- }
-
- for (int i = 0; i < keyEditors.getChildCount(); ++i) {
- KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
- keysExpiryDates.add(editor.getExpiryDate());
- }
-
- return keysExpiryDates;
- }
-
- private void updatePassphraseButtonText() {
- mChangePassphrase.setText(isPassphraseSet() ? getString(R.string.btn_change_passphrase)
- : getString(R.string.btn_set_passphrase));
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
deleted file mode 100644
index a03c7d797..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.view.PagerTabStrip;
-import android.support.v4.view.ViewPager;
-import android.widget.Toast;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.ActionBarHelper;
-import org.sufficientlysecure.keychain.helper.FileHelper;
-import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter;
-import org.sufficientlysecure.keychain.util.Log;
-
-public class EncryptActivity extends DrawerActivity implements
- EncryptSymmetricFragment.OnSymmetricKeySelection,
- EncryptAsymmetricFragment.OnAsymmetricKeySelection,
- EncryptActivityInterface {
-
- /* Intents */
- public static final String ACTION_ENCRYPT = Constants.INTENT_PREFIX + "ENCRYPT";
-
- /* EXTRA keys for input */
- public static final String EXTRA_TEXT = "text";
-
- // enables ASCII Armor for file encryption when uri is given
- public static final String EXTRA_ASCII_ARMOR = "ascii_armor";
-
- // preselect ids, for internal use
- public static final String EXTRA_SIGNATURE_KEY_ID = "signature_key_id";
- public static final String EXTRA_ENCRYPTION_KEY_IDS = "encryption_key_ids";
-
- // view
- ViewPager mViewPagerMode;
- PagerTabStrip mPagerTabStripMode;
- PagerTabStripAdapter mTabsAdapterMode;
- ViewPager mViewPagerContent;
- PagerTabStrip mPagerTabStripContent;
- PagerTabStripAdapter mTabsAdapterContent;
-
- // tabs
- Bundle mAsymmetricFragmentBundle = new Bundle();
- Bundle mSymmetricFragmentBundle = new Bundle();
- Bundle mMessageFragmentBundle = new Bundle();
- Bundle mFileFragmentBundle = new Bundle();
- int mSwitchToMode = PAGER_MODE_ASYMMETRIC;
- int mSwitchToContent = PAGER_CONTENT_MESSAGE;
-
- private static final int PAGER_MODE_ASYMMETRIC = 0;
- private static final int PAGER_MODE_SYMMETRIC = 1;
- private static final int PAGER_CONTENT_MESSAGE = 0;
- private static final int PAGER_CONTENT_FILE = 1;
-
- // model useb by message and file fragment
- private long mEncryptionKeyIds[] = null;
- private long mSigningKeyId = Id.key.none;
- private String mPassphrase;
- private String mPassphraseAgain;
-
- @Override
- public void onSigningKeySelected(long signingKeyId) {
- mSigningKeyId = signingKeyId;
- }
-
- @Override
- public void onEncryptionKeysSelected(long[] encryptionKeyIds) {
- mEncryptionKeyIds = encryptionKeyIds;
- }
-
- @Override
- public void onPassphraseUpdate(String passphrase) {
- mPassphrase = passphrase;
- }
-
- @Override
- public void onPassphraseAgainUpdate(String passphrase) {
- mPassphraseAgain = passphrase;
- }
-
- @Override
- public boolean isModeSymmetric() {
- if (PAGER_MODE_SYMMETRIC == mViewPagerMode.getCurrentItem()) {
- return true;
- } else {
- return false;
- }
- }
-
- @Override
- public long getSignatureKey() {
- return mSigningKeyId;
- }
-
- @Override
- public long[] getEncryptionKeys() {
- return mEncryptionKeyIds;
- }
-
- @Override
- public String getPassphrase() {
- return mPassphrase;
- }
-
- @Override
- public String getPassphraseAgain() {
- return mPassphraseAgain;
- }
-
-
- private void initView() {
- mViewPagerMode = (ViewPager) findViewById(R.id.encrypt_pager_mode);
- mPagerTabStripMode = (PagerTabStrip) findViewById(R.id.encrypt_pager_tab_strip_mode);
- mViewPagerContent = (ViewPager) findViewById(R.id.encrypt_pager_content);
- mPagerTabStripContent = (PagerTabStrip) findViewById(R.id.encrypt_pager_tab_strip_content);
-
- mTabsAdapterMode = new PagerTabStripAdapter(this);
- mViewPagerMode.setAdapter(mTabsAdapterMode);
- mTabsAdapterContent = new PagerTabStripAdapter(this);
- mViewPagerContent.setAdapter(mTabsAdapterContent);
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.encrypt_activity);
-
- // set actionbar without home button if called from another app
- ActionBarHelper.setBackButton(this);
-
- initView();
-
- setupDrawerNavigation(savedInstanceState);
-
- // Handle intent actions
- handleActions(getIntent());
-
- mTabsAdapterMode.addTab(EncryptAsymmetricFragment.class,
- mAsymmetricFragmentBundle, getString(R.string.label_asymmetric));
- mTabsAdapterMode.addTab(EncryptSymmetricFragment.class,
- mSymmetricFragmentBundle, getString(R.string.label_symmetric));
- mViewPagerMode.setCurrentItem(mSwitchToMode);
-
- mTabsAdapterContent.addTab(EncryptMessageFragment.class,
- mMessageFragmentBundle, getString(R.string.label_message));
- mTabsAdapterContent.addTab(EncryptFileFragment.class,
- mFileFragmentBundle, getString(R.string.label_file));
- mViewPagerContent.setCurrentItem(mSwitchToContent);
- }
-
- /**
- * Handles all actions with this intent
- *
- * @param intent
- */
- private void handleActions(Intent intent) {
- String action = intent.getAction();
- Bundle extras = intent.getExtras();
- String type = intent.getType();
- Uri uri = intent.getData();
-
- if (extras == null) {
- extras = new Bundle();
- }
-
- /*
- * Android's Action
- */
- if (Intent.ACTION_SEND.equals(action) && type != null) {
- // When sending to APG Encrypt via share menu
- if ("text/plain".equals(type)) {
- // Plain text
- String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
- if (sharedText != null) {
- // handle like normal text encryption, override action and extras to later
- // executeServiceMethod ACTION_ENCRYPT in main actions
- extras.putString(EXTRA_TEXT, sharedText);
- extras.putBoolean(EXTRA_ASCII_ARMOR, true);
- action = ACTION_ENCRYPT;
- }
- } else {
- // Files via content provider, override uri and action
- uri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
- action = ACTION_ENCRYPT;
- }
- }
-
- if (extras.containsKey(EXTRA_ASCII_ARMOR)) {
- boolean requestAsciiArmor = extras.getBoolean(EXTRA_ASCII_ARMOR, true);
- mFileFragmentBundle.putBoolean(EncryptFileFragment.ARG_ASCII_ARMOR, requestAsciiArmor);
- }
-
- String textData = extras.getString(EXTRA_TEXT);
-
- long signatureKeyId = extras.getLong(EXTRA_SIGNATURE_KEY_ID);
- long[] encryptionKeyIds = extras.getLongArray(EXTRA_ENCRYPTION_KEY_IDS);
-
- // preselect keys given by intent
- mAsymmetricFragmentBundle.putLongArray(EncryptAsymmetricFragment.ARG_ENCRYPTION_KEY_IDS,
- encryptionKeyIds);
- mAsymmetricFragmentBundle.putLong(EncryptAsymmetricFragment.ARG_SIGNATURE_KEY_ID,
- signatureKeyId);
- mSwitchToMode = PAGER_MODE_ASYMMETRIC;
-
- /**
- * Main Actions
- */
- if (ACTION_ENCRYPT.equals(action) && textData != null) {
- // encrypt text based on given extra
- mMessageFragmentBundle.putString(EncryptMessageFragment.ARG_TEXT, textData);
- mSwitchToContent = PAGER_CONTENT_MESSAGE;
- } else if (ACTION_ENCRYPT.equals(action) && uri != null) {
- // encrypt file based on Uri
-
- // get file path from uri
- String path = FileHelper.getPath(this, uri);
-
- if (path != null) {
- mFileFragmentBundle.putString(EncryptFileFragment.ARG_FILENAME, path);
- mSwitchToContent = PAGER_CONTENT_FILE;
- } else {
- Log.e(Constants.TAG,
- "Direct binary data without actual file in filesystem is not supported " +
- "by Intents. Please use the Remote Service API!");
- Toast.makeText(this, R.string.error_only_files_are_supported, Toast.LENGTH_LONG)
- .show();
- // end activity
- finish();
- }
- } else {
- Log.e(Constants.TAG,
- "Include the extra 'text' or an Uri with setData() in your Intent!");
- }
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java
deleted file mode 100644
index 0786b3a16..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-public interface EncryptActivityInterface {
-
- public boolean isModeSymmetric();
-
- public long getSignatureKey();
- public long[] getEncryptionKeys();
-
- public String getPassphrase();
- public String getPassphraseAgain();
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
deleted file mode 100644
index 8400cf397..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CheckBox;
-import android.widget.TextView;
-
-import com.beardedhen.androidbootstrap.BootstrapButton;
-
-import org.spongycastle.openpgp.PGPPublicKey;
-import org.spongycastle.openpgp.PGPPublicKeyRing;
-import org.spongycastle.openpgp.PGPSecretKey;
-import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-
-import java.util.HashMap;
-import java.util.Vector;
-
-public class EncryptAsymmetricFragment extends Fragment {
- public static final String ARG_SIGNATURE_KEY_ID = "signature_key_id";
- public static final String ARG_ENCRYPTION_KEY_IDS = "encryption_key_ids";
-
- public static final int RESULT_CODE_PUBLIC_KEYS = 0x00007001;
- public static final int RESULT_CODE_SECRET_KEYS = 0x00007002;
-
- OnAsymmetricKeySelection mKeySelectionListener;
-
- // view
- private BootstrapButton mSelectKeysButton;
- private CheckBox mSign;
- private TextView mMainUserId;
- private TextView mMainUserIdRest;
-
- // model
- private long mSecretKeyId = Id.key.none;
- private long mEncryptionKeyIds[] = null;
-
- // Container Activity must implement this interface
- public interface OnAsymmetricKeySelection {
- public void onSigningKeySelected(long signingKeyId);
-
- public void onEncryptionKeysSelected(long[] encryptionKeyIds);
- }
-
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- try {
- mKeySelectionListener = (OnAsymmetricKeySelection) activity;
- } catch (ClassCastException e) {
- throw new ClassCastException(activity.toString() + " must implement OnAsymmetricKeySelection");
- }
- }
-
- private void setSignatureKeyId(long signatureKeyId) {
- mSecretKeyId = signatureKeyId;
- // update key selection in EncryptActivity
- mKeySelectionListener.onSigningKeySelected(signatureKeyId);
- updateView();
- }
-
- private void setEncryptionKeyIds(long[] encryptionKeyIds) {
- mEncryptionKeyIds = encryptionKeyIds;
- // update key selection in EncryptActivity
- mKeySelectionListener.onEncryptionKeysSelected(encryptionKeyIds);
- updateView();
- }
-
- /**
- * Inflate the layout for this fragment
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.encrypt_asymmetric_fragment, container, false);
-
- mSelectKeysButton = (BootstrapButton) view.findViewById(R.id.btn_selectEncryptKeys);
- mSign = (CheckBox) view.findViewById(R.id.sign);
- mMainUserId = (TextView) view.findViewById(R.id.mainUserId);
- mMainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest);
- mSelectKeysButton.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- selectPublicKeys();
- }
- });
- mSign.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- CheckBox checkBox = (CheckBox) v;
- if (checkBox.isChecked()) {
- selectSecretKey();
- } else {
- setSignatureKeyId(Id.key.none);
- }
- }
- });
-
- return view;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- long signatureKeyId = getArguments().getLong(ARG_SIGNATURE_KEY_ID);
- long[] encryptionKeyIds = getArguments().getLongArray(ARG_ENCRYPTION_KEY_IDS);
-
- // preselect keys given by arguments (given by Intent to EncryptActivity)
- preselectKeys(signatureKeyId, encryptionKeyIds);
- }
-
- /**
- * If an Intent gives a signatureKeyId and/or encryptionKeyIds, preselect those!
- *
- * @param preselectedSignatureKeyId
- * @param preselectedEncryptionKeyIds
- */
- private void preselectKeys(long preselectedSignatureKeyId, long[] preselectedEncryptionKeyIds) {
- if (preselectedSignatureKeyId != 0) {
- // TODO: don't use bouncy castle objects!
- PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingWithKeyId(getActivity(),
- preselectedSignatureKeyId);
- PGPSecretKey masterKey;
- if (keyRing != null) {
- masterKey = keyRing.getSecretKey();
- if (masterKey != null) {
- Vector<PGPSecretKey> signKeys = PgpKeyHelper.getUsableSigningKeys(keyRing);
- if (signKeys.size() > 0) {
- setSignatureKeyId(masterKey.getKeyID());
- }
- }
- }
- }
-
- if (preselectedEncryptionKeyIds != null) {
- Vector<Long> goodIds = new Vector<Long>();
- for (int i = 0; i < preselectedEncryptionKeyIds.length; ++i) {
- long id = ProviderHelper.getMasterKeyId(getActivity(),
- KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(preselectedEncryptionKeyIds[i]))
- );
- // TODO check for available encrypt keys... is this even relevant?
- goodIds.add(id);
- }
- if (goodIds.size() > 0) {
- long[] keyIds = new long[goodIds.size()];
- for (int i = 0; i < goodIds.size(); ++i) {
- keyIds[i] = goodIds.get(i);
- }
- setEncryptionKeyIds(keyIds);
- }
- }
- }
-
- private void updateView() {
- if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) {
- mSelectKeysButton.setText(getString(R.string.select_keys_button_default));
- } else {
- mSelectKeysButton.setText(getResources().getQuantityString(
- R.plurals.select_keys_button, mEncryptionKeyIds.length,
- mEncryptionKeyIds.length));
- }
-
- if (mSecretKeyId == Id.key.none) {
- mSign.setChecked(false);
- mMainUserId.setText("");
- mMainUserIdRest.setText("");
- } else {
- // See if we can get a user_id from a unified query
- String userIdResult = (String) ProviderHelper.getUnifiedData(
- getActivity(), mSecretKeyId, KeyRings.USER_ID, ProviderHelper.FIELD_TYPE_STRING);
- String[] userId = PgpKeyHelper.splitUserId(userIdResult);
- if (userId[0] != null) {
- mMainUserId.setText(userId[0]);
- } else {
- mMainUserId.setText(getResources().getString(R.string.user_id_no_name));
- }
- if (userId[1] != null) {
- mMainUserIdRest.setText(userId[1]);
- } else {
- mMainUserIdRest.setText("");
- }
- mSign.setChecked(true);
- }
- }
-
- private void selectPublicKeys() {
- Intent intent = new Intent(getActivity(), SelectPublicKeyActivity.class);
- Vector<Long> keyIds = new Vector<Long>();
- if (mSecretKeyId != 0) {
- keyIds.add(mSecretKeyId);
- }
- if (mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0) {
- for (int i = 0; i < mEncryptionKeyIds.length; ++i) {
- keyIds.add(mEncryptionKeyIds[i]);
- }
- }
- long[] initialKeyIds = null;
- if (keyIds.size() > 0) {
- initialKeyIds = new long[keyIds.size()];
- for (int i = 0; i < keyIds.size(); ++i) {
- initialKeyIds[i] = keyIds.get(i);
- }
- }
- intent.putExtra(SelectPublicKeyActivity.EXTRA_SELECTED_MASTER_KEY_IDS, initialKeyIds);
- startActivityForResult(intent, Id.request.public_keys);
- }
-
- private void selectSecretKey() {
- Intent intent = new Intent(getActivity(), SelectSecretKeyActivity.class);
- startActivityForResult(intent, Id.request.secret_keys);
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case RESULT_CODE_PUBLIC_KEYS: {
- if (resultCode == Activity.RESULT_OK) {
- Bundle bundle = data.getExtras();
- setEncryptionKeyIds(bundle
- .getLongArray(SelectPublicKeyActivity.RESULT_EXTRA_MASTER_KEY_IDS));
- }
- break;
- }
-
- case RESULT_CODE_SECRET_KEYS: {
- if (resultCode == Activity.RESULT_OK) {
- Uri uriMasterKey = data.getData();
- setSignatureKeyId(Long.valueOf(uriMasterKey.getLastPathSegment()));
- } else {
- setSignatureKeyId(Id.key.none);
- }
- break;
- }
-
- default: {
- super.onActivityResult(requestCode, resultCode, data);
-
- break;
- }
- }
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java
deleted file mode 100644
index 470c85715..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.app.Activity;
-import android.app.ProgressDialog;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.CheckBox;
-import android.widget.EditText;
-import android.widget.Spinner;
-
-import com.beardedhen.androidbootstrap.BootstrapButton;
-import com.devspark.appmsg.AppMsg;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.FileHelper;
-import org.sufficientlysecure.keychain.helper.Preferences;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.service.PassphraseCacheService;
-import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment;
-import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment;
-import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
-import org.sufficientlysecure.keychain.util.Choice;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.io.File;
-
-public class EncryptFileFragment extends Fragment {
- public static final String ARG_FILENAME = "filename";
- public static final String ARG_ASCII_ARMOR = "ascii_armor";
-
- private static final int RESULT_CODE_FILE = 0x00007003;
-
- private EncryptActivityInterface mEncryptInterface;
-
- // view
- private CheckBox mAsciiArmor = null;
- private Spinner mFileCompression = null;
- private EditText mFilename = null;
- private CheckBox mDeleteAfter = null;
- private CheckBox mShareAfter = null;
- private BootstrapButton mBrowse = null;
- private BootstrapButton mEncryptFile;
-
- private FileDialogFragment mFileDialog;
-
- // model
- private String mInputFilename = null;
- private String mOutputFilename = null;
-
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- try {
- mEncryptInterface = (EncryptActivityInterface) activity;
- } catch (ClassCastException e) {
- throw new ClassCastException(activity.toString() + " must implement EncryptActivityInterface");
- }
- }
-
- /**
- * Inflate the layout for this fragment
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.encrypt_file_fragment, container, false);
-
- mEncryptFile = (BootstrapButton) view.findViewById(R.id.action_encrypt_file);
- mEncryptFile.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- encryptClicked();
- }
- });
-
- mFilename = (EditText) view.findViewById(R.id.filename);
- mBrowse = (BootstrapButton) view.findViewById(R.id.btn_browse);
- mBrowse.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- FileHelper.openFile(EncryptFileFragment.this, mFilename.getText().toString(), "*/*",
- Id.request.filename);
- }
- });
-
- mFileCompression = (Spinner) view.findViewById(R.id.fileCompression);
- Choice[] choices = new Choice[] {
- new Choice(Id.choice.compression.none, getString(R.string.choice_none) + " ("
- + getString(R.string.compression_fast) + ")"),
- new Choice(Id.choice.compression.zip, "ZIP ("
- + getString(R.string.compression_fast) + ")"),
- new Choice(Id.choice.compression.zlib, "ZLIB ("
- + getString(R.string.compression_fast) + ")"),
- new Choice(Id.choice.compression.bzip2, "BZIP2 ("
- + getString(R.string.compression_very_slow) + ")"),
- };
- ArrayAdapter<Choice> adapter = new ArrayAdapter<Choice>(getActivity(),
- android.R.layout.simple_spinner_item, choices);
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- mFileCompression.setAdapter(adapter);
-
- int defaultFileCompression = Preferences.getPreferences(getActivity()).getDefaultFileCompression();
- for (int i = 0; i < choices.length; ++i) {
- if (choices[i].getId() == defaultFileCompression) {
- mFileCompression.setSelection(i);
- break;
- }
- }
-
- mDeleteAfter = (CheckBox) view.findViewById(R.id.deleteAfterEncryption);
- mShareAfter = (CheckBox) view.findViewById(R.id.shareAfterEncryption);
-
- mAsciiArmor = (CheckBox) view.findViewById(R.id.asciiArmor);
- mAsciiArmor.setChecked(Preferences.getPreferences(getActivity()).getDefaultAsciiArmor());
-
- return view;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- String filename = getArguments().getString(ARG_FILENAME);
- if (filename != null) {
- mFilename.setText(filename);
- }
- boolean asciiArmor = getArguments().getBoolean(ARG_ASCII_ARMOR);
- if (asciiArmor) {
- mAsciiArmor.setChecked(asciiArmor);
- }
- }
-
- /**
- * Guess output filename based on input path
- *
- * @param path
- * @return Suggestion for output filename
- */
- private String guessOutputFilename(String path) {
- // output in the same directory but with additional ending
- File file = new File(path);
- String ending = (mAsciiArmor.isChecked() ? ".asc" : ".gpg");
- String outputFilename = file.getParent() + File.separator + file.getName() + ending;
-
- return outputFilename;
- }
-
- private void showOutputFileDialog() {
- // Message is received after file is selected
- Handler returnHandler = new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.what == FileDialogFragment.MESSAGE_OKAY) {
- Bundle data = message.getData();
- mOutputFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME);
- encryptStart();
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(returnHandler);
-
- mFileDialog = FileDialogFragment.newInstance(messenger,
- getString(R.string.title_encrypt_to_file),
- getString(R.string.specify_file_to_encrypt_to), mOutputFilename, null);
-
- mFileDialog.show(getActivity().getSupportFragmentManager(), "fileDialog");
- }
-
- private void encryptClicked() {
- String currentFilename = mFilename.getText().toString();
- if (mInputFilename == null || !mInputFilename.equals(currentFilename)) {
- mInputFilename = mFilename.getText().toString();
- }
-
- mOutputFilename = guessOutputFilename(mInputFilename);
-
- if (mInputFilename.equals("")) {
- AppMsg.makeText(getActivity(), R.string.no_file_selected, AppMsg.STYLE_ALERT).show();
- return;
- }
-
- if (!mInputFilename.startsWith("content")) {
- File file = new File(mInputFilename);
- if (!file.exists() || !file.isFile()) {
- AppMsg.makeText(
- getActivity(),
- getString(R.string.error_message,
- getString(R.string.error_file_not_found)), AppMsg.STYLE_ALERT)
- .show();
- return;
- }
- }
-
- if (mEncryptInterface.isModeSymmetric()) {
- // symmetric encryption
-
- boolean gotPassphrase = (mEncryptInterface.getPassphrase() != null
- && mEncryptInterface.getPassphrase().length() != 0);
- if (!gotPassphrase) {
- AppMsg.makeText(getActivity(), R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT)
- .show();
- return;
- }
-
- if (!mEncryptInterface.getPassphrase().equals(mEncryptInterface.getPassphraseAgain())) {
- AppMsg.makeText(getActivity(), R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show();
- return;
- }
- } else {
- // asymmetric encryption
-
- boolean gotEncryptionKeys = (mEncryptInterface.getEncryptionKeys() != null
- && mEncryptInterface.getEncryptionKeys().length > 0);
-
- if (!gotEncryptionKeys) {
- AppMsg.makeText(getActivity(), R.string.select_encryption_key, AppMsg.STYLE_ALERT).show();
- return;
- }
-
- if (!gotEncryptionKeys && mEncryptInterface.getSignatureKey() == 0) {
- AppMsg.makeText(getActivity(), R.string.select_encryption_or_signature_key,
- AppMsg.STYLE_ALERT).show();
- return;
- }
-
- if (mEncryptInterface.getSignatureKey() != 0 &&
- PassphraseCacheService.getCachedPassphrase(getActivity(),
- mEncryptInterface.getSignatureKey()) == null) {
- PassphraseDialogFragment.show(getActivity(), mEncryptInterface.getSignatureKey(),
- new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
- showOutputFileDialog();
- }
- }
- });
-
- return;
- }
- }
-
- showOutputFileDialog();
- }
-
- private void encryptStart() {
- // Send all information needed to service to edit key in other thread
- Intent intent = new Intent(getActivity(), KeychainIntentService.class);
-
- intent.setAction(KeychainIntentService.ACTION_ENCRYPT_SIGN);
-
- // fill values for this action
- Bundle data = new Bundle();
-
- data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_URI);
-
- if (mEncryptInterface.isModeSymmetric()) {
- Log.d(Constants.TAG, "Symmetric encryption enabled!");
- String passphrase = mEncryptInterface.getPassphrase();
- if (passphrase.length() == 0) {
- passphrase = null;
- }
- data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase);
- } else {
- data.putLong(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_ID,
- mEncryptInterface.getSignatureKey());
- data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS,
- mEncryptInterface.getEncryptionKeys());
- }
-
- Log.d(Constants.TAG, "mInputFilename=" + mInputFilename + ", mOutputFilename="
- + mOutputFilename);
-
- data.putString(KeychainIntentService.ENCRYPT_INPUT_FILE, mInputFilename);
- data.putString(KeychainIntentService.ENCRYPT_OUTPUT_FILE, mOutputFilename);
-
- boolean useAsciiArmor = mAsciiArmor.isChecked();
- data.putBoolean(KeychainIntentService.ENCRYPT_USE_ASCII_ARMOR, useAsciiArmor);
-
- int compressionId = ((Choice) mFileCompression.getSelectedItem()).getId();
- data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID, compressionId);
-// data.putBoolean(KeychainIntentService.ENCRYPT_GENERATE_SIGNATURE, mGenerateSignature);
-
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
-
- // Message is received after encrypting is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(),
- getString(R.string.progress_encrypting), ProgressDialog.STYLE_HORIZONTAL) {
- public void handleMessage(Message message) {
- // handle messages by standard KeychainIntentServiceHandler first
- super.handleMessage(message);
-
- if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- AppMsg.makeText(getActivity(), R.string.encryption_successful,
- AppMsg.STYLE_INFO).show();
-
- if (mDeleteAfter.isChecked()) {
- // Create and show dialog to delete original file
- DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment
- .newInstance(mInputFilename);
- deleteFileDialog.show(getActivity().getSupportFragmentManager(), "deleteDialog");
- }
-
- if (mShareAfter.isChecked()) {
- // Share encrypted file
- Intent sendFileIntent = new Intent(Intent.ACTION_SEND);
- sendFileIntent.setType("*/*");
- sendFileIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(mOutputFilename));
- startActivity(Intent.createChooser(sendFileIntent,
- getString(R.string.title_send_file)));
- }
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
-
- // show progress dialog
- saveHandler.showProgressDialog(getActivity());
-
- // start service with intent
- getActivity().startService(intent);
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case RESULT_CODE_FILE: {
- if (resultCode == Activity.RESULT_OK && data != null) {
- try {
- String path = FileHelper.getPath(getActivity(), data.getData());
- Log.d(Constants.TAG, "path=" + path);
-
- mFilename.setText(path);
- } catch (NullPointerException e) {
- Log.e(Constants.TAG, "Nullpointer while retrieving path!");
- }
- }
- return;
- }
-
- default: {
- super.onActivityResult(requestCode, resultCode, data);
-
- break;
- }
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java
deleted file mode 100644
index ba11074fc..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.app.Activity;
-import android.app.ProgressDialog;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.EditText;
-
-import com.beardedhen.androidbootstrap.BootstrapButton;
-import com.devspark.appmsg.AppMsg;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
-import org.sufficientlysecure.keychain.helper.Preferences;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.service.PassphraseCacheService;
-import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
-import org.sufficientlysecure.keychain.util.Log;
-
-public class EncryptMessageFragment extends Fragment {
- public static final String ARG_TEXT = "text";
-
- private EditText mMessage = null;
- private BootstrapButton mEncryptShare;
- private BootstrapButton mEncryptClipboard;
-
- private EncryptActivityInterface mEncryptInterface;
-
-
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- try {
- mEncryptInterface = (EncryptActivityInterface) activity;
- } catch (ClassCastException e) {
- throw new ClassCastException(activity.toString() + " must implement EncryptActivityInterface");
- }
- }
-
- /**
- * Inflate the layout for this fragment
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.encrypt_message_fragment, container, false);
-
- mMessage = (EditText) view.findViewById(R.id.message);
- mEncryptClipboard = (BootstrapButton) view.findViewById(R.id.action_encrypt_clipboard);
- mEncryptShare = (BootstrapButton) view.findViewById(R.id.action_encrypt_share);
- mEncryptClipboard.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- encryptClicked(true);
- }
- });
- mEncryptShare.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- encryptClicked(false);
- }
- });
-
- return view;
- }
-
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- String text = getArguments().getString(ARG_TEXT);
- if (text != null) {
- mMessage.setText(text);
- }
- }
-
- /**
- * Fixes bad message characters for gmail
- *
- * @param message
- * @return
- */
- private String fixBadCharactersForGmail(String message) {
- // fix the message a bit, trailing spaces and newlines break stuff,
- // because GMail sends as HTML and such things fuck up the
- // signature,
- // TODO: things like "<" and ">" also fuck up the signature
- message = message.replaceAll(" +\n", "\n");
- message = message.replaceAll("\n\n+", "\n\n");
- message = message.replaceFirst("^\n+", "");
- // make sure there'll be exactly one newline at the end
- message = message.replaceFirst("\n*$", "\n");
-
- return message;
- }
-
- private void encryptClicked(final boolean toClipboard) {
- if (mEncryptInterface.isModeSymmetric()) {
- // symmetric encryption
-
- boolean gotPassphrase = (mEncryptInterface.getPassphrase() != null
- && mEncryptInterface.getPassphrase().length() != 0);
- if (!gotPassphrase) {
- AppMsg.makeText(getActivity(), R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT)
- .show();
- return;
- }
-
- if (!mEncryptInterface.getPassphrase().equals(mEncryptInterface.getPassphraseAgain())) {
- AppMsg.makeText(getActivity(), R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show();
- return;
- }
-
- } else {
- // asymmetric encryption
-
- boolean gotEncryptionKeys = (mEncryptInterface.getEncryptionKeys() != null
- && mEncryptInterface.getEncryptionKeys().length > 0);
-
- if (!gotEncryptionKeys && mEncryptInterface.getSignatureKey() == 0) {
- AppMsg.makeText(getActivity(), R.string.select_encryption_or_signature_key,
- AppMsg.STYLE_ALERT).show();
- return;
- }
-
- if (mEncryptInterface.getSignatureKey() != 0 &&
- PassphraseCacheService.getCachedPassphrase(getActivity(),
- mEncryptInterface.getSignatureKey()) == null) {
- PassphraseDialogFragment.show(getActivity(), mEncryptInterface.getSignatureKey(),
- new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
- encryptStart(toClipboard);
- }
- }
- });
-
- return;
- }
- }
-
- encryptStart(toClipboard);
- }
-
- private void encryptStart(final boolean toClipboard) {
- // Send all information needed to service to edit key in other thread
- Intent intent = new Intent(getActivity(), KeychainIntentService.class);
-
- intent.setAction(KeychainIntentService.ACTION_ENCRYPT_SIGN);
-
- // fill values for this action
- Bundle data = new Bundle();
-
- data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES);
-
- String message = mMessage.getText().toString();
-
- if (mEncryptInterface.isModeSymmetric()) {
- Log.d(Constants.TAG, "Symmetric encryption enabled!");
- String passphrase = mEncryptInterface.getPassphrase();
- if (passphrase.length() == 0) {
- passphrase = null;
- }
- data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase);
- } else {
- data.putLong(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_ID,
- mEncryptInterface.getSignatureKey());
- data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS,
- mEncryptInterface.getEncryptionKeys());
-
- boolean signOnly = (mEncryptInterface.getEncryptionKeys() == null
- || mEncryptInterface.getEncryptionKeys().length == 0);
- if (signOnly) {
- message = fixBadCharactersForGmail(message);
- }
- }
-
- data.putByteArray(KeychainIntentService.ENCRYPT_MESSAGE_BYTES, message.getBytes());
-
- data.putBoolean(KeychainIntentService.ENCRYPT_USE_ASCII_ARMOR, true);
-
- int compressionId = Preferences.getPreferences(getActivity()).getDefaultMessageCompression();
- data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID, compressionId);
-// data.putBoolean(KeychainIntentService.ENCRYPT_GENERATE_SIGNATURE, mGenerateSignature);
-
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
-
- // Message is received after encrypting is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(),
- getString(R.string.progress_encrypting), ProgressDialog.STYLE_HORIZONTAL) {
- public void handleMessage(Message message) {
- // handle messages by standard KeychainIntentServiceHandler first
- super.handleMessage(message);
-
- if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- // get returned data bundle
- Bundle data = message.getData();
-
- String output = new String(data.getByteArray(KeychainIntentService.RESULT_BYTES));
- Log.d(Constants.TAG, "output: " + output);
-
- if (toClipboard) {
- ClipboardReflection.copyToClipboard(getActivity(), output);
- AppMsg.makeText(getActivity(),
- R.string.encryption_to_clipboard_successful, AppMsg.STYLE_INFO)
- .show();
- } else {
- Intent sendIntent = new Intent(Intent.ACTION_SEND);
-
- // Type is set to text/plain so that encrypted messages can
- // be sent with Whatsapp, Hangouts, SMS etc...
- sendIntent.setType("text/plain");
-
- sendIntent.putExtra(Intent.EXTRA_TEXT, output);
- startActivity(Intent.createChooser(sendIntent,
- getString(R.string.title_send_email)));
- }
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
-
- // show progress dialog
- saveHandler.showProgressDialog(getActivity());
-
- // start service with intent
- getActivity().startService(intent);
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java
deleted file mode 100644
index 8efa07953..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.EditText;
-
-import org.sufficientlysecure.keychain.R;
-
-public class EncryptSymmetricFragment extends Fragment {
-
- OnSymmetricKeySelection mPassphraseUpdateListener;
-
- private EditText mPassphrase;
- private EditText mPassphraseAgain;
-
- // Container Activity must implement this interface
- public interface OnSymmetricKeySelection {
- public void onPassphraseUpdate(String passphrase);
-
- public void onPassphraseAgainUpdate(String passphrase);
- }
-
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- try {
- mPassphraseUpdateListener = (OnSymmetricKeySelection) activity;
- } catch (ClassCastException e) {
- throw new ClassCastException(activity.toString() + " must implement OnSymmetricKeySelection");
- }
- }
-
- /**
- * Inflate the layout for this fragment
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.encrypt_symmetric_fragment, container, false);
-
- mPassphrase = (EditText) view.findViewById(R.id.passphrase);
- mPassphraseAgain = (EditText) view.findViewById(R.id.passphraseAgain);
- mPassphrase.addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- // update passphrase in EncryptActivity
- mPassphraseUpdateListener.onPassphraseUpdate(s.toString());
- }
- });
- mPassphraseAgain.addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- // update passphrase in EncryptActivity
- mPassphraseUpdateListener.onPassphraseAgainUpdate(s.toString());
- }
- });
-
- return view;
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java
deleted file mode 100644
index a484b57de..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-import org.sufficientlysecure.htmltextview.HtmlTextView;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.util.Log;
-
-
-public class HelpAboutFragment extends Fragment {
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.help_about_fragment, container, false);
-
- TextView versionText = (TextView) view.findViewById(R.id.help_about_version);
- versionText.setText(getString(R.string.help_about_version) + " " + getVersion());
-
- HtmlTextView aboutTextView = (HtmlTextView) view.findViewById(R.id.help_about_text);
-
- // load html from raw resource (Parsing handled by HtmlTextView library)
- aboutTextView.setHtmlFromRawResource(getActivity(), R.raw.help_about);
-
- // no flickering when clicking textview for Android < 4
- aboutTextView.setTextColor(getResources().getColor(android.R.color.black));
-
- return view;
- }
-
- /**
- * Get the current package version.
- *
- * @return The current version.
- */
- private String getVersion() {
- String result = "";
- try {
- PackageManager manager = getActivity().getPackageManager();
- PackageInfo info = manager.getPackageInfo(getActivity().getPackageName(), 0);
-
- result = String.format("%s (%s)", info.versionName, info.versionCode);
- } catch (NameNotFoundException e) {
- Log.w(Constants.TAG, "Unable to get application version: " + e.getMessage());
- result = "Unable to get application version.";
- }
-
- return result;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
deleted file mode 100644
index 32f37a0a5..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.v4.view.ViewPager;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.ui.adapter.TabsAdapter;
-
-public class HelpActivity extends ActionBarActivity {
- public static final String EXTRA_SELECTED_TAB = "selected_tab";
-
- ViewPager mViewPager;
- TabsAdapter mTabsAdapter;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.help_activity);
-
- mViewPager = (ViewPager) findViewById(R.id.pager);
-
- final ActionBar actionBar = getSupportActionBar();
- actionBar.setDisplayShowTitleEnabled(true);
- actionBar.setDisplayHomeAsUpEnabled(false);
- actionBar.setHomeButtonEnabled(false);
- actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
-
- mTabsAdapter = new TabsAdapter(this, mViewPager);
-
- int selectedTab = 0;
- Intent intent = getIntent();
- if (intent.getExtras() != null && intent.getExtras().containsKey(EXTRA_SELECTED_TAB)) {
- selectedTab = intent.getExtras().getInt(EXTRA_SELECTED_TAB);
- }
-
- Bundle startBundle = new Bundle();
- startBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_start);
- mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_start)),
- HelpHtmlFragment.class, startBundle, (selectedTab == 0));
-
- Bundle faqBundle = new Bundle();
- faqBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_faq);
- mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_faq)),
- HelpHtmlFragment.class, faqBundle, (selectedTab == 1));
-
- Bundle nfcBundle = new Bundle();
- nfcBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_nfc_beam);
- mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_nfc_beam)),
- HelpHtmlFragment.class, nfcBundle, (selectedTab == 2));
-
- Bundle changelogBundle = new Bundle();
- changelogBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_changelog);
- mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_changelog)),
- HelpHtmlFragment.class, changelogBundle, (selectedTab == 3));
-
- mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_about)),
- HelpAboutFragment.class, null, (selectedTab == 4));
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java
deleted file mode 100644
index 6b3c51b08..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ScrollView;
-import org.sufficientlysecure.htmltextview.HtmlTextView;
-
-public class HelpHtmlFragment extends Fragment {
- private Activity mActivity;
-
- private int mHtmlFile;
-
- public static final String ARG_HTML_FILE = "htmlFile";
-
- /**
- * Create a new instance of HelpHtmlFragment, providing "htmlFile" as an argument.
- */
- static HelpHtmlFragment newInstance(int htmlFile) {
- HelpHtmlFragment f = new HelpHtmlFragment();
-
- // Supply html raw file input as an argument.
- Bundle args = new Bundle();
- args.putInt(ARG_HTML_FILE, htmlFile);
- f.setArguments(args);
-
- return f;
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- mActivity = getActivity();
-
- mHtmlFile = getArguments().getInt(ARG_HTML_FILE);
-
- ScrollView scroller = new ScrollView(mActivity);
- HtmlTextView text = new HtmlTextView(mActivity);
-
- // padding
- int padding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16, mActivity
- .getResources().getDisplayMetrics());
- text.setPadding(padding, padding, padding, 0);
-
- scroller.addView(text);
-
- // load html from raw resource (Parsing handled by HtmlTextView library)
- text.setHtmlFromRawResource(getActivity(), mHtmlFile);
-
- // no flickering when clicking textview for Android < 4
- text.setTextColor(getResources().getColor(android.R.color.black));
-
- return scroller;
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
deleted file mode 100644
index 6ea79473a..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2011 Senecaso
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.annotation.SuppressLint;
-import android.app.Activity;
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.nfc.NdefMessage;
-import android.nfc.NfcAdapter;
-import android.os.Bundle;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.Parcelable;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentTransaction;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.ArrayAdapter;
-
-import com.beardedhen.androidbootstrap.BootstrapButton;
-import com.devspark.appmsg.AppMsg;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.ActionBarHelper;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
-import org.sufficientlysecure.keychain.ui.dialog.BadImportKeyDialogFragment;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.util.ArrayList;
-import java.util.Locale;
-
-public class ImportKeysActivity extends ActionBarActivity implements ActionBar.OnNavigationListener {
- public static final String ACTION_IMPORT_KEY = Constants.INTENT_PREFIX + "IMPORT_KEY";
- public static final String ACTION_IMPORT_KEY_FROM_QR_CODE = Constants.INTENT_PREFIX
- + "IMPORT_KEY_FROM_QR_CODE";
- public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER = Constants.INTENT_PREFIX
- + "IMPORT_KEY_FROM_KEYSERVER";
- public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN = Constants.INTENT_PREFIX
- + "IMPORT_KEY_FROM_KEY_SERVER_AND_RETURN";
-
- // Actions for internal use only:
- public static final String ACTION_IMPORT_KEY_FROM_FILE = Constants.INTENT_PREFIX
- + "IMPORT_KEY_FROM_FILE";
- public static final String ACTION_IMPORT_KEY_FROM_NFC = Constants.INTENT_PREFIX
- + "IMPORT_KEY_FROM_NFC";
-
- // only used by ACTION_IMPORT_KEY
- public static final String EXTRA_KEY_BYTES = "key_bytes";
-
- // only used by ACTION_IMPORT_KEY_FROM_KEYSERVER
- public static final String EXTRA_QUERY = "query";
- public static final String EXTRA_KEY_ID = "key_id";
- public static final String EXTRA_FINGERPRINT = "fingerprint";
-
- // only used by ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN when used from OpenPgpService
- public static final String EXTRA_PENDING_INTENT_DATA = "data";
- private Intent mPendingIntentData;
-
- // view
- private ImportKeysListFragment mListFragment;
- private String[] mNavigationStrings;
- private Fragment mCurrentFragment;
- private BootstrapButton mImportButton;
-
- private static final Class[] NAVIGATION_CLASSES = new Class[]{
- ImportKeysServerFragment.class,
- ImportKeysFileFragment.class,
- ImportKeysQrCodeFragment.class,
- ImportKeysClipboardFragment.class,
- ImportKeysNFCFragment.class
- };
-
- private int mCurrentNavPosition = -1;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.import_keys_activity);
-
- mImportButton = (BootstrapButton) findViewById(R.id.import_import);
- mImportButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- importKeys();
- }
- });
-
- mNavigationStrings = getResources().getStringArray(R.array.import_action_list);
-
- if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN.equals(getIntent().getAction())) {
- setTitle(R.string.nav_import);
- } else {
- ActionBarHelper.setBackButton(this);
- getSupportActionBar().setDisplayShowTitleEnabled(false);
-
- // set drop down navigation
- Context context = getSupportActionBar().getThemedContext();
- ArrayAdapter<CharSequence> navigationAdapter = ArrayAdapter.createFromResource(context,
- R.array.import_action_list, android.R.layout.simple_spinner_dropdown_item);
- getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
- getSupportActionBar().setListNavigationCallbacks(navigationAdapter, this);
- }
-
- handleActions(savedInstanceState, getIntent());
- }
-
- protected void handleActions(Bundle savedInstanceState, Intent intent) {
- String action = intent.getAction();
- Bundle extras = intent.getExtras();
- Uri dataUri = intent.getData();
- String scheme = intent.getScheme();
-
- if (extras == null) {
- extras = new Bundle();
- }
-
- if (Intent.ACTION_VIEW.equals(action)) {
- // Android's Action when opening file associated to Keychain (see AndroidManifest.xml)
- // override action to delegate it to Keychain's ACTION_IMPORT_KEY
- action = ACTION_IMPORT_KEY;
- }
-
- if (scheme != null && scheme.toLowerCase(Locale.ENGLISH).equals(Constants.FINGERPRINT_SCHEME)) {
- /* Scanning a fingerprint directly with Barcode Scanner */
- loadFromFingerprintUri(savedInstanceState, dataUri);
- } else if (ACTION_IMPORT_KEY.equals(action)) {
- /* Keychain's own Actions */
-
- // display file fragment
- loadNavFragment(1, null);
-
- if (dataUri != null) {
- // action: directly load data
- startListFragment(savedInstanceState, null, dataUri, null);
- } else if (extras.containsKey(EXTRA_KEY_BYTES)) {
- byte[] importData = intent.getByteArrayExtra(EXTRA_KEY_BYTES);
-
- // action: directly load data
- startListFragment(savedInstanceState, importData, null, null);
- }
- } else if (ACTION_IMPORT_KEY_FROM_KEYSERVER.equals(action)
- || ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN.equals(action)) {
-
- // only used for OpenPgpService
- if (extras.containsKey(EXTRA_PENDING_INTENT_DATA)) {
- mPendingIntentData = extras.getParcelable(EXTRA_PENDING_INTENT_DATA);
- }
- if (extras.containsKey(EXTRA_QUERY) || extras.containsKey(EXTRA_KEY_ID)) {
- /* simple search based on query or key id */
-
- String query = null;
- if (extras.containsKey(EXTRA_QUERY)) {
- query = extras.getString(EXTRA_QUERY);
- } else if (extras.containsKey(EXTRA_KEY_ID)) {
- long keyId = intent.getLongExtra(EXTRA_KEY_ID, 0);
- if (keyId != 0) {
- query = PgpKeyHelper.convertKeyIdToHex(keyId);
- }
- }
-
- if (query != null && query.length() > 0) {
- // display keyserver fragment with query
- Bundle args = new Bundle();
- args.putString(ImportKeysServerFragment.ARG_QUERY, query);
- loadNavFragment(0, args);
-
- // action: search immediately
- startListFragment(savedInstanceState, null, null, query);
- } else {
- Log.e(Constants.TAG, "Query is empty!");
- return;
- }
- } else if (extras.containsKey(EXTRA_FINGERPRINT)) {
- /*
- * search based on fingerprint, here we can enforce a check in the end
- * if the right key has been downloaded
- */
-
- String fingerprint = intent.getStringExtra(EXTRA_FINGERPRINT);
- loadFromFingerprint(savedInstanceState, fingerprint);
- } else {
- Log.e(Constants.TAG,
- "IMPORT_KEY_FROM_KEYSERVER action needs to contain the 'query', 'key_id', or " +
- "'fingerprint' extra!");
- return;
- }
- } else if (ACTION_IMPORT_KEY_FROM_FILE.equals(action)) {
-
- // NOTE: this only displays the appropriate fragment, no actions are taken
- loadNavFragment(1, null);
-
- // no immediate actions!
- startListFragment(savedInstanceState, null, null, null);
- } else if (ACTION_IMPORT_KEY_FROM_QR_CODE.equals(action)) {
- // also exposed in AndroidManifest
-
- // NOTE: this only displays the appropriate fragment, no actions are taken
- loadNavFragment(2, null);
-
- // no immediate actions!
- startListFragment(savedInstanceState, null, null, null);
- } else if (ACTION_IMPORT_KEY_FROM_NFC.equals(action)) {
-
- // NOTE: this only displays the appropriate fragment, no actions are taken
- loadNavFragment(3, null);
-
- // no immediate actions!
- startListFragment(savedInstanceState, null, null, null);
- } else {
- startListFragment(savedInstanceState, null, null, null);
- }
- }
-
- private void startListFragment(Bundle savedInstanceState, byte[] bytes, Uri dataUri, String serverQuery) {
- // However, if we're being restored from a previous state,
- // then we don't need to do anything and should return or else
- // we could end up with overlapping fragments.
- if (savedInstanceState != null) {
- return;
- }
-
- // Create an instance of the fragment
- mListFragment = ImportKeysListFragment.newInstance(bytes, dataUri, serverQuery);
-
- // Add the fragment to the 'fragment_container' FrameLayout
- // NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
- getSupportFragmentManager().beginTransaction()
- .replace(R.id.import_keys_list_container, mListFragment)
- .commitAllowingStateLoss();
- // do it immediately!
- getSupportFragmentManager().executePendingTransactions();
- }
-
- /**
- * "Basically, when using a list navigation, onNavigationItemSelected() is automatically
- * called when your activity is created/re-created, whether you like it or not. To prevent
- * your Fragment's onCreateView() from being called twice, this initial automatic call to
- * onNavigationItemSelected() should check whether the Fragment is already in existence
- * inside your Activity."
- * <p/>
- * from http://stackoverflow.com/a/14295474
- * <p/>
- * In our case, if we start ImportKeysActivity with parameters to directly search using a fingerprint,
- * the fragment would be loaded twice resulting in the query being empty after the second load.
- * <p/>
- * Our solution:
- * To prevent that a fragment will be loaded again even if it was already loaded loadNavFragment
- * checks against mCurrentNavPosition.
- *
- * @param itemPosition
- * @param itemId
- * @return
- */
- @Override
- public boolean onNavigationItemSelected(int itemPosition, long itemId) {
- Log.d(Constants.TAG, "onNavigationItemSelected");
-
- loadNavFragment(itemPosition, null);
-
- return true;
- }
-
- private void loadNavFragment(int itemPosition, Bundle args) {
- if (mCurrentNavPosition != itemPosition) {
- if (ActionBar.NAVIGATION_MODE_LIST == getSupportActionBar().getNavigationMode()) {
- getSupportActionBar().setSelectedNavigationItem(itemPosition);
- }
- loadFragment(NAVIGATION_CLASSES[itemPosition], args, mNavigationStrings[itemPosition]);
- mCurrentNavPosition = itemPosition;
- }
- }
-
- private void loadFragment(Class<?> clss, Bundle args, String tag) {
- mCurrentFragment = Fragment.instantiate(this, clss.getName(), args);
-
- FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
- // Replace whatever is in the fragment container with this fragment
- // and give the fragment a tag name equal to the string at the position selected
- ft.replace(R.id.import_navigation_fragment, mCurrentFragment, tag);
- // Apply changes
- ft.commit();
- }
-
- public void loadFromFingerprintUri(Bundle savedInstanceState, Uri dataUri) {
- String fingerprint = dataUri.toString().split(":")[1].toLowerCase(Locale.ENGLISH);
-
- Log.d(Constants.TAG, "fingerprint: " + fingerprint);
-
- loadFromFingerprint(savedInstanceState, fingerprint);
- }
-
- public void loadFromFingerprint(Bundle savedInstanceState, String fingerprint) {
- if (fingerprint == null || fingerprint.length() < 40) {
- AppMsg.makeText(this, R.string.import_qr_code_too_short_fingerprint,
- AppMsg.STYLE_ALERT).show();
- return;
- }
-
- String query = "0x" + fingerprint;
-
- // display keyserver fragment with query
- Bundle args = new Bundle();
- args.putString(ImportKeysServerFragment.ARG_QUERY, query);
- args.putBoolean(ImportKeysServerFragment.ARG_DISABLE_QUERY_EDIT, true);
- loadNavFragment(0, args);
-
- // action: search directly
- startListFragment(savedInstanceState, null, null, query);
- }
-
- public void loadCallback(byte[] importData, Uri dataUri, String serverQuery, String keyServer) {
- mListFragment.loadNew(importData, dataUri, serverQuery, keyServer);
- }
-
- /**
- * Import keys with mImportData
- */
- public void importKeys() {
- // Message is received after importing is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
- this,
- getString(R.string.progress_importing),
- ProgressDialog.STYLE_HORIZONTAL) {
- public void handleMessage(Message message) {
- // handle messages by standard KeychainIntentServiceHandler first
- super.handleMessage(message);
-
- if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- // get returned data bundle
- Bundle returnData = message.getData();
-
- int added = returnData.getInt(KeychainIntentService.RESULT_IMPORT_ADDED);
- int updated = returnData
- .getInt(KeychainIntentService.RESULT_IMPORT_UPDATED);
- int bad = returnData.getInt(KeychainIntentService.RESULT_IMPORT_BAD);
- String toastMessage;
- if (added > 0 && updated > 0) {
- String addedStr = getResources().getQuantityString(
- R.plurals.keys_added_and_updated_1, added, added);
- String updatedStr = getResources().getQuantityString(
- R.plurals.keys_added_and_updated_2, updated, updated);
- toastMessage = addedStr + updatedStr;
- } else if (added > 0) {
- toastMessage = getResources().getQuantityString(R.plurals.keys_added,
- added, added);
- } else if (updated > 0) {
- toastMessage = getResources().getQuantityString(R.plurals.keys_updated,
- updated, updated);
- } else {
- toastMessage = getString(R.string.no_keys_added_or_updated);
- }
- AppMsg.makeText(ImportKeysActivity.this, toastMessage, AppMsg.STYLE_INFO)
- .show();
- if (bad > 0) {
- BadImportKeyDialogFragment badImportKeyDialogFragment =
- BadImportKeyDialogFragment.newInstance(bad);
- badImportKeyDialogFragment.show(getSupportFragmentManager(), "badKeyDialog");
- }
-
- if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN.equals(getIntent().getAction())) {
- ImportKeysActivity.this.setResult(Activity.RESULT_OK, mPendingIntentData);
- finish();
- }
- }
- }
- };
-
- if (mListFragment.getKeyBytes() != null || mListFragment.getDataUri() != null) {
- Log.d(Constants.TAG, "importKeys started");
-
- // Send all information needed to service to import key in other thread
- Intent intent = new Intent(this, KeychainIntentService.class);
-
- intent.setAction(KeychainIntentService.ACTION_IMPORT_KEYRING);
-
- // fill values for this action
- Bundle data = new Bundle();
-
- // get selected key entries
- ArrayList<ImportKeysListEntry> selectedEntries = mListFragment.getSelectedData();
- data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, selectedEntries);
-
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
-
- // show progress dialog
- saveHandler.showProgressDialog(this);
-
- // start service with intent
- startService(intent);
- } else if (mListFragment.getServerQuery() != null) {
- // Send all information needed to service to query keys in other thread
- Intent intent = new Intent(this, KeychainIntentService.class);
-
- intent.setAction(KeychainIntentService.ACTION_DOWNLOAD_AND_IMPORT_KEYS);
-
- // fill values for this action
- Bundle data = new Bundle();
-
- data.putString(KeychainIntentService.DOWNLOAD_KEY_SERVER, mListFragment.getKeyServer());
-
- // get selected key entries
- ArrayList<ImportKeysListEntry> selectedEntries = mListFragment.getSelectedData();
- data.putParcelableArrayList(KeychainIntentService.DOWNLOAD_KEY_LIST, selectedEntries);
-
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
-
- // show progress dialog
- saveHandler.showProgressDialog(this);
-
- // start service with intent
- startService(intent);
- } else {
- AppMsg.makeText(this, R.string.error_nothing_import, AppMsg.STYLE_ALERT).show();
- }
- }
-
- /**
- * NFC
- */
- @Override
- public void onResume() {
- super.onResume();
- // Check to see that the Activity started due to an Android Beam
- if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
- handleActionNdefDiscovered(getIntent());
- }
- }
-
- /**
- * NFC
- */
- @Override
- public void onNewIntent(Intent intent) {
- // onResume gets called after this to handle the intent
- setIntent(intent);
- }
-
- /**
- * NFC: Parses the NDEF Message from the intent and prints to the TextView
- */
- @SuppressLint("NewApi")
- void handleActionNdefDiscovered(Intent intent) {
- Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
- // only one message sent during the beam
- NdefMessage msg = (NdefMessage) rawMsgs[0];
- // record 0 contains the MIME type, record 1 is the AAR, if present
- byte[] receivedKeyringBytes = msg.getRecords()[0].getPayload();
-
- Intent importIntent = new Intent(this, ImportKeysActivity.class);
- importIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY);
- importIntent.putExtra(ImportKeysActivity.EXTRA_KEY_BYTES, receivedKeyringBytes);
-
- handleActions(null, importIntent);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java
deleted file mode 100644
index 28e2091a9..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import com.beardedhen.androidbootstrap.BootstrapButton;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
-
-import java.util.Locale;
-
-public class ImportKeysClipboardFragment extends Fragment {
-
- private ImportKeysActivity mImportActivity;
- private BootstrapButton mButton;
-
- /**
- * Creates new instance of this fragment
- */
- public static ImportKeysClipboardFragment newInstance() {
- ImportKeysClipboardFragment frag = new ImportKeysClipboardFragment();
-
- Bundle args = new Bundle();
- frag.setArguments(args);
-
- return frag;
- }
-
- /**
- * Inflate the layout for this fragment
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.import_keys_clipboard_fragment, container, false);
-
- mButton = (BootstrapButton) view.findViewById(R.id.import_clipboard_button);
- mButton.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- CharSequence clipboardText = ClipboardReflection.getClipboardText(getActivity());
- String sendText = "";
- if (clipboardText != null) {
- sendText = clipboardText.toString();
- if (sendText.toLowerCase(Locale.ENGLISH).startsWith(Constants.FINGERPRINT_SCHEME)) {
- mImportActivity.loadFromFingerprintUri(null, Uri.parse(sendText));
- return;
- }
- }
- mImportActivity.loadCallback(sendText.getBytes(), null, null, null);
- }
- });
-
- return view;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- mImportActivity = (ImportKeysActivity) getActivity();
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java
deleted file mode 100644
index 31d5f3fd0..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import com.beardedhen.androidbootstrap.BootstrapButton;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.FileHelper;
-
-public class ImportKeysFileFragment extends Fragment {
- private ImportKeysActivity mImportActivity;
- private BootstrapButton mBrowse;
-
- /**
- * Creates new instance of this fragment
- */
- public static ImportKeysFileFragment newInstance() {
- ImportKeysFileFragment frag = new ImportKeysFileFragment();
-
- Bundle args = new Bundle();
-
- frag.setArguments(args);
- return frag;
- }
-
- /**
- * Inflate the layout for this fragment
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.import_keys_file_fragment, container, false);
-
- mBrowse = (BootstrapButton) view.findViewById(R.id.import_keys_file_browse);
-
- mBrowse.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- // open .asc or .gpg files
- // setting it to text/plain prevents Cynaogenmod's file manager from selecting asc
- // or gpg types!
- FileHelper.openFile(ImportKeysFileFragment.this, Constants.Path.APP_DIR + "/",
- "*/*", Id.request.filename);
- }
- });
-
- return view;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- mImportActivity = (ImportKeysActivity) getActivity();
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode & 0xFFFF) {
- case Id.request.filename: {
- if (resultCode == Activity.RESULT_OK && data != null) {
-
- // load data
- mImportActivity.loadCallback(null, data.getData(), null, null);
- }
-
- break;
- }
-
- default:
- super.onActivityResult(requestCode, resultCode, data);
-
- break;
- }
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
deleted file mode 100644
index 077fa0cab..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.app.Activity;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.ListFragment;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.Loader;
-import android.view.View;
-import android.widget.ListView;
-import com.devspark.appmsg.AppMsg;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.Preferences;
-import org.sufficientlysecure.keychain.ui.adapter.AsyncTaskResultWrapper;
-import org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter;
-import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
-import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListLoader;
-import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListServerLoader;
-import org.sufficientlysecure.keychain.util.InputData;
-import org.sufficientlysecure.keychain.util.KeyServer;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.io.ByteArrayInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-public class ImportKeysListFragment extends ListFragment implements
- LoaderManager.LoaderCallbacks<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> {
- private static final String ARG_DATA_URI = "uri";
- private static final String ARG_BYTES = "bytes";
- private static final String ARG_SERVER_QUERY = "query";
-
- private Activity mActivity;
- private ImportKeysAdapter mAdapter;
-
- private byte[] mKeyBytes;
- private Uri mDataUri;
- private String mServerQuery;
- private String mKeyServer;
-
- private static final int LOADER_ID_BYTES = 0;
- private static final int LOADER_ID_SERVER_QUERY = 1;
-
- public byte[] getKeyBytes() {
- return mKeyBytes;
- }
-
- public Uri getDataUri() {
- return mDataUri;
- }
-
- public String getServerQuery() {
- return mServerQuery;
- }
-
- public String getKeyServer() {
- return mKeyServer;
- }
-
- public List<ImportKeysListEntry> getData() {
- return mAdapter.getData();
- }
-
- public ArrayList<ImportKeysListEntry> getSelectedData() {
- return mAdapter.getSelectedData();
- }
-
- /**
- * Creates new instance of this fragment
- */
- public static ImportKeysListFragment newInstance(byte[] bytes, Uri dataUri, String serverQuery) {
- ImportKeysListFragment frag = new ImportKeysListFragment();
-
- Bundle args = new Bundle();
- args.putByteArray(ARG_BYTES, bytes);
- args.putParcelable(ARG_DATA_URI, dataUri);
- args.putString(ARG_SERVER_QUERY, serverQuery);
-
- frag.setArguments(args);
-
- return frag;
- }
-
- /**
- * Define Adapter and Loader on create of Activity
- */
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- mActivity = getActivity();
-
- // Give some text to display if there is no data. In a real
- // application this would come from a resource.
- setEmptyText(mActivity.getString(R.string.error_nothing_import));
-
- // Create an empty adapter we will use to display the loaded data.
- mAdapter = new ImportKeysAdapter(mActivity);
- setListAdapter(mAdapter);
-
- mDataUri = getArguments().getParcelable(ARG_DATA_URI);
- mKeyBytes = getArguments().getByteArray(ARG_BYTES);
- mServerQuery = getArguments().getString(ARG_SERVER_QUERY);
-
- // TODO: this is used when scanning QR Code. Currently it simply uses keyserver nr 0
- mKeyServer = Preferences.getPreferences(getActivity())
- .getKeyServers()[0];
-
- if (mDataUri != null || mKeyBytes != null) {
- // Start out with a progress indicator.
- setListShown(false);
-
- // Prepare the loader. Either re-connect with an existing one,
- // or start a new one.
- // give arguments to onCreateLoader()
- getLoaderManager().initLoader(LOADER_ID_BYTES, null, this);
- }
-
- if (mServerQuery != null && mKeyServer != null) {
- // Start out with a progress indicator.
- setListShown(false);
-
- // Prepare the loader. Either re-connect with an existing one,
- // or start a new one.
- // give arguments to onCreateLoader()
- getLoaderManager().initLoader(LOADER_ID_SERVER_QUERY, null, this);
- }
- }
-
- @Override
- public void onListItemClick(ListView l, View v, int position, long id) {
- super.onListItemClick(l, v, position, id);
-
- // Select checkbox!
- // Update underlying data and notify adapter of change. The adapter will
- // update the view automatically.
- ImportKeysListEntry entry = mAdapter.getItem(position);
- entry.setSelected(!entry.isSelected());
- mAdapter.notifyDataSetChanged();
- }
-
- public void loadNew(byte[] keyBytes, Uri dataUri, String serverQuery, String keyServer) {
- mKeyBytes = keyBytes;
- mDataUri = dataUri;
- mServerQuery = serverQuery;
- mKeyServer = keyServer;
-
- if (mKeyBytes != null || mDataUri != null) {
- // Start out with a progress indicator.
- setListShown(false);
-
- getLoaderManager().restartLoader(LOADER_ID_BYTES, null, this);
- }
-
- if (mServerQuery != null && mKeyServer != null) {
- // Start out with a progress indicator.
- setListShown(false);
-
- getLoaderManager().restartLoader(LOADER_ID_SERVER_QUERY, null, this);
- }
- }
-
- @Override
- public Loader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>>
- onCreateLoader(int id, Bundle args) {
- switch (id) {
- case LOADER_ID_BYTES: {
- InputData inputData = getInputData(mKeyBytes, mDataUri);
- return new ImportKeysListLoader(mActivity, inputData);
- }
- case LOADER_ID_SERVER_QUERY: {
- return new ImportKeysListServerLoader(getActivity(), mServerQuery, mKeyServer);
- }
-
- default:
- return null;
- }
- }
-
- @Override
- public void onLoadFinished(Loader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> loader,
- AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> data) {
- // Swap the new cursor in. (The framework will take care of closing the
- // old cursor once we return.)
-
- Log.d(Constants.TAG, "data: " + data.getResult());
-
- // swap in the real data!
- mAdapter.setData(data.getResult());
- mAdapter.notifyDataSetChanged();
-
- setListAdapter(mAdapter);
-
- // The list should now be shown.
- if (isResumed()) {
- setListShown(true);
- } else {
- setListShownNoAnimation(true);
- }
-
- Exception error = data.getError();
-
- switch (loader.getId()) {
- case LOADER_ID_BYTES:
-
- if (error == null) {
- // No error
- } else if (error instanceof ImportKeysListLoader.FileHasNoContent) {
- AppMsg.makeText(getActivity(), R.string.error_import_file_no_content,
- AppMsg.STYLE_ALERT).show();
- } else if (error instanceof ImportKeysListLoader.NonPgpPart) {
- AppMsg.makeText(getActivity(),
- ((ImportKeysListLoader.NonPgpPart) error).getCount() + " " + getResources().
- getQuantityString(R.plurals.error_import_non_pgp_part,
- ((ImportKeysListLoader.NonPgpPart) error).getCount()),
- new AppMsg.Style(AppMsg.LENGTH_LONG, R.color.confirm)).show();
- } else {
- AppMsg.makeText(getActivity(), R.string.error_generic_report_bug,
- new AppMsg.Style(AppMsg.LENGTH_LONG, R.color.alert)).show();
- }
- break;
-
- case LOADER_ID_SERVER_QUERY:
-
- if (error == null) {
- AppMsg.makeText(
- getActivity(), getResources().getQuantityString(R.plurals.keys_found,
- mAdapter.getCount(), mAdapter.getCount()),
- AppMsg.STYLE_INFO
- ).show();
- } else if (error instanceof KeyServer.InsufficientQuery) {
- AppMsg.makeText(getActivity(), R.string.error_keyserver_insufficient_query,
- AppMsg.STYLE_ALERT).show();
- } else if (error instanceof KeyServer.QueryException) {
- AppMsg.makeText(getActivity(), R.string.error_keyserver_query,
- AppMsg.STYLE_ALERT).show();
- } else if (error instanceof KeyServer.TooManyResponses) {
- AppMsg.makeText(getActivity(), R.string.error_keyserver_too_many_responses,
- AppMsg.STYLE_ALERT).show();
- }
- break;
-
- default:
- break;
- }
- }
-
- @Override
- public void onLoaderReset(Loader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> loader) {
- switch (loader.getId()) {
- case LOADER_ID_BYTES:
- // Clear the data in the adapter.
- mAdapter.clear();
- break;
- case LOADER_ID_SERVER_QUERY:
- // Clear the data in the adapter.
- mAdapter.clear();
- break;
- default:
- break;
- }
- }
-
- private InputData getInputData(byte[] importBytes, Uri dataUri) {
- InputData inputData = null;
- if (importBytes != null) {
- inputData = new InputData(new ByteArrayInputStream(importBytes), importBytes.length);
- } else if (dataUri != null) {
- try {
- InputStream inputStream = getActivity().getContentResolver().openInputStream(dataUri);
- int length = inputStream.available();
-
- inputData = new InputData(inputStream, length);
- } catch (FileNotFoundException e) {
- Log.e(Constants.TAG, "FileNotFoundException!", e);
- } catch (IOException e) {
- Log.e(Constants.TAG, "IOException!", e);
- }
- }
-
- return inputData;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysNFCFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysNFCFragment.java
deleted file mode 100644
index 110647284..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysNFCFragment.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import com.beardedhen.androidbootstrap.BootstrapButton;
-import org.sufficientlysecure.keychain.R;
-
-public class ImportKeysNFCFragment extends Fragment {
-
- private BootstrapButton mButton;
-
- /**
- * Creates new instance of this fragment
- */
- public static ImportKeysNFCFragment newInstance() {
- ImportKeysNFCFragment frag = new ImportKeysNFCFragment();
-
- Bundle args = new Bundle();
- frag.setArguments(args);
-
- return frag;
- }
-
- /**
- * Inflate the layout for this fragment
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.import_keys_nfc_fragment, container, false);
-
- mButton = (BootstrapButton) view.findViewById(R.id.import_nfc_button);
- mButton.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- // show nfc help
- Intent intent = new Intent(getActivity(), HelpActivity.class);
- intent.putExtra(HelpActivity.EXTRA_SELECTED_TAB, 2);
- startActivityForResult(intent, 0);
- }
- });
-
- return view;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java
deleted file mode 100644
index 8b553d273..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import com.google.zxing.integration.android.IntentResult;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.beardedhen.androidbootstrap.BootstrapButton;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.util.IntentIntegratorSupportV4;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.util.ArrayList;
-import java.util.Locale;
-
-public class ImportKeysQrCodeFragment extends Fragment {
-
- private ImportKeysActivity mImportActivity;
- private BootstrapButton mButton;
- private TextView mText;
- private ProgressBar mProgress;
-
- private String[] mScannedContent;
-
- /**
- * Creates new instance of this fragment
- */
- public static ImportKeysQrCodeFragment newInstance() {
- ImportKeysQrCodeFragment frag = new ImportKeysQrCodeFragment();
-
- Bundle args = new Bundle();
- frag.setArguments(args);
-
- return frag;
- }
-
- /**
- * Inflate the layout for this fragment
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.import_keys_qr_code_fragment, container, false);
-
- mButton = (BootstrapButton) view.findViewById(R.id.import_qrcode_button);
- mText = (TextView) view.findViewById(R.id.import_qrcode_text);
- mProgress = (ProgressBar) view.findViewById(R.id.import_qrcode_progress);
-
- mButton.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- // scan using xzing's Barcode Scanner
- new IntentIntegratorSupportV4(ImportKeysQrCodeFragment.this).initiateScan();
- }
- });
-
- return view;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- mImportActivity = (ImportKeysActivity) getActivity();
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode & 0xFFFF) {
- case IntentIntegratorSupportV4.REQUEST_CODE: {
- IntentResult scanResult = IntentIntegratorSupportV4.parseActivityResult(requestCode,
- resultCode, data);
- if (scanResult != null && scanResult.getFormatName() != null) {
- String scannedContent = scanResult.getContents();
-
- Log.d(Constants.TAG, "scannedContent: " + scannedContent);
-
- // look if it's fingerprint only
- if (scannedContent.toLowerCase(Locale.ENGLISH).startsWith(Constants.FINGERPRINT_SCHEME)) {
- importFingerprint(Uri.parse(scanResult.getContents()));
- return;
- }
-
- // look if it is the whole key
- String[] parts = scannedContent.split(",");
- if (parts.length == 3) {
- importParts(parts);
- return;
- }
-
- // is this a full key encoded as qr code?
- if (scannedContent.startsWith("-----BEGIN PGP")) {
- mImportActivity.loadCallback(scannedContent.getBytes(), null, null, null);
- return;
- }
-
- // fail...
- Toast.makeText(getActivity(), R.string.import_qr_code_wrong, Toast.LENGTH_LONG)
- .show();
- }
-
- break;
- }
-
- default:
- super.onActivityResult(requestCode, resultCode, data);
-
- break;
- }
- }
-
- public void importFingerprint(Uri dataUri) {
- mImportActivity.loadFromFingerprintUri(null, dataUri);
- }
-
- private void importParts(String[] parts) {
- int counter = Integer.valueOf(parts[0]);
- int size = Integer.valueOf(parts[1]);
- String content = parts[2];
-
- Log.d(Constants.TAG, "" + counter);
- Log.d(Constants.TAG, "" + size);
- Log.d(Constants.TAG, "" + content);
-
- // first qr code -> setup
- if (counter == 0) {
- mScannedContent = new String[size];
- mProgress.setMax(size);
- mProgress.setVisibility(View.VISIBLE);
- mText.setVisibility(View.VISIBLE);
- }
-
- if (mScannedContent == null || counter > mScannedContent.length) {
- Toast.makeText(getActivity(), R.string.import_qr_code_start_with_one, Toast.LENGTH_LONG)
- .show();
- return;
- }
-
- // save scanned content
- mScannedContent[counter] = content;
-
- // get missing numbers
- ArrayList<Integer> missing = new ArrayList<Integer>();
- for (int i = 0; i < mScannedContent.length; i++) {
- if (mScannedContent[i] == null) {
- missing.add(i);
- }
- }
-
- // update progress and text
- int alreadyScanned = mScannedContent.length - missing.size();
- mProgress.setProgress(alreadyScanned);
-
- String missingString = "";
- for (int m : missing) {
- if (!missingString.equals("")) {
- missingString += ", ";
- }
- missingString += String.valueOf(m + 1);
- }
-
- String missingText = getResources().getQuantityString(R.plurals.import_qr_code_missing,
- missing.size(), missingString);
- mText.setText(missingText);
-
- // finished!
- if (missing.size() == 0) {
- mText.setText(R.string.import_qr_code_finished);
- String result = "";
- for (String in : mScannedContent) {
- result += in;
- }
- mImportActivity.loadCallback(result.getBytes(), null, null, null);
- }
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java
deleted file mode 100644
index 3eb463dac..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.ArrayAdapter;
-import android.widget.EditText;
-import android.widget.Spinner;
-import android.widget.TextView;
-import com.beardedhen.androidbootstrap.BootstrapButton;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.Preferences;
-import org.sufficientlysecure.keychain.util.Log;
-
-public class ImportKeysServerFragment extends Fragment {
- public static final String ARG_QUERY = "query";
- public static final String ARG_KEY_SERVER = "key_server";
- public static final String ARG_DISABLE_QUERY_EDIT = "disable_query_edit";
-
- private ImportKeysActivity mImportActivity;
-
- private BootstrapButton mSearchButton;
- private EditText mQueryEditText;
- private Spinner mServerSpinner;
- private ArrayAdapter<String> mServerAdapter;
-
- /**
- * Creates new instance of this fragment
- */
- public static ImportKeysServerFragment newInstance(String query, String keyServer) {
- ImportKeysServerFragment frag = new ImportKeysServerFragment();
-
- Bundle args = new Bundle();
- args.putString(ARG_QUERY, query);
- args.putString(ARG_KEY_SERVER, keyServer);
-
- frag.setArguments(args);
-
- return frag;
- }
-
- /**
- * Inflate the layout for this fragment
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.import_keys_server_fragment, container, false);
-
- mSearchButton = (BootstrapButton) view.findViewById(R.id.import_server_search);
- mQueryEditText = (EditText) view.findViewById(R.id.import_server_query);
- mServerSpinner = (Spinner) view.findViewById(R.id.import_server_spinner);
-
- // add keyservers to spinner
- mServerAdapter = new ArrayAdapter<String>(getActivity(),
- android.R.layout.simple_spinner_item, Preferences.getPreferences(getActivity())
- .getKeyServers());
- mServerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- mServerSpinner.setAdapter(mServerAdapter);
- if (mServerAdapter.getCount() > 0) {
- mServerSpinner.setSelection(0);
- } else {
- mSearchButton.setEnabled(false);
- }
-
- mSearchButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- String query = mQueryEditText.getText().toString();
- String keyServer = (String) mServerSpinner.getSelectedItem();
- search(query, keyServer);
-
- // close keyboard after pressing search
- InputMethodManager imm =
- (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.hideSoftInputFromWindow(mQueryEditText.getWindowToken(), 0);
- }
- });
-
- mQueryEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
- @Override
- public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- if (actionId == EditorInfo.IME_ACTION_SEARCH) {
- String query = mQueryEditText.getText().toString();
- String keyServer = (String) mServerSpinner.getSelectedItem();
- search(query, keyServer);
-
- // Don't return true to let the keyboard close itself after pressing search
- return false;
- }
- return false;
- }
- });
-
- return view;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- mImportActivity = (ImportKeysActivity) getActivity();
-
- // set displayed values
- if (getArguments() != null) {
- if (getArguments().containsKey(ARG_QUERY)) {
- String query = getArguments().getString(ARG_QUERY);
- mQueryEditText.setText(query, TextView.BufferType.EDITABLE);
-
- Log.d(Constants.TAG, "query: " + query);
- }
-
- if (getArguments().containsKey(ARG_KEY_SERVER)) {
- String keyServer = getArguments().getString(ARG_KEY_SERVER);
- int keyServerPos = mServerAdapter.getPosition(keyServer);
- mServerSpinner.setSelection(keyServerPos);
-
- Log.d(Constants.TAG, "keyServer: " + keyServer);
- }
-
- if (getArguments().getBoolean(ARG_DISABLE_QUERY_EDIT, false)) {
- mQueryEditText.setEnabled(false);
- }
- }
- }
-
- private void search(String query, String keyServer) {
- mImportActivity.loadCallback(null, null, query, keyServer);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java
deleted file mode 100644
index 8db643583..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuItem;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.ExportHelper;
-
-public class KeyListActivity extends DrawerActivity {
-
- ExportHelper mExportHelper;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- mExportHelper = new ExportHelper(this);
-
- setContentView(R.layout.key_list_activity);
-
- // now setup navigation drawer in DrawerActivity...
- setupDrawerNavigation(savedInstanceState);
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- super.onCreateOptionsMenu(menu);
- getMenuInflater().inflate(R.menu.key_list, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.menu_key_list_import:
- importKeys();
- return true;
-
- case R.id.menu_key_list_create:
- createKey();
- return true;
-
- case R.id.menu_key_list_create_expert:
- createKeyExpert();
- return true;
-
- case R.id.menu_key_list_export:
- mExportHelper.showExportKeysDialog(null, Constants.Path.APP_DIR_FILE, true);
- return true;
-
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-
- private void importKeys() {
- Intent intent = new Intent(this, ImportKeysActivity.class);
- startActivityForResult(intent, 0);
- }
-
- private void createKey() {
- Intent intent = new Intent(this, EditKeyActivity.class);
- intent.setAction(EditKeyActivity.ACTION_CREATE_KEY);
- intent.putExtra(EditKeyActivity.EXTRA_GENERATE_DEFAULT_KEYS, true);
- intent.putExtra(EditKeyActivity.EXTRA_USER_IDS, ""); // show user id view
- startActivityForResult(intent, 0);
- }
-
- private void createKeyExpert() {
- Intent intent = new Intent(this, EditKeyActivity.class);
- intent.setAction(EditKeyActivity.ACTION_CREATE_KEY);
- startActivityForResult(intent, 0);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
deleted file mode 100644
index 3e2c96464..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
+++ /dev/null
@@ -1,700 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.graphics.Color;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.CursorLoader;
-import android.support.v4.content.Loader;
-import android.support.v4.view.MenuItemCompat;
-import android.support.v7.app.ActionBarActivity;
-import android.support.v7.widget.SearchView;
-import android.text.TextUtils;
-import android.view.ActionMode;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.view.animation.AnimationUtils;
-import android.widget.AbsListView.MultiChoiceModeListener;
-import android.widget.AdapterView;
-import android.widget.Button;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
-import com.beardedhen.androidbootstrap.BootstrapButton;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.ExportHelper;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
-import org.sufficientlysecure.keychain.ui.adapter.HighlightQueryCursorAdapter;
-import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
-import org.sufficientlysecure.keychain.util.Log;
-import se.emilsjolander.stickylistheaders.ApiLevelTooLowException;
-import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
-import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
-
-import java.util.HashMap;
-
-/**
- * Public key list with sticky list headers. It does _not_ extend ListFragment because it uses
- * StickyListHeaders library which does not extend upon ListView.
- */
-public class KeyListFragment extends Fragment
- implements SearchView.OnQueryTextListener, AdapterView.OnItemClickListener,
- LoaderManager.LoaderCallbacks<Cursor> {
-
- private KeyListAdapter mAdapter;
- private StickyListHeadersListView mStickyList;
-
- // rebuild functionality of ListFragment, http://stackoverflow.com/a/12504097
- boolean mListShown;
- View mProgressContainer;
- View mListContainer;
-
- private String mCurQuery;
- private SearchView mSearchView;
- // empty list layout
- private BootstrapButton mButtonEmptyCreate;
- private BootstrapButton mButtonEmptyImport;
-
-
- /**
- * Load custom layout with StickyListView from library
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View root = inflater.inflate(R.layout.key_list_fragment, container, false);
-
- mStickyList = (StickyListHeadersListView) root.findViewById(R.id.key_list_list);
- mStickyList.setOnItemClickListener(this);
-
-
- // empty view
- mButtonEmptyCreate = (BootstrapButton) root.findViewById(R.id.key_list_empty_button_create);
- mButtonEmptyCreate.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- Intent intent = new Intent(getActivity(), EditKeyActivity.class);
- intent.setAction(EditKeyActivity.ACTION_CREATE_KEY);
- intent.putExtra(EditKeyActivity.EXTRA_GENERATE_DEFAULT_KEYS, true);
- intent.putExtra(EditKeyActivity.EXTRA_USER_IDS, ""); // show user id view
- startActivityForResult(intent, 0);
- }
- });
- mButtonEmptyImport = (BootstrapButton) root.findViewById(R.id.key_list_empty_button_import);
- mButtonEmptyImport.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- Intent intent = new Intent(getActivity(), ImportKeysActivity.class);
- intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE);
- startActivityForResult(intent, 0);
- }
- });
-
- // rebuild functionality of ListFragment, http://stackoverflow.com/a/12504097
- mListContainer = root.findViewById(R.id.key_list_list_container);
- mProgressContainer = root.findViewById(R.id.key_list_progress_container);
- mListShown = true;
-
- return root;
- }
-
- /**
- * Define Adapter and Loader on create of Activity
- */
- @SuppressLint("NewApi")
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- mStickyList.setOnItemClickListener(this);
- mStickyList.setAreHeadersSticky(true);
- mStickyList.setDrawingListUnderStickyHeader(false);
- mStickyList.setFastScrollEnabled(true);
- try {
- mStickyList.setFastScrollAlwaysVisible(true);
- } catch (ApiLevelTooLowException e) {
- }
-
- /*
- * ActionBarSherlock does not support MultiChoiceModeListener. Thus multi-selection is only
- * available for Android >= 3.0
- */
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- mStickyList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
- mStickyList.getWrappedList().setMultiChoiceModeListener(new MultiChoiceModeListener() {
-
- @Override
- public boolean onCreateActionMode(ActionMode mode, Menu menu) {
- android.view.MenuInflater inflater = getActivity().getMenuInflater();
- inflater.inflate(R.menu.key_list_multi, menu);
- return true;
- }
-
- @Override
- public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
- return false;
- }
-
- @Override
- public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
-
- // get IDs for checked positions as long array
- long[] ids;
-
- switch (item.getItemId()) {
- case R.id.menu_key_list_multi_encrypt: {
- ids = mAdapter.getCurrentSelectedMasterKeyIds();
- encrypt(mode, ids);
- break;
- }
- case R.id.menu_key_list_multi_delete: {
- ids = mAdapter.getCurrentSelectedMasterKeyIds();
- showDeleteKeyDialog(mode, ids);
- break;
- }
- case R.id.menu_key_list_multi_export: {
- ids = mAdapter.getCurrentSelectedMasterKeyIds();
- ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity());
- mExportHelper.showExportKeysDialog(
- ids, Constants.Path.APP_DIR_FILE, mAdapter.isAnySecretSelected());
- break;
- }
- case R.id.menu_key_list_multi_select_all: {
- // select all
- for (int i = 0; i < mStickyList.getCount(); i++) {
- mStickyList.setItemChecked(i, true);
- }
- break;
- }
- }
- return true;
- }
-
- @Override
- public void onDestroyActionMode(ActionMode mode) {
- mAdapter.clearSelection();
- }
-
- @Override
- public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
- boolean checked) {
- if (checked) {
- mAdapter.setNewSelection(position, checked);
- } else {
- mAdapter.removeSelection(position);
- }
- int count = mStickyList.getCheckedItemCount();
- String keysSelected = getResources().getQuantityString(
- R.plurals.key_list_selected_keys, count, count);
- mode.setTitle(keysSelected);
- }
-
- });
- }
-
- // We have a menu item to show in action bar.
- setHasOptionsMenu(true);
-
- // NOTE: Not supported by StickyListHeader, but reimplemented here
- // Start out with a progress indicator.
- setListShown(false);
-
- // Create an empty adapter we will use to display the loaded data.
- mAdapter = new KeyListAdapter(getActivity(), null, Id.type.public_key);
- mStickyList.setAdapter(mAdapter);
-
- // Prepare the loader. Either re-connect with an existing one,
- // or start a new one.
- getLoaderManager().initLoader(0, null, this);
- }
-
- // These are the rows that we will retrieve.
- static final String[] PROJECTION = new String[]{
- KeyRings._ID,
- KeyRings.MASTER_KEY_ID,
- KeyRings.USER_ID,
- KeyRings.IS_REVOKED,
- KeyRings.VERIFIED,
- KeyRings.HAS_SECRET
- };
-
- static final int INDEX_MASTER_KEY_ID = 1;
- static final int INDEX_USER_ID = 2;
- static final int INDEX_IS_REVOKED = 3;
- static final int INDEX_VERIFIED = 4;
- static final int INDEX_HAS_SECRET = 5;
-
- @Override
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- // This is called when a new Loader needs to be created. This
- // sample only has one Loader, so we don't care about the ID.
- Uri baseUri = KeyRings.buildUnifiedKeyRingsUri();
- String where = null;
- String whereArgs[] = null;
- if (mCurQuery != null) {
- where = KeyRings.USER_ID + " LIKE ?";
- whereArgs = new String[]{"%" + mCurQuery + "%"};
- }
- // Now create and return a CursorLoader that will take care of
- // creating a Cursor for the data being displayed.
- return new CursorLoader(getActivity(), baseUri, PROJECTION, where, whereArgs, null);
- }
-
- @Override
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- // Swap the new cursor in. (The framework will take care of closing the
- // old cursor once we return.)
- mAdapter.setSearchQuery(mCurQuery);
- mAdapter.swapCursor(data);
-
- mStickyList.setAdapter(mAdapter);
-
- // this view is made visible if no data is available
- mStickyList.setEmptyView(getActivity().findViewById(R.id.key_list_empty));
-
- // NOTE: Not supported by StickyListHeader, but reimplemented here
- // The list should now be shown.
- if (isResumed()) {
- setListShown(true);
- } else {
- setListShownNoAnimation(true);
- }
- }
-
- @Override
- public void onLoaderReset(Loader<Cursor> loader) {
- // This is called when the last Cursor provided to onLoadFinished()
- // above is about to be closed. We need to make sure we are no
- // longer using it.
- mAdapter.swapCursor(null);
- }
-
- /**
- * On click on item, start key view activity
- */
- @Override
- public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
- Intent viewIntent = null;
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
- viewIntent = new Intent(getActivity(), ViewKeyActivity.class);
- } else {
- viewIntent = new Intent(getActivity(), ViewKeyActivityJB.class);
- }
- viewIntent.setData(
- KeyRings.buildGenericKeyRingUri(Long.toString(mAdapter.getMasterKeyId(position))));
- startActivity(viewIntent);
- }
-
- @TargetApi(11)
- protected void encrypt(ActionMode mode, long[] masterKeyIds) {
- Intent intent = new Intent(getActivity(), EncryptActivity.class);
- intent.setAction(EncryptActivity.ACTION_ENCRYPT);
- intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, masterKeyIds);
- // used instead of startActivity set actionbar based on callingPackage
- startActivityForResult(intent, 0);
-
- mode.finish();
- }
-
- /**
- * Show dialog to delete key
- *
- * @param masterKeyIds
- */
- @TargetApi(11)
- // TODO: this method needs an overhaul to handle both public and secret keys gracefully!
- public void showDeleteKeyDialog(final ActionMode mode, long[] masterKeyIds) {
- // Message is received after key is deleted
- Handler returnHandler = new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) {
- mode.finish();
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(returnHandler);
-
- DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger,
- masterKeyIds);
-
- deleteKeyDialog.show(getActivity().getSupportFragmentManager(), "deleteKeyDialog");
- }
-
-
- @Override
- public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
- // Get the searchview
- MenuItem searchItem = menu.findItem(R.id.menu_key_list_search);
- mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
-
- // Execute this when searching
- mSearchView.setOnQueryTextListener(this);
-
- // Erase search result without focus
- MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() {
- @Override
- public boolean onMenuItemActionExpand(MenuItem item) {
- return true;
- }
-
- @Override
- public boolean onMenuItemActionCollapse(MenuItem item) {
- mCurQuery = null;
- mSearchView.setQuery("", true);
- getLoaderManager().restartLoader(0, null, KeyListFragment.this);
- return true;
- }
- });
-
- super.onCreateOptionsMenu(menu, inflater);
- }
-
- @Override
- public boolean onQueryTextSubmit(String s) {
- return true;
- }
-
- @Override
- public boolean onQueryTextChange(String s) {
- // Called when the action bar search text has changed. Update
- // the search filter, and restart the loader to do a new query
- // with this filter.
- mCurQuery = !TextUtils.isEmpty(s) ? s : null;
- getLoaderManager().restartLoader(0, null, this);
- return true;
- }
-
- // rebuild functionality of ListFragment, http://stackoverflow.com/a/12504097
- public void setListShown(boolean shown, boolean animate) {
- if (mListShown == shown) {
- return;
- }
- mListShown = shown;
- if (shown) {
- if (animate) {
- mProgressContainer.startAnimation(AnimationUtils.loadAnimation(
- getActivity(), android.R.anim.fade_out));
- mListContainer.startAnimation(AnimationUtils.loadAnimation(
- getActivity(), android.R.anim.fade_in));
- }
- mProgressContainer.setVisibility(View.GONE);
- mListContainer.setVisibility(View.VISIBLE);
- } else {
- if (animate) {
- mProgressContainer.startAnimation(AnimationUtils.loadAnimation(
- getActivity(), android.R.anim.fade_in));
- mListContainer.startAnimation(AnimationUtils.loadAnimation(
- getActivity(), android.R.anim.fade_out));
- }
- mProgressContainer.setVisibility(View.VISIBLE);
- mListContainer.setVisibility(View.INVISIBLE);
- }
- }
-
- // rebuild functionality of ListFragment, http://stackoverflow.com/a/12504097
- public void setListShown(boolean shown) {
- setListShown(shown, true);
- }
-
- // rebuild functionality of ListFragment, http://stackoverflow.com/a/12504097
- public void setListShownNoAnimation(boolean shown) {
- setListShown(shown, false);
- }
-
- /**
- * Implements StickyListHeadersAdapter from library
- */
- private class KeyListAdapter extends HighlightQueryCursorAdapter implements StickyListHeadersAdapter {
- private LayoutInflater mInflater;
-
- private HashMap<Integer, Boolean> mSelection = new HashMap<Integer, Boolean>();
-
- public KeyListAdapter(Context context, Cursor c, int flags) {
- super(context, c, flags);
-
- mInflater = LayoutInflater.from(context);
- }
-
- @Override
- public Cursor swapCursor(Cursor newCursor) {
- return super.swapCursor(newCursor);
- }
-
- /**
- * Bind cursor data to the item list view
- * <p/>
- * NOTE: CursorAdapter already implements the ViewHolder pattern in its getView() method.
- * Thus no ViewHolder is required here.
- */
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
-
- { // set name and stuff, common to both key types
- TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId);
- TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest);
-
- String userId = cursor.getString(INDEX_USER_ID);
- String[] userIdSplit = PgpKeyHelper.splitUserId(userId);
- if (userIdSplit[0] != null) {
- mainUserId.setText(highlightSearchQuery(userIdSplit[0]));
- } else {
- mainUserId.setText(R.string.user_id_no_name);
- }
- if (userIdSplit[1] != null) {
- mainUserIdRest.setText(highlightSearchQuery(userIdSplit[1]));
- mainUserIdRest.setVisibility(View.VISIBLE);
- } else {
- mainUserIdRest.setVisibility(View.GONE);
- }
- }
-
- { // set edit button and revoked info, specific by key type
- View statusDivider = (View) view.findViewById(R.id.status_divider);
- FrameLayout statusLayout = (FrameLayout) view.findViewById(R.id.status_layout);
- Button button = (Button) view.findViewById(R.id.edit);
- TextView revoked = (TextView) view.findViewById(R.id.revoked);
- ImageView verified = (ImageView) view.findViewById(R.id.verified);
-
- if (cursor.getInt(KeyListFragment.INDEX_HAS_SECRET) != 0) {
- // this is a secret key - show the edit button
- statusDivider.setVisibility(View.VISIBLE);
- statusLayout.setVisibility(View.VISIBLE);
- revoked.setVisibility(View.GONE);
- verified.setVisibility(View.GONE);
- button.setVisibility(View.VISIBLE);
-
- final long id = cursor.getLong(INDEX_MASTER_KEY_ID);
- button.setOnClickListener(new OnClickListener() {
- public void onClick(View view) {
- Intent editIntent = new Intent(getActivity(), EditKeyActivity.class);
- editIntent.setData(KeyRingData.buildSecretKeyRingUri(Long.toString(id)));
- editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
- startActivityForResult(editIntent, 0);
- }
- });
- } else {
- // this is a public key - hide the edit button, show if it's revoked
- statusDivider.setVisibility(View.GONE);
- button.setVisibility(View.GONE);
-
- boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0;
- if(isRevoked) {
- statusLayout.setVisibility(isRevoked ? View.VISIBLE : View.GONE);
- revoked.setVisibility(isRevoked ? View.VISIBLE : View.GONE);
- verified.setVisibility(View.GONE);
- } else {
- boolean isVerified = cursor.getInt(INDEX_VERIFIED) > 0;
- statusLayout.setVisibility(isVerified ? View.VISIBLE : View.GONE);
- revoked.setVisibility(View.GONE);
- verified.setVisibility(isVerified ? View.VISIBLE : View.GONE);
- }
- }
- }
-
- }
-
- public boolean isSecretAvailable(int id) {
- if (!mCursor.moveToPosition(id)) {
- throw new IllegalStateException("couldn't move cursor to position " + id);
- }
-
- return mCursor.getInt(INDEX_HAS_SECRET) != 0;
- }
- public long getMasterKeyId(int id) {
- if (!mCursor.moveToPosition(id)) {
- throw new IllegalStateException("couldn't move cursor to position " + id);
- }
-
- return mCursor.getLong(INDEX_MASTER_KEY_ID);
- }
-
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(R.layout.key_list_item, parent, false);
- }
-
- /**
- * Creates a new header view and binds the section headers to it. It uses the ViewHolder
- * pattern. Most functionality is similar to getView() from Android's CursorAdapter.
- * <p/>
- * NOTE: The variables mDataValid and mCursor are available due to the super class
- * CursorAdapter.
- */
- @Override
- public View getHeaderView(int position, View convertView, ViewGroup parent) {
- HeaderViewHolder holder;
- if (convertView == null) {
- holder = new HeaderViewHolder();
- convertView = mInflater.inflate(R.layout.key_list_header, parent, false);
- holder.mText = (TextView) convertView.findViewById(R.id.stickylist_header_text);
- holder.mCount = (TextView) convertView.findViewById(R.id.contacts_num);
- convertView.setTag(holder);
- } else {
- holder = (HeaderViewHolder) convertView.getTag();
- }
-
- if (!mDataValid) {
- // no data available at this point
- Log.d(Constants.TAG, "getHeaderView: No data available at this point!");
- return convertView;
- }
-
- if (!mCursor.moveToPosition(position)) {
- throw new IllegalStateException("couldn't move cursor to position " + position);
- }
-
- if (mCursor.getInt(KeyListFragment.INDEX_HAS_SECRET) != 0) {
- { // set contact count
- int num = mCursor.getCount();
- String contactsTotal = getResources().getQuantityString(R.plurals.n_contacts, num, num);
- holder.mCount.setText(contactsTotal);
- holder.mCount.setVisibility(View.VISIBLE);
- }
-
- holder.mText.setText(convertView.getResources().getString(R.string.my_keys));
- return convertView;
- }
-
- // set header text as first char in user id
- String userId = mCursor.getString(KeyListFragment.INDEX_USER_ID);
- String headerText = convertView.getResources().getString(R.string.user_id_no_name);
- if (userId != null && userId.length() > 0) {
- headerText = "" + userId.subSequence(0, 1).charAt(0);
- }
- holder.mText.setText(headerText);
- holder.mCount.setVisibility(View.GONE);
- return convertView;
- }
-
- /**
- * Header IDs should be static, position=1 should always return the same Id that is.
- */
- @Override
- public long getHeaderId(int position) {
- if (!mDataValid) {
- // no data available at this point
- Log.d(Constants.TAG, "getHeaderView: No data available at this point!");
- return -1;
- }
-
- if (!mCursor.moveToPosition(position)) {
- throw new IllegalStateException("couldn't move cursor to position " + position);
- }
-
- // early breakout: all secret keys are assigned id 0
- if (mCursor.getInt(KeyListFragment.INDEX_HAS_SECRET) != 0) {
- return 1L;
- }
- // otherwise, return the first character of the name as ID
- String userId = mCursor.getString(KeyListFragment.INDEX_USER_ID);
- if (userId != null && userId.length() > 0) {
- return userId.charAt(0);
- } else {
- return Long.MAX_VALUE;
- }
- }
-
- class HeaderViewHolder {
- TextView mText;
- TextView mCount;
- }
-
- /**
- * -------------------------- MULTI-SELECTION METHODS --------------
- */
- public void setNewSelection(int position, boolean value) {
- mSelection.put(position, value);
- notifyDataSetChanged();
- }
-
- public boolean isAnySecretSelected() {
- for (int pos : mSelection.keySet()) {
- if(mAdapter.isSecretAvailable(pos))
- return true;
- }
- return false;
- }
-
- public long[] getCurrentSelectedMasterKeyIds() {
- long[] ids = new long[mSelection.size()];
- int i = 0;
- // get master key ids
- for (int pos : mSelection.keySet()) {
- ids[i++] = mAdapter.getMasterKeyId(pos);
- }
- return ids;
- }
-
- public void removeSelection(int position) {
- mSelection.remove(position);
- notifyDataSetChanged();
- }
-
- public void clearSelection() {
- mSelection.clear();
- notifyDataSetChanged();
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- // let the adapter handle setting up the row views
- View v = super.getView(position, convertView, parent);
-
- /**
- * Change color for multi-selection
- */
- if (mSelection.get(position) != null) {
- // selected position color
- v.setBackgroundColor(parent.getResources().getColor(R.color.emphasis));
- } else {
- // default color
- v.setBackgroundColor(Color.TRANSPARENT);
- }
-
- return v;
- }
-
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java
deleted file mode 100644
index 265bb2139..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.annotation.SuppressLint;
-import android.content.Intent;
-import android.os.Build;
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.Preference;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceFragment;
-import android.preference.PreferenceScreen;
-
-import org.spongycastle.bcpg.HashAlgorithmTags;
-import org.spongycastle.openpgp.PGPEncryptedData;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.Preferences;
-import org.sufficientlysecure.keychain.ui.widget.IntegerListPreference;
-
-import java.util.List;
-
-@SuppressLint("NewApi")
-public class PreferencesActivity extends PreferenceActivity {
-
- public static final String ACTION_PREFS_GEN = "org.sufficientlysecure.keychain.ui.PREFS_GEN";
- public static final String ACTION_PREFS_ADV = "org.sufficientlysecure.keychain.ui.PREFS_ADV";
-
- private PreferenceScreen mKeyServerPreference = null;
- private static Preferences sPreferences;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- sPreferences = Preferences.getPreferences(this);
- super.onCreate(savedInstanceState);
-
-// final ActionBar actionBar = getSupportActionBar();
-// actionBar.setDisplayShowTitleEnabled(true);
-// actionBar.setDisplayHomeAsUpEnabled(false);
-// actionBar.setHomeButtonEnabled(false);
-
- String action = getIntent().getAction();
-
- if (action != null && action.equals(ACTION_PREFS_GEN)) {
- addPreferencesFromResource(R.xml.gen_preferences);
-
- initializePassPassphraceCacheTtl(
- (IntegerListPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_TTL));
-
- mKeyServerPreference = (PreferenceScreen) findPreference(Constants.Pref.KEY_SERVERS);
- String servers[] = sPreferences.getKeyServers();
- mKeyServerPreference.setSummary(getResources().getQuantityString(R.plurals.n_key_servers,
- servers.length, servers.length));
- mKeyServerPreference
- .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
- public boolean onPreferenceClick(Preference preference) {
- Intent intent = new Intent(PreferencesActivity.this,
- PreferencesKeyServerActivity.class);
- intent.putExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS,
- sPreferences.getKeyServers());
- startActivityForResult(intent, Id.request.key_server_preference);
- return false;
- }
- });
-
- } else if (action != null && action.equals(ACTION_PREFS_ADV)) {
- addPreferencesFromResource(R.xml.adv_preferences);
-
- initializeEncryptionAlgorithm(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_ENCRYPTION_ALGORITHM));
-
- int[] valueIds = new int[]{Id.choice.compression.none, Id.choice.compression.zip,
- Id.choice.compression.zlib, Id.choice.compression.bzip2, };
- String[] entries = new String[]{
- getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
- "ZIP (" + getString(R.string.compression_fast) + ")",
- "ZLIB (" + getString(R.string.compression_fast) + ")",
- "BZIP2 (" + getString(R.string.compression_very_slow) + ")", };
- String[] values = new String[valueIds.length];
- for (int i = 0; i < values.length; ++i) {
- values[i] = "" + valueIds[i];
- }
-
- initializeHashAlgorithm(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_HASH_ALGORITHM),
- valueIds, entries, values);
-
- initializeMessageCompression(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_MESSAGE_COMPRESSION),
- valueIds, entries, values);
-
- initializeFileCompression(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_FILE_COMPRESSION),
- entries, values);
-
- initializeAsciiArmor(
- (CheckBoxPreference) findPreference(Constants.Pref.DEFAULT_ASCII_ARMOR));
-
- initializeForceV3Signatures(
- (CheckBoxPreference) findPreference(Constants.Pref.FORCE_V3_SIGNATURES));
-
- } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
- // Load the legacy preferences headers
- addPreferencesFromResource(R.xml.preference_headers_legacy);
- }
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case Id.request.key_server_preference: {
- if (resultCode == RESULT_CANCELED || data == null) {
- return;
- }
- String servers[] = data
- .getStringArrayExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS);
- sPreferences.setKeyServers(servers);
- mKeyServerPreference.setSummary(getResources().getQuantityString(
- R.plurals.n_key_servers, servers.length, servers.length));
- break;
- }
-
- default: {
- super.onActivityResult(requestCode, resultCode, data);
- break;
- }
- }
- }
-
- /* Called only on Honeycomb and later */
- @Override
- public void onBuildHeaders(List<Header> target) {
- super.onBuildHeaders(target);
- loadHeadersFromResource(R.xml.preference_headers, target);
- }
-
- /**
- * This fragment shows the general preferences in android 3.0+
- */
- public static class GeneralPrefsFragment extends PreferenceFragment {
-
- private PreferenceScreen mKeyServerPreference = null;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Load the preferences from an XML resource
- addPreferencesFromResource(R.xml.gen_preferences);
-
- initializePassPassphraceCacheTtl(
- (IntegerListPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_TTL));
-
- mKeyServerPreference = (PreferenceScreen) findPreference(Constants.Pref.KEY_SERVERS);
- String servers[] = sPreferences.getKeyServers();
- mKeyServerPreference.setSummary(getResources().getQuantityString(R.plurals.n_key_servers,
- servers.length, servers.length));
- mKeyServerPreference
- .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
- public boolean onPreferenceClick(Preference preference) {
- Intent intent = new Intent(getActivity(),
- PreferencesKeyServerActivity.class);
- intent.putExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS,
- sPreferences.getKeyServers());
- startActivityForResult(intent, Id.request.key_server_preference);
- return false;
- }
- });
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case Id.request.key_server_preference: {
- if (resultCode == RESULT_CANCELED || data == null) {
- return;
- }
- String servers[] = data
- .getStringArrayExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS);
- sPreferences.setKeyServers(servers);
- mKeyServerPreference.setSummary(getResources().getQuantityString(
- R.plurals.n_key_servers, servers.length, servers.length));
- break;
- }
-
- default: {
- super.onActivityResult(requestCode, resultCode, data);
- break;
- }
- }
- }
- }
-
- /**
- * This fragment shows the advanced preferences in android 3.0+
- */
- public static class AdvancedPrefsFragment extends PreferenceFragment {
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Load the preferences from an XML resource
- addPreferencesFromResource(R.xml.adv_preferences);
-
- initializeEncryptionAlgorithm(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_ENCRYPTION_ALGORITHM));
-
- int[] valueIds = new int[]{Id.choice.compression.none, Id.choice.compression.zip,
- Id.choice.compression.zlib, Id.choice.compression.bzip2, };
- String[] entries = new String[]{
- getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
- "ZIP (" + getString(R.string.compression_fast) + ")",
- "ZLIB (" + getString(R.string.compression_fast) + ")",
- "BZIP2 (" + getString(R.string.compression_very_slow) + ")", };
- String[] values = new String[valueIds.length];
- for (int i = 0; i < values.length; ++i) {
- values[i] = "" + valueIds[i];
- }
-
- initializeHashAlgorithm(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_HASH_ALGORITHM),
- valueIds, entries, values);
-
- initializeMessageCompression(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_MESSAGE_COMPRESSION),
- valueIds, entries, values);
-
- initializeFileCompression(
- (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_FILE_COMPRESSION),
- entries, values);
-
- initializeAsciiArmor(
- (CheckBoxPreference) findPreference(Constants.Pref.DEFAULT_ASCII_ARMOR));
-
- initializeForceV3Signatures(
- (CheckBoxPreference) findPreference(Constants.Pref.FORCE_V3_SIGNATURES));
- }
- }
-
- protected boolean isValidFragment(String fragmentName) {
- return AdvancedPrefsFragment.class.getName().equals(fragmentName)
- || GeneralPrefsFragment.class.getName().equals(fragmentName)
- || super.isValidFragment(fragmentName);
- }
-
- private static void initializePassPassphraceCacheTtl(final IntegerListPreference mPassphraseCacheTtl) {
- mPassphraseCacheTtl.setValue("" + sPreferences.getPassphraseCacheTtl());
- mPassphraseCacheTtl.setSummary(mPassphraseCacheTtl.getEntry());
- mPassphraseCacheTtl
- .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mPassphraseCacheTtl.setValue(newValue.toString());
- mPassphraseCacheTtl.setSummary(mPassphraseCacheTtl.getEntry());
- sPreferences.setPassphraseCacheTtl(Integer.parseInt(newValue.toString()));
- return false;
- }
- });
- }
-
- private static void initializeEncryptionAlgorithm(final IntegerListPreference mEncryptionAlgorithm) {
- int valueIds[] = {PGPEncryptedData.AES_128, PGPEncryptedData.AES_192,
- PGPEncryptedData.AES_256, PGPEncryptedData.BLOWFISH, PGPEncryptedData.TWOFISH,
- PGPEncryptedData.CAST5, PGPEncryptedData.DES, PGPEncryptedData.TRIPLE_DES,
- PGPEncryptedData.IDEA, };
- String entries[] = {"AES-128", "AES-192", "AES-256", "Blowfish", "Twofish", "CAST5",
- "DES", "Triple DES", "IDEA", };
- String values[] = new String[valueIds.length];
- for (int i = 0; i < values.length; ++i) {
- values[i] = "" + valueIds[i];
- }
- mEncryptionAlgorithm.setEntries(entries);
- mEncryptionAlgorithm.setEntryValues(values);
- mEncryptionAlgorithm.setValue("" + sPreferences.getDefaultEncryptionAlgorithm());
- mEncryptionAlgorithm.setSummary(mEncryptionAlgorithm.getEntry());
- mEncryptionAlgorithm
- .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mEncryptionAlgorithm.setValue(newValue.toString());
- mEncryptionAlgorithm.setSummary(mEncryptionAlgorithm.getEntry());
- sPreferences.setDefaultEncryptionAlgorithm(Integer.parseInt(newValue
- .toString()));
- return false;
- }
- });
- }
-
- private static void initializeHashAlgorithm
- (final IntegerListPreference mHashAlgorithm, int[] valueIds, String[] entries, String[] values) {
- valueIds = new int[]{HashAlgorithmTags.MD5, HashAlgorithmTags.RIPEMD160,
- HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA224, HashAlgorithmTags.SHA256,
- HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA512, };
- entries = new String[]{"MD5", "RIPEMD-160", "SHA-1", "SHA-224", "SHA-256", "SHA-384",
- "SHA-512", };
- values = new String[valueIds.length];
- for (int i = 0; i < values.length; ++i) {
- values[i] = "" + valueIds[i];
- }
- mHashAlgorithm.setEntries(entries);
- mHashAlgorithm.setEntryValues(values);
- mHashAlgorithm.setValue("" + sPreferences.getDefaultHashAlgorithm());
- mHashAlgorithm.setSummary(mHashAlgorithm.getEntry());
- mHashAlgorithm.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mHashAlgorithm.setValue(newValue.toString());
- mHashAlgorithm.setSummary(mHashAlgorithm.getEntry());
- sPreferences.setDefaultHashAlgorithm(Integer.parseInt(newValue.toString()));
- return false;
- }
- });
- }
-
- private static void initializeMessageCompression(
- final IntegerListPreference mMessageCompression,
- int[] valueIds, String[] entries, String[] values) {
- mMessageCompression.setEntries(entries);
- mMessageCompression.setEntryValues(values);
- mMessageCompression.setValue("" + sPreferences.getDefaultMessageCompression());
- mMessageCompression.setSummary(mMessageCompression.getEntry());
- mMessageCompression
- .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mMessageCompression.setValue(newValue.toString());
- mMessageCompression.setSummary(mMessageCompression.getEntry());
- sPreferences.setDefaultMessageCompression(Integer.parseInt(newValue
- .toString()));
- return false;
- }
- });
- }
-
- private static void initializeFileCompression
- (final IntegerListPreference mFileCompression, String[] entries, String[] values) {
- mFileCompression.setEntries(entries);
- mFileCompression.setEntryValues(values);
- mFileCompression.setValue("" + sPreferences.getDefaultFileCompression());
- mFileCompression.setSummary(mFileCompression.getEntry());
- mFileCompression.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mFileCompression.setValue(newValue.toString());
- mFileCompression.setSummary(mFileCompression.getEntry());
- sPreferences.setDefaultFileCompression(Integer.parseInt(newValue.toString()));
- return false;
- }
- });
- }
-
- private static void initializeAsciiArmor(final CheckBoxPreference mAsciiArmor) {
- mAsciiArmor.setChecked(sPreferences.getDefaultAsciiArmor());
- mAsciiArmor.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mAsciiArmor.setChecked((Boolean) newValue);
- sPreferences.setDefaultAsciiArmor((Boolean) newValue);
- return false;
- }
- });
- }
-
- private static void initializeForceV3Signatures(final CheckBoxPreference mForceV3Signatures) {
- mForceV3Signatures.setChecked(sPreferences.getForceV3Signatures());
- mForceV3Signatures
- .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- mForceV3Signatures.setChecked((Boolean) newValue);
- sPreferences.setForceV3Signatures((Boolean) newValue);
- return false;
- }
- });
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java
deleted file mode 100644
index 719378274..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.v7.app.ActionBarActivity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.TextView;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.ActionBarHelper;
-import org.sufficientlysecure.keychain.ui.widget.Editor;
-import org.sufficientlysecure.keychain.ui.widget.Editor.EditorListener;
-import org.sufficientlysecure.keychain.ui.widget.KeyServerEditor;
-
-import java.util.Vector;
-
-public class PreferencesKeyServerActivity extends ActionBarActivity implements OnClickListener,
- EditorListener {
-
- public static final String EXTRA_KEY_SERVERS = "key_servers";
-
- private LayoutInflater mInflater;
- private ViewGroup mEditors;
- private View mAdd;
- private TextView mTitle;
- private TextView mSummary;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.btn_okay, R.drawable.ic_action_done,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // ok
- okClicked();
- }
- }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // cancel
- cancelClicked();
- }
- }
- );
-
- setContentView(R.layout.key_server_preference);
-
- mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- mTitle = (TextView) findViewById(R.id.title);
- mSummary = (TextView) findViewById(R.id.summary);
-
- mTitle.setText(R.string.label_key_servers);
-
- mEditors = (ViewGroup) findViewById(R.id.editors);
- mAdd = findViewById(R.id.add);
- mAdd.setOnClickListener(this);
-
- Intent intent = getIntent();
- String servers[] = intent.getStringArrayExtra(EXTRA_KEY_SERVERS);
- if (servers != null) {
- for (String serv : servers) {
- KeyServerEditor view = (KeyServerEditor) mInflater.inflate(
- R.layout.key_server_editor, mEditors, false);
- view.setEditorListener(this);
- view.setValue(serv);
- mEditors.addView(view);
- }
- }
- }
-
- public void onDeleted(Editor editor, boolean wasNewItem) {
- // nothing to do
- }
-
- @Override
- public void onEdited() {
-
- }
-
- public void onClick(View v) {
- KeyServerEditor view = (KeyServerEditor) mInflater.inflate(R.layout.key_server_editor,
- mEditors, false);
- view.setEditorListener(this);
- mEditors.addView(view);
- }
-
- private void cancelClicked() {
- setResult(RESULT_CANCELED, null);
- finish();
- }
-
- private void okClicked() {
- Intent data = new Intent();
- Vector<String> servers = new Vector<String>();
- for (int i = 0; i < mEditors.getChildCount(); ++i) {
- KeyServerEditor editor = (KeyServerEditor) mEditors.getChildAt(i);
- String tmp = editor.getValue();
- if (tmp.length() > 0) {
- servers.add(tmp);
- }
- }
- String[] dummy = new String[0];
- data.putExtra(EXTRA_KEY_SERVERS, servers.toArray(dummy));
- setResult(RESULT_OK, data);
- finish();
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java
deleted file mode 100644
index 874703704..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.v7.app.ActionBarActivity;
-import android.view.View;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.ActionBarHelper;
-
-public class SelectPublicKeyActivity extends ActionBarActivity {
-
- // Actions for internal use only:
- public static final String ACTION_SELECT_PUBLIC_KEYS = Constants.INTENT_PREFIX
- + "SELECT_PUBLIC_KEYRINGS";
-
- public static final String EXTRA_SELECTED_MASTER_KEY_IDS = "master_key_ids";
-
- public static final String RESULT_EXTRA_MASTER_KEY_IDS = "master_key_ids";
- public static final String RESULT_EXTRA_USER_IDS = "user_ids";
-
- SelectPublicKeyFragment mSelectFragment;
-
- long mSelectedMasterKeyIds[];
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.btn_okay, R.drawable.ic_action_done,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // ok
- okClicked();
- }
- }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // cancel
- cancelClicked();
- }
- }
- );
-
- setContentView(R.layout.select_public_key_activity);
-
- setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
-
- handleIntent(getIntent());
-
- // Check that the activity is using the layout version with
- // the fragment_container FrameLayout
- if (findViewById(R.id.select_public_key_fragment_container) != null) {
-
- // However, if we're being restored from a previous state,
- // then we don't need to do anything and should return or else
- // we could end up with overlapping fragments.
- if (savedInstanceState != null) {
- return;
- }
-
- // Create an instance of the fragment
- mSelectFragment = SelectPublicKeyFragment.newInstance(mSelectedMasterKeyIds);
-
- // Add the fragment to the 'fragment_container' FrameLayout
- getSupportFragmentManager().beginTransaction()
- .add(R.id.select_public_key_fragment_container, mSelectFragment).commit();
- }
-
- // TODO: reimplement!
- // mFilterLayout = findViewById(R.id.layout_filter);
- // mFilterInfo = (TextView) mFilterLayout.findViewById(R.id.filterInfo);
- // mClearFilterButton = (Button) mFilterLayout.findViewById(R.id.btn_clear);
- //
- // mClearFilterButton.setOnClickListener(new OnClickListener() {
- // public void onClick(View v) {
- // handleIntent(new Intent());
- // }
- // });
-
- }
-
- @Override
- protected void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
- handleIntent(intent);
- }
-
- private void handleIntent(Intent intent) {
- // TODO: reimplement search!
-
- // String searchString = null;
- // if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
- // searchString = intent.getStringExtra(SearchManager.QUERY);
- // if (searchString != null && searchString.trim().length() == 0) {
- // searchString = null;
- // }
- // }
-
- // if (searchString == null) {
- // mFilterLayout.setVisibility(View.GONE);
- // } else {
- // mFilterLayout.setVisibility(View.VISIBLE);
- // mFilterInfo.setText(getString(R.string.filterInfo, searchString));
- // }
-
- // preselected master keys
- mSelectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS);
- }
-
- private void cancelClicked() {
- setResult(RESULT_CANCELED, null);
- finish();
- }
-
- private void okClicked() {
- Intent data = new Intent();
- data.putExtra(RESULT_EXTRA_MASTER_KEY_IDS, mSelectFragment.getSelectedMasterKeyIds());
- data.putExtra(RESULT_EXTRA_USER_IDS, mSelectFragment.getSelectedUserIds());
- setResult(RESULT_OK, data);
- finish();
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
deleted file mode 100644
index 9bfe3eaa9..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.CursorLoader;
-import android.support.v4.content.Loader;
-import android.text.Editable;
-import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.EditText;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.compatibility.ListFragmentWorkaround;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
-import org.sufficientlysecure.keychain.provider.KeychainDatabase;
-import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
-import org.sufficientlysecure.keychain.ui.adapter.SelectKeyCursorAdapter;
-
-import java.util.Date;
-import java.util.Vector;
-
-public class SelectPublicKeyFragment extends ListFragmentWorkaround implements TextWatcher,
- LoaderManager.LoaderCallbacks<Cursor> {
- public static final String ARG_PRESELECTED_KEY_IDS = "preselected_key_ids";
-
- private SelectKeyCursorAdapter mAdapter;
- private EditText mSearchView;
- private long mSelectedMasterKeyIds[];
- private String mCurQuery;
-
- // copied from ListFragment
- static final int INTERNAL_EMPTY_ID = 0x00ff0001;
- static final int INTERNAL_PROGRESS_CONTAINER_ID = 0x00ff0002;
- static final int INTERNAL_LIST_CONTAINER_ID = 0x00ff0003;
- // added for search view
- static final int SEARCH_ID = 0x00ff0004;
-
- /**
- * Creates new instance of this fragment
- */
- public static SelectPublicKeyFragment newInstance(long[] preselectedKeyIds) {
- SelectPublicKeyFragment frag = new SelectPublicKeyFragment();
- Bundle args = new Bundle();
-
- args.putLongArray(ARG_PRESELECTED_KEY_IDS, preselectedKeyIds);
-
- frag.setArguments(args);
-
- return frag;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mSelectedMasterKeyIds = getArguments().getLongArray(ARG_PRESELECTED_KEY_IDS);
- }
-
- /**
- * Copied from ListFragment and added EditText for search on top of list.
- * We do not use a custom layout here, because this breaks the progress bar functionality
- * of ListFragment.
- *
- * @param inflater
- * @param container
- * @param savedInstanceState
- * @return
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- final Context context = getActivity();
-
- FrameLayout root = new FrameLayout(context);
-
- // ------------------------------------------------------------------
-
- LinearLayout pframe = new LinearLayout(context);
- pframe.setId(INTERNAL_PROGRESS_CONTAINER_ID);
- pframe.setOrientation(LinearLayout.VERTICAL);
- pframe.setVisibility(View.GONE);
- pframe.setGravity(Gravity.CENTER);
-
- ProgressBar progress = new ProgressBar(context, null,
- android.R.attr.progressBarStyleLarge);
- pframe.addView(progress, new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
-
- root.addView(pframe, new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
-
- // ------------------------------------------------------------------
-
- FrameLayout lframe = new FrameLayout(context);
- lframe.setId(INTERNAL_LIST_CONTAINER_ID);
-
- TextView tv = new TextView(getActivity());
- tv.setId(INTERNAL_EMPTY_ID);
- tv.setGravity(Gravity.CENTER);
- lframe.addView(tv, new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
-
- // Added for search view: linearLayout, mSearchView
- LinearLayout linearLayout = new LinearLayout(context);
- linearLayout.setOrientation(LinearLayout.VERTICAL);
-
- mSearchView = new EditText(context);
- mSearchView.setId(SEARCH_ID);
- mSearchView.setHint(R.string.menu_search);
- mSearchView.setCompoundDrawablesWithIntrinsicBounds(
- getResources().getDrawable(R.drawable.ic_action_search), null, null, null);
-
- linearLayout.addView(mSearchView, new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
-
- ListView lv = new ListView(getActivity());
- lv.setId(android.R.id.list);
- lv.setDrawSelectorOnTop(false);
- linearLayout.addView(lv, new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
-
- lframe.addView(linearLayout, new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
-
- root.addView(lframe, new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
-
- // ------------------------------------------------------------------
-
- root.setLayoutParams(new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
-
- return root;
- }
-
- /**
- * Define Adapter and Loader on create of Activity
- */
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
-
- // Give some text to display if there is no data. In a real
- // application this would come from a resource.
- setEmptyText(getString(R.string.list_empty));
-
- mSearchView.addTextChangedListener(this);
-
- mAdapter = new SelectKeyCursorAdapter(getActivity(), null, 0, getListView(), Id.type.public_key);
-
- setListAdapter(mAdapter);
-
- // Start out with a progress indicator.
- setListShown(false);
-
- // Prepare the loader. Either re-connect with an existing one,
- // or start a new one.
- getLoaderManager().initLoader(0, null, this);
- }
-
- /**
- * Selects items based on master key ids in list view
- *
- * @param masterKeyIds
- */
- private void preselectMasterKeyIds(long[] masterKeyIds) {
- if (masterKeyIds != null) {
- for (int i = 0; i < getListView().getCount(); ++i) {
- long keyId = mAdapter.getMasterKeyId(i);
- for (long masterKeyId : masterKeyIds) {
- if (keyId == masterKeyId) {
- getListView().setItemChecked(i, true);
- break;
- }
- }
- }
- }
- }
-
- /**
- * Returns all selected master key ids
- *
- * @return
- */
- public long[] getSelectedMasterKeyIds() {
- // mListView.getCheckedItemIds() would give the row ids of the KeyRings not the master key
- // ids!
- Vector<Long> vector = new Vector<Long>();
- for (int i = 0; i < getListView().getCount(); ++i) {
- if (getListView().isItemChecked(i)) {
- vector.add(mAdapter.getMasterKeyId(i));
- }
- }
-
- // convert to long array
- long[] selectedMasterKeyIds = new long[vector.size()];
- for (int i = 0; i < vector.size(); ++i) {
- selectedMasterKeyIds[i] = vector.get(i);
- }
-
- return selectedMasterKeyIds;
- }
-
- /**
- * Returns all selected user ids
- *
- * @return
- */
- public String[] getSelectedUserIds() {
- Vector<String> userIds = new Vector<String>();
- for (int i = 0; i < getListView().getCount(); ++i) {
- if (getListView().isItemChecked(i)) {
- userIds.add((String) mAdapter.getUserId(i));
- }
- }
-
- // make empty array to not return null
- String userIdArray[] = new String[0];
- return userIds.toArray(userIdArray);
- }
-
- @Override
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- Uri baseUri = KeyRings.buildUnifiedKeyRingsUri();
-
- // These are the rows that we will retrieve.
- long now = new Date().getTime() / 1000;
- String[] projection = new String[]{
- KeyRings._ID,
- KeyRings.MASTER_KEY_ID,
- UserIds.USER_ID,
- "(SELECT COUNT(*) FROM " + Tables.KEYS + " AS k"
- +" WHERE k." + Keys.MASTER_KEY_ID + " = "
- + KeychainDatabase.Tables.KEYS + "." + Keys.MASTER_KEY_ID
- + " AND k." + Keys.IS_REVOKED + " = '0'"
- + " AND k." + Keys.CAN_ENCRYPT + " = '1'"
- + ") AS " + SelectKeyCursorAdapter.PROJECTION_ROW_AVAILABLE,
- "(SELECT COUNT(*) FROM " + Tables.KEYS + " AS k"
- + " WHERE k." + Keys.MASTER_KEY_ID + " = "
- + KeychainDatabase.Tables.KEYS + "." + Keys.MASTER_KEY_ID
- + " AND k." + Keys.IS_REVOKED + " = '0'"
- + " AND k." + Keys.CAN_ENCRYPT + " = '1'"
- + " AND k." + Keys.CREATION + " <= '" + now + "'"
- + " AND ( k." + Keys.EXPIRY + " IS NULL OR k." + Keys.EXPIRY + " >= '" + now + "' )"
- + ") AS " + SelectKeyCursorAdapter.PROJECTION_ROW_VALID, };
-
- String inMasterKeyList = null;
- if (mSelectedMasterKeyIds != null && mSelectedMasterKeyIds.length > 0) {
- inMasterKeyList = Tables.KEYS + "." + KeyRings.MASTER_KEY_ID + " IN (";
- for (int i = 0; i < mSelectedMasterKeyIds.length; ++i) {
- if (i != 0) {
- inMasterKeyList += ", ";
- }
- inMasterKeyList += DatabaseUtils.sqlEscapeString("" + mSelectedMasterKeyIds[i]);
- }
- inMasterKeyList += ")";
- }
-
- String orderBy = UserIds.USER_ID + " ASC";
- if (inMasterKeyList != null) {
- // sort by selected master keys
- orderBy = inMasterKeyList + " DESC, " + orderBy;
- }
- String where = null;
- String whereArgs[] = null;
- if (mCurQuery != null) {
- where = UserIds.USER_ID + " LIKE ?";
- whereArgs = new String[]{"%" + mCurQuery + "%"};
- }
-
- // Now create and return a CursorLoader that will take care of
- // creating a Cursor for the data being displayed.
- return new CursorLoader(getActivity(), baseUri, projection, where, whereArgs, orderBy);
- }
-
- @Override
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- // Swap the new cursor in. (The framework will take care of closing the
- // old cursor once we return.)
- mAdapter.setSearchQuery(mCurQuery);
- mAdapter.swapCursor(data);
-
- // The list should now be shown.
- if (isResumed()) {
- setListShown(true);
- } else {
- setListShownNoAnimation(true);
- }
-
- // preselect given master keys
- preselectMasterKeyIds(mSelectedMasterKeyIds);
- }
-
- @Override
- public void onLoaderReset(Loader<Cursor> loader) {
- // This is called when the last Cursor provided to onLoadFinished()
- // above is about to be closed. We need to make sure we are no
- // longer using it.
- mAdapter.swapCursor(null);
- }
-
- @Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
-
- }
-
- @Override
- public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
-
- }
-
- @Override
- public void afterTextChanged(Editable editable) {
- mCurQuery = !TextUtils.isEmpty(editable.toString()) ? editable.toString() : null;
- getLoaderManager().restartLoader(0, null, this);
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java
deleted file mode 100644
index 0ff88d97c..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyActivity.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
-
-import org.sufficientlysecure.keychain.R;
-
-public class SelectSecretKeyActivity extends ActionBarActivity {
-
- public static final String EXTRA_FILTER_CERTIFY = "filter_certify";
-
- public static final String RESULT_EXTRA_MASTER_KEY_ID = "master_key_id";
-
- private boolean mFilterCertify;
- private SelectSecretKeyFragment mSelectFragment;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.select_secret_key_activity);
-
- final ActionBar actionBar = getSupportActionBar();
- actionBar.setDisplayShowTitleEnabled(true);
- actionBar.setDisplayHomeAsUpEnabled(false);
- actionBar.setHomeButtonEnabled(false);
-
- mFilterCertify = getIntent().getBooleanExtra(EXTRA_FILTER_CERTIFY, false);
-
- // Check that the activity is using the layout version with
- // the fragment_container FrameLayout
- if (findViewById(R.id.select_secret_key_fragment_container) != null) {
-
- // However, if we're being restored from a previous state,
- // then we don't need to do anything and should return or else
- // we could end up with overlapping fragments.
- if (savedInstanceState != null) {
- return;
- }
-
- // Create an instance of the fragment
- mSelectFragment = SelectSecretKeyFragment.newInstance(mFilterCertify);
-
- // Add the fragment to the 'fragment_container' FrameLayout
- getSupportFragmentManager().beginTransaction()
- .add(R.id.select_secret_key_fragment_container, mSelectFragment).commit();
- }
- }
-
- /**
- * This is executed by SelectSecretKeyFragment after clicking on an item
- *
- * @param selectedUri
- */
- public void afterListSelection(Uri selectedUri) {
- Intent data = new Intent();
- data.setData(selectedUri);
-
- setResult(RESULT_OK, data);
- finish();
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java
deleted file mode 100644
index 9987facbc..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.ListFragment;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.CursorLoader;
-import android.support.v4.content.Loader;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ListView;
-
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
-import org.sufficientlysecure.keychain.provider.KeychainDatabase;
-import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
-import org.sufficientlysecure.keychain.ui.adapter.SelectKeyCursorAdapter;
-
-import java.util.Date;
-
-public class SelectSecretKeyFragment extends ListFragment implements
- LoaderManager.LoaderCallbacks<Cursor> {
-
- private SelectSecretKeyActivity mActivity;
- private SelectKeyCursorAdapter mAdapter;
- private ListView mListView;
-
- private boolean mFilterCertify;
-
- private static final String ARG_FILTER_CERTIFY = "filter_certify";
-
- /**
- * Creates new instance of this fragment
- */
- public static SelectSecretKeyFragment newInstance(boolean filterCertify) {
- SelectSecretKeyFragment frag = new SelectSecretKeyFragment();
-
- Bundle args = new Bundle();
- args.putBoolean(ARG_FILTER_CERTIFY, filterCertify);
- frag.setArguments(args);
-
- return frag;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- mFilterCertify = getArguments().getBoolean(ARG_FILTER_CERTIFY);
- }
-
- /**
- * Define Adapter and Loader on create of Activity
- */
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- mActivity = (SelectSecretKeyActivity) getActivity();
- mListView = getListView();
-
- mListView.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
- long masterKeyId = mAdapter.getMasterKeyId(position);
- Uri result = KeyRings.buildGenericKeyRingUri(String.valueOf(masterKeyId));
-
- // return data to activity, which results in finishing it
- mActivity.afterListSelection(result);
- }
- });
-
- // Give some text to display if there is no data. In a real
- // application this would come from a resource.
- setEmptyText(getString(R.string.list_empty));
-
- mAdapter = new SelectKeyCursorAdapter(mActivity, null, 0, mListView, Id.type.secret_key);
-
- setListAdapter(mAdapter);
-
- // Start out with a progress indicator.
- setListShown(false);
-
- // Prepare the loader. Either re-connect with an existing one,
- // or start a new one.
- getLoaderManager().initLoader(0, null, this);
- }
-
- @Override
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- // This is called when a new Loader needs to be created. This
- // sample only has one Loader, so we don't care about the ID.
- Uri baseUri = KeyRings.buildUnifiedKeyRingsUri();
-
- // These are the rows that we will retrieve.
- long now = new Date().getTime() / 1000;
- String[] projection = new String[]{
- KeyRings._ID,
- KeyRings.MASTER_KEY_ID,
- UserIds.USER_ID,
- "(SELECT COUNT(*) FROM " + Tables.KEYS + " AS k"
- + " WHERE k." + Keys.MASTER_KEY_ID + " = "
- + KeychainDatabase.Tables.KEYS + "." + KeyRings.MASTER_KEY_ID
- + " AND k." + Keys.CAN_CERTIFY + " = '1'"
- + ") AS cert",
- "(SELECT COUNT(*) FROM " + Tables.KEYS + " AS k"
- +" WHERE k." + Keys.MASTER_KEY_ID + " = "
- + KeychainDatabase.Tables.KEYS + "." + Keys.MASTER_KEY_ID
- + " AND k." + Keys.IS_REVOKED + " = '0'"
- + " AND k." + Keys.CAN_SIGN + " = '1'"
- + ") AS " + SelectKeyCursorAdapter.PROJECTION_ROW_AVAILABLE,
- "(SELECT COUNT(*) FROM " + Tables.KEYS + " AS k"
- + " WHERE k." + Keys.MASTER_KEY_ID + " = "
- + KeychainDatabase.Tables.KEYS + "." + Keys.MASTER_KEY_ID
- + " AND k." + Keys.IS_REVOKED + " = '0'"
- + " AND k." + Keys.CAN_SIGN + " = '1'"
- + " AND k." + Keys.CREATION + " <= '" + now + "'"
- + " AND ( k." + Keys.EXPIRY + " IS NULL OR k." + Keys.EXPIRY + " >= '" + now + "' )"
- + ") AS " + SelectKeyCursorAdapter.PROJECTION_ROW_VALID, };
-
- String orderBy = UserIds.USER_ID + " ASC";
-
- String where = Tables.KEY_RINGS_SECRET + "." + KeyRings.MASTER_KEY_ID + " IS NOT NULL";
- if (mFilterCertify) {
- where += " AND (cert > 0)";
- }
-
- // Now create and return a CursorLoader that will take care of
- // creating a Cursor for the data being displayed.
- return new CursorLoader(getActivity(), baseUri, projection, where, null, orderBy);
- }
-
- @Override
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- // Swap the new cursor in. (The framework will take care of closing the
- // old cursor once we return.)
- mAdapter.swapCursor(data);
-
- // The list should now be shown.
- if (isResumed()) {
- setListShown(true);
- } else {
- setListShownNoAnimation(true);
- }
- }
-
- @Override
- public void onLoaderReset(Loader<Cursor> loader) {
- // This is called when the last Cursor provided to onLoadFinished()
- // above is about to be closed. We need to make sure we are no
- // longer using it.
- mAdapter.swapCursor(null);
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java
deleted file mode 100644
index 514951385..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.CursorLoader;
-import android.support.v4.content.Loader;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import com.beardedhen.androidbootstrap.BootstrapButton;
-
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-
-public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
-
- private TextView mKeyUserId;
- private TextView mKeyUserIdRest;
- private TextView mKeyMasterKeyIdHex;
- private TextView mNoKeySelected;
- private BootstrapButton mSelectKeyButton;
- private Boolean mFilterCertify;
-
- private Uri mReceivedUri = null;
-
- private SelectSecretKeyCallback mCallback;
-
- private static final int REQUEST_CODE_SELECT_KEY = 8882;
-
- private static final int LOADER_ID = 0;
-
- //The Projection we will retrieve, Master Key ID is for convenience sake,
- //to avoid having to pass the Key Around
- final String[] PROJECTION = new String[] {
- KeychainContract.Keys.MASTER_KEY_ID,
- KeychainContract.UserIds.USER_ID
- };
- final int INDEX_MASTER_KEY_ID = 0;
- final int INDEX_USER_ID = 1;
-
- public interface SelectSecretKeyCallback {
- void onKeySelected(long secretKeyId);
- }
-
- public void setCallback(SelectSecretKeyCallback callback) {
- mCallback = callback;
- }
-
- public void setFilterCertify(Boolean filterCertify) {
- mFilterCertify = filterCertify;
- }
-
- public void setNoKeySelected() {
- mNoKeySelected.setVisibility(View.VISIBLE);
- mKeyUserId.setVisibility(View.GONE);
- mKeyUserIdRest.setVisibility(View.GONE);
- mKeyMasterKeyIdHex.setVisibility(View.GONE);
- }
-
- public void setSelectedKeyData(String userName, String email, String masterKeyHex) {
-
- mNoKeySelected.setVisibility(View.GONE);
-
- mKeyUserId.setText(userName);
- mKeyUserIdRest.setText(email);
- mKeyMasterKeyIdHex.setText(masterKeyHex);
-
- mKeyUserId.setVisibility(View.VISIBLE);
- mKeyUserIdRest.setVisibility(View.VISIBLE);
- mKeyMasterKeyIdHex.setVisibility(View.VISIBLE);
-
- }
-
- public void setError(String error) {
- mNoKeySelected.requestFocus();
- mNoKeySelected.setError(error);
- }
-
- /**
- * Inflate the layout for this fragment
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.select_secret_key_layout_fragment, container, false);
-
- mNoKeySelected = (TextView) view.findViewById(R.id.no_key_selected);
- mKeyUserId = (TextView) view.findViewById(R.id.select_secret_key_user_id);
- mKeyUserIdRest = (TextView) view.findViewById(R.id.select_secret_key_user_id_rest);
- mKeyMasterKeyIdHex = (TextView) view.findViewById(R.id.select_secret_key_master_key_hex);
- mSelectKeyButton = (BootstrapButton) view
- .findViewById(R.id.select_secret_key_select_key_button);
- mFilterCertify = false;
- mSelectKeyButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- startSelectKeyActivity();
- }
- });
-
- return view;
- }
-
- //For AppSettingsFragment
- public void selectKey(long masterKeyId) {
- Uri buildUri = KeychainContract.KeyRings.buildGenericKeyRingUri(String.valueOf(masterKeyId));
- mReceivedUri = buildUri;
- getActivity().getSupportLoaderManager().restartLoader(LOADER_ID, null, this);
- }
-
- private void startSelectKeyActivity() {
- Intent intent = new Intent(getActivity(), SelectSecretKeyActivity.class);
- intent.putExtra(SelectSecretKeyActivity.EXTRA_FILTER_CERTIFY, mFilterCertify);
- startActivityForResult(intent, REQUEST_CODE_SELECT_KEY);
- }
-
- @Override
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- Uri uri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(mReceivedUri);
- //We don't care about the Loader id
- return new CursorLoader(getActivity(), uri, PROJECTION, null, null, null);
- }
-
- @Override
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- if (data.moveToFirst()) {
- String userName, email, masterKeyHex;
- String userID = data.getString(INDEX_USER_ID);
- long masterKeyID = data.getLong(INDEX_MASTER_KEY_ID);
-
- String splitUserID[] = PgpKeyHelper.splitUserId(userID);
-
- if (splitUserID[0] != null) {
- userName = splitUserID[0];
- } else {
- userName = getActivity().getResources().getString(R.string.user_id_no_name);
- }
-
- if (splitUserID[1] != null) {
- email = splitUserID[1];
- } else {
- email = getActivity().getResources().getString(R.string.error_user_id_no_email);
- }
-
- //TODO Can the cursor return invalid values for the Master Key ?
- masterKeyHex = PgpKeyHelper.convertKeyIdToHexShort(masterKeyID);
-
- //Set the data
- setSelectedKeyData(userName, email, masterKeyHex);
-
- //Give value to the callback
- mCallback.onKeySelected(masterKeyID);
- } else {
- //Set The empty View
- setNoKeySelected();
- }
-
- }
-
- @Override
- public void onLoaderReset(Loader<Cursor> loader) {
- return;
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case REQUEST_CODE_SELECT_KEY: {
- if (resultCode == Activity.RESULT_OK) {
- mReceivedUri = data.getData();
-
- //Must be restartLoader() or the data will not be updated on selecting a new key
- getActivity().getSupportLoaderManager().restartLoader(0, null, this);
-
- mKeyUserId.setError(null);
- }
- break;
- }
-
- default:
- super.onActivityResult(requestCode, resultCode, data);
-
- break;
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
deleted file mode 100644
index 0e231e6a8..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2011 Senecaso
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.app.ProgressDialog;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Message;
-import android.os.Messenger;
-import android.support.v7.app.ActionBarActivity;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.ArrayAdapter;
-import android.widget.Spinner;
-import android.widget.Toast;
-import com.beardedhen.androidbootstrap.BootstrapButton;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.Preferences;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.util.Log;
-
-/**
- * Sends the selected public key to a keyserver
- */
-public class UploadKeyActivity extends ActionBarActivity {
- private BootstrapButton mUploadButton;
- private Spinner mKeyServerSpinner;
-
- private Uri mDataUri;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.key_server_export);
-
- mUploadButton = (BootstrapButton) findViewById(R.id.btn_export_to_server);
- mKeyServerSpinner = (Spinner) findViewById(R.id.sign_key_keyserver);
-
- ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
- android.R.layout.simple_spinner_item, Preferences.getPreferences(this)
- .getKeyServers());
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- mKeyServerSpinner.setAdapter(adapter);
- if (adapter.getCount() > 0) {
- mKeyServerSpinner.setSelection(0);
- } else {
- mUploadButton.setEnabled(false);
- }
-
- mUploadButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- uploadKey();
- }
- });
-
- mDataUri = getIntent().getData();
- if (mDataUri == null) {
- Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!");
- finish();
- return;
- }
- }
-
- private void uploadKey() {
- // Send all information needed to service to upload key in other thread
- Intent intent = new Intent(this, KeychainIntentService.class);
-
- intent.setAction(KeychainIntentService.ACTION_UPLOAD_KEYRING);
-
- // set data uri as path to keyring
- intent.setData(mDataUri);
-
- // fill values for this action
- Bundle data = new Bundle();
-
- String server = (String) mKeyServerSpinner.getSelectedItem();
- data.putString(KeychainIntentService.UPLOAD_KEY_SERVER, server);
-
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
-
- // Message is received after uploading is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL) {
- public void handleMessage(Message message) {
- // handle messages by standard KeychainIntentServiceHandler first
- super.handleMessage(message);
-
- if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
-
- Toast.makeText(UploadKeyActivity.this, R.string.key_send_success,
- Toast.LENGTH_SHORT).show();
- finish();
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
-
- // show progress dialog
- saveHandler.showProgressDialog(this);
-
- // start service with intent
- startService(intent);
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java
deleted file mode 100644
index 294fadab2..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.CursorLoader;
-import android.support.v4.content.Loader;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
-import android.text.format.DateFormat;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.TextView;
-
-import org.spongycastle.bcpg.SignatureSubpacket;
-import org.spongycastle.bcpg.SignatureSubpacketTags;
-import org.spongycastle.bcpg.sig.RevocationReason;
-import org.spongycastle.openpgp.PGPException;
-import org.spongycastle.openpgp.PGPKeyRing;
-import org.spongycastle.openpgp.PGPSignature;
-import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.security.SignatureException;
-import java.util.Date;
-
-public class ViewCertActivity extends ActionBarActivity
- implements LoaderManager.LoaderCallbacks<Cursor> {
-
- // These are the rows that we will retrieve.
- static final String[] PROJECTION = new String[]{
- Certs.MASTER_KEY_ID,
- Certs.USER_ID,
- Certs.TYPE,
- Certs.CREATION,
- Certs.KEY_ID_CERTIFIER,
- Certs.SIGNER_UID,
- Certs.DATA,
- };
- private static final int INDEX_MASTER_KEY_ID = 0;
- private static final int INDEX_USER_ID = 1;
- private static final int INDEX_TYPE = 2;
- private static final int INDEX_CREATION = 3;
- private static final int INDEX_KEY_ID_CERTIFIER = 4;
- private static final int INDEX_SIGNER_UID = 5;
- private static final int INDEX_DATA = 6;
-
- private Uri mDataUri;
-
- private long mSignerKeyId;
-
- private TextView mSigneeKey, mSigneeUid, mAlgorithm, mType, mRReason, mCreation;
- private TextView mSignerKey, mSignerUid, mStatus;
- private View mRowReason;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- ActionBar actionBar = getSupportActionBar();
- actionBar.setDisplayHomeAsUpEnabled(true);
-
- setContentView(R.layout.view_cert_activity);
-
- mStatus = (TextView) findViewById(R.id.status);
- mSigneeKey = (TextView) findViewById(R.id.signee_key);
- mSigneeUid = (TextView) findViewById(R.id.signee_uid);
- mAlgorithm = (TextView) findViewById(R.id.algorithm);
- mType = (TextView) findViewById(R.id.signature_type);
- mRReason = (TextView) findViewById(R.id.reason);
- mCreation = (TextView) findViewById(R.id.creation);
-
- mSignerKey = (TextView) findViewById(R.id.signer_key_id);
- mSignerUid = (TextView) findViewById(R.id.signer_uid);
-
- mRowReason = findViewById(R.id.row_reason);
-
- mDataUri = getIntent().getData();
- if (mDataUri == null) {
- Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!");
- finish();
- return;
- }
-
- getSupportLoaderManager().initLoader(0, null, this);
- }
-
- @Override
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- // Now create and return a CursorLoader that will take care of
- // creating a Cursor for the data being displayed.
- return new CursorLoader(this, mDataUri, PROJECTION, null, null, null);
- }
-
- @Override
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- if (data.moveToFirst()) {
- String signeeKey = "0x" + PgpKeyHelper.convertKeyIdToHex(data.getLong(INDEX_MASTER_KEY_ID));
- mSigneeKey.setText(signeeKey);
-
- String signeeUid = data.getString(INDEX_USER_ID);
- mSigneeUid.setText(signeeUid);
-
- Date creationDate = new Date(data.getLong(INDEX_CREATION) * 1000);
- mCreation.setText(DateFormat.getDateFormat(getApplicationContext()).format(creationDate));
-
- mSignerKeyId = data.getLong(INDEX_KEY_ID_CERTIFIER);
- String signerKey = "0x" + PgpKeyHelper.convertKeyIdToHex(mSignerKeyId);
- mSignerKey.setText(signerKey);
-
- String signerUid = data.getString(INDEX_SIGNER_UID);
- if (signerUid != null) {
- mSignerUid.setText(signerUid);
- } else {
- mSignerUid.setText(R.string.unknown_uid);
- }
-
- PGPSignature sig = PgpConversionHelper.BytesToPGPSignature(data.getBlob(INDEX_DATA));
- PGPKeyRing signeeRing = ProviderHelper.getPGPKeyRing(this,
- KeychainContract.KeyRingData.buildPublicKeyRingUri(
- Long.toString(data.getLong(INDEX_MASTER_KEY_ID))));
- PGPKeyRing signerRing = ProviderHelper.getPGPKeyRing(this,
- KeychainContract.KeyRingData.buildPublicKeyRingUri(
- Long.toString(sig.getKeyID())));
-
- if (signerRing != null) {
- try {
- sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider(
- Constants.BOUNCY_CASTLE_PROVIDER_NAME), signeeRing.getPublicKey());
- if (sig.verifyCertification(signeeUid, signerRing.getPublicKey())) {
- mStatus.setText("ok");
- mStatus.setTextColor(getResources().getColor(R.color.bbutton_success));
- } else {
- mStatus.setText("failed!");
- mStatus.setTextColor(getResources().getColor(R.color.alert));
- }
- } catch (SignatureException e) {
- mStatus.setText("error!");
- mStatus.setTextColor(getResources().getColor(R.color.alert));
- } catch (PGPException e) {
- mStatus.setText("error!");
- mStatus.setTextColor(getResources().getColor(R.color.alert));
- }
- } else {
- mStatus.setText("key unavailable");
- mStatus.setTextColor(getResources().getColor(R.color.black));
- }
-
- String algorithmStr = PgpKeyHelper.getAlgorithmInfo(sig.getKeyAlgorithm(), 0);
- mAlgorithm.setText(algorithmStr);
-
- mRowReason.setVisibility(View.GONE);
- switch (data.getInt(INDEX_TYPE)) {
- case PGPSignature.DEFAULT_CERTIFICATION:
- mType.setText(R.string.cert_default);
- break;
- case PGPSignature.NO_CERTIFICATION:
- mType.setText(R.string.cert_none);
- break;
- case PGPSignature.CASUAL_CERTIFICATION:
- mType.setText(R.string.cert_casual);
- break;
- case PGPSignature.POSITIVE_CERTIFICATION:
- mType.setText(R.string.cert_positive);
- break;
- case PGPSignature.CERTIFICATION_REVOCATION: {
- mType.setText(R.string.cert_revoke);
- if (sig.getHashedSubPackets().hasSubpacket(SignatureSubpacketTags.REVOCATION_REASON)) {
- SignatureSubpacket p = sig.getHashedSubPackets().getSubpacket(
- SignatureSubpacketTags.REVOCATION_REASON);
- // For some reason, this is missing in SignatureSubpacketInputStream:146
- if (!(p instanceof RevocationReason)) {
- p = new RevocationReason(false, p.getData());
- }
- String reason = ((RevocationReason) p).getRevocationDescription();
- mRReason.setText(reason);
- mRowReason.setVisibility(View.VISIBLE);
- }
- break;
- }
- }
- }
- }
-
- @Override
- public void onLoaderReset(Loader<Cursor> loader) {
- }
-
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- super.onCreateOptionsMenu(menu);
- getMenuInflater().inflate(R.menu.view_cert, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.menu_view_cert_view_signer:
- // can't do this before the data is initialized
- Intent viewIntent = null;
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
- viewIntent = new Intent(this, ViewKeyActivity.class);
- } else {
- viewIntent = new Intent(this, ViewKeyActivityJB.class);
- }
- //
- long signerMasterKeyId = ProviderHelper.getMasterKeyId(this,
- KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(mSignerKeyId))
- );
- // TODO notify user of this, maybe offer download?
- if (mSignerKeyId == 0L)
- return true;
- viewIntent.setData(KeyRings.buildGenericKeyRingUri(
- Long.toString(signerMasterKeyId))
- );
- startActivity(viewIntent);
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
deleted file mode 100644
index cce34139c..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2013 Bahtiar 'kalkin' Gadimov
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.support.v4.view.ViewPager;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.Window;
-import android.widget.Toast;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
-import org.sufficientlysecure.keychain.helper.ExportHelper;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.ui.adapter.TabsAdapter;
-import org.sufficientlysecure.keychain.ui.dialog.ShareNfcDialogFragment;
-import org.sufficientlysecure.keychain.ui.dialog.ShareQrCodeDialogFragment;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-public class ViewKeyActivity extends ActionBarActivity {
-
- ExportHelper mExportHelper;
-
- protected Uri mDataUri;
-
- public static final String EXTRA_SELECTED_TAB = "selectedTab";
-
- ViewPager mViewPager;
- TabsAdapter mTabsAdapter;
-
- private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
- super.onCreate(savedInstanceState);
-
- mExportHelper = new ExportHelper(this);
-
- // let the actionbar look like Android's contact app
- ActionBar actionBar = getSupportActionBar();
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setIcon(android.R.color.transparent);
- actionBar.setHomeButtonEnabled(true);
- actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
-
- setContentView(R.layout.view_key_activity);
-
- mViewPager = (ViewPager) findViewById(R.id.pager);
-
- mTabsAdapter = new TabsAdapter(this, mViewPager);
-
- int selectedTab = 0;
- Intent intent = getIntent();
- if (intent.getExtras() != null && intent.getExtras().containsKey(EXTRA_SELECTED_TAB)) {
- selectedTab = intent.getExtras().getInt(EXTRA_SELECTED_TAB);
- }
-
- mDataUri = getIntent().getData();
-
- Bundle mainBundle = new Bundle();
- mainBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, mDataUri);
- mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.key_view_tab_main)),
- ViewKeyMainFragment.class, mainBundle, (selectedTab == 0));
-
- Bundle certBundle = new Bundle();
- certBundle.putParcelable(ViewKeyCertsFragment.ARG_DATA_URI, mDataUri);
- mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.key_view_tab_certs)),
- ViewKeyCertsFragment.class, certBundle, (selectedTab == 1));
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- super.onCreateOptionsMenu(menu);
- getMenuInflater().inflate(R.menu.key_view, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- Intent homeIntent = new Intent(this, KeyListActivity.class);
- homeIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(homeIntent);
- return true;
- case R.id.menu_key_view_update:
- updateFromKeyserver(mDataUri);
- return true;
- case R.id.menu_key_view_export_keyserver:
- uploadToKeyserver(mDataUri);
- return true;
- case R.id.menu_key_view_export_file:
- exportToFile(mDataUri);
- return true;
- case R.id.menu_key_view_share_default_fingerprint:
- shareKey(mDataUri, true);
- return true;
- case R.id.menu_key_view_share_default:
- shareKey(mDataUri, false);
- return true;
- case R.id.menu_key_view_share_qr_code_fingerprint:
- shareKeyQrCode(mDataUri, true);
- return true;
- case R.id.menu_key_view_share_qr_code:
- shareKeyQrCode(mDataUri, false);
- return true;
- case R.id.menu_key_view_share_nfc:
- shareNfc();
- return true;
- case R.id.menu_key_view_share_clipboard:
- copyToClipboard(mDataUri);
- return true;
- case R.id.menu_key_view_delete: {
- deleteKey(mDataUri);
- return true;
- }
- }
- return super.onOptionsItemSelected(item);
- }
-
- private void exportToFile(Uri dataUri) {
- Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri);
-
- HashMap<String, Object> data = ProviderHelper.getGenericData(this,
- baseUri,
- new String[]{KeychainContract.Keys.MASTER_KEY_ID, KeychainContract.KeyRings.HAS_SECRET},
- new int[]{ProviderHelper.FIELD_TYPE_INTEGER, ProviderHelper.FIELD_TYPE_INTEGER});
-
- mExportHelper.showExportKeysDialog(
- new long[]{(Long) data.get(KeychainContract.KeyRings.MASTER_KEY_ID)},
- Constants.Path.APP_DIR_FILE,
- ((Long) data.get(KeychainContract.KeyRings.HAS_SECRET) == 1)
- );
- }
-
- private void uploadToKeyserver(Uri dataUri) {
- Intent uploadIntent = new Intent(this, UploadKeyActivity.class);
- uploadIntent.setData(dataUri);
- startActivityForResult(uploadIntent, Id.request.export_to_server);
- }
-
- private void updateFromKeyserver(Uri dataUri) {
- byte[] blob = (byte[]) ProviderHelper.getGenericData(
- this, KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri),
- KeychainContract.Keys.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB);
- String fingerprint = PgpKeyHelper.convertFingerprintToHex(blob);
-
- Intent queryIntent = new Intent(this, ImportKeysActivity.class);
- queryIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN);
- queryIntent.putExtra(ImportKeysActivity.EXTRA_FINGERPRINT, fingerprint);
-
- startActivityForResult(queryIntent, RESULT_CODE_LOOKUP_KEY);
- }
-
- private void shareKey(Uri dataUri, boolean fingerprintOnly) {
- String content;
- if (fingerprintOnly) {
- byte[] data = (byte[]) ProviderHelper.getGenericData(
- this, KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri),
- KeychainContract.Keys.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB);
- if (data != null) {
- String fingerprint = PgpKeyHelper.convertFingerprintToHex(data);
- content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
- } else {
- Toast.makeText(getApplicationContext(), "Bad key selected!",
- Toast.LENGTH_LONG).show();
- return;
- }
- } else {
- // get public keyring as ascii armored string
- long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri);
- ArrayList<String> keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(
- this, new long[]{masterKeyId});
-
- content = keyringArmored.get(0);
-
- // Android will fail with android.os.TransactionTooLargeException if key is too big
- // see http://www.lonestarprod.com/?p=34
- if (content.length() >= 86389) {
- Toast.makeText(getApplicationContext(), R.string.key_too_big_for_sharing,
- Toast.LENGTH_LONG).show();
- return;
- }
- }
-
- // let user choose application
- Intent sendIntent = new Intent(Intent.ACTION_SEND);
- sendIntent.putExtra(Intent.EXTRA_TEXT, content);
- sendIntent.setType("text/plain");
- startActivity(Intent.createChooser(sendIntent,
- getResources().getText(R.string.action_share_key_with)));
- }
-
- private void shareKeyQrCode(Uri dataUri, boolean fingerprintOnly) {
- ShareQrCodeDialogFragment dialog = ShareQrCodeDialogFragment.newInstance(dataUri,
- fingerprintOnly);
- dialog.show(getSupportFragmentManager(), "shareQrCodeDialog");
- }
-
- private void copyToClipboard(Uri dataUri) {
- // get public keyring as ascii armored string
- long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri);
- ArrayList<String> keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(
- this, new long[]{masterKeyId});
-
- ClipboardReflection.copyToClipboard(this, keyringArmored.get(0));
- Toast.makeText(getApplicationContext(), R.string.key_copied_to_clipboard, Toast.LENGTH_LONG)
- .show();
- }
-
- private void shareNfc() {
- ShareNfcDialogFragment dialog = ShareNfcDialogFragment.newInstance();
- dialog.show(getSupportFragmentManager(), "shareNfcDialog");
- }
-
- private void deleteKey(Uri dataUri) {
- // Message is received after key is deleted
- Handler returnHandler = new Handler() {
- @Override
- public void handleMessage(Message message) {
- setResult(RESULT_CANCELED);
- finish();
- }
- };
-
- mExportHelper.deleteKey(dataUri, returnHandler);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case RESULT_CODE_LOOKUP_KEY: {
- if (resultCode == Activity.RESULT_OK) {
- // TODO: reload key??? move this into fragment?
- }
- break;
- }
-
- default: {
- super.onActivityResult(requestCode, resultCode, data);
-
- break;
- }
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java
deleted file mode 100644
index 6dc0413bb..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.annotation.TargetApi;
-import android.nfc.NdefMessage;
-import android.nfc.NdefRecord;
-import android.nfc.NfcAdapter;
-import android.nfc.NfcAdapter.CreateNdefMessageCallback;
-import android.nfc.NfcAdapter.OnNdefPushCompleteCallback;
-import android.nfc.NfcEvent;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.widget.Toast;
-
-import com.devspark.appmsg.AppMsg;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.io.IOException;
-
-@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
-public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMessageCallback,
- OnNdefPushCompleteCallback {
-
- private NfcAdapter mNfcAdapter;
- private byte[] mSharedKeyringBytes;
- private static final int NFC_SENT = 1;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- initNfc();
- }
-
- /**
- * NFC: Initialize NFC sharing if OS and device supports it
- */
- private void initNfc() {
- // check if NFC Beam is supported (>= Android 4.1)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- // Check for available NFC Adapter
- mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
- if (mNfcAdapter != null) {
- // init nfc
- // Register callback to set NDEF message
- mNfcAdapter.setNdefPushMessageCallback(this, this);
- // Register callback to listen for message-sent success
- mNfcAdapter.setOnNdefPushCompleteCallback(this, this);
- }
- }
- }
-
- /**
- * NFC: Implementation for the CreateNdefMessageCallback interface
- */
- @Override
- public NdefMessage createNdefMessage(NfcEvent event) {
- /**
- * When a device receives a push with an AAR in it, the application specified in the AAR is
- * guaranteed to run. The AAR overrides the tag dispatch system. You can add it back in to
- * guarantee that this activity starts when receiving a beamed message. For now, this code
- * uses the tag dispatch system.
- */
- try {
- // get public keyring as byte array
- mSharedKeyringBytes = ProviderHelper.getPGPKeyRing(this, mDataUri).getEncoded();
-
- NdefMessage msg = new NdefMessage(NdefRecord.createMime(Constants.NFC_MIME,
- mSharedKeyringBytes), NdefRecord.createApplicationRecord(Constants.PACKAGE_NAME));
- return msg;
- } catch(IOException e) {
- Log.e(Constants.TAG, "Error parsing keyring", e);
- return null;
- }
- }
-
- /**
- * NFC: Implementation for the OnNdefPushCompleteCallback interface
- */
- @Override
- public void onNdefPushComplete(NfcEvent arg0) {
- // A handler is needed to send messages to the activity when this
- // callback occurs, because it happens from a binder thread
- mNfcHandler.obtainMessage(NFC_SENT).sendToTarget();
- }
-
- /**
- * NFC: This handler receives a message from onNdefPushComplete
- */
- private final Handler mNfcHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case NFC_SENT:
- AppMsg.makeText(ViewKeyActivityJB.this, R.string.nfc_successfull,
- AppMsg.STYLE_INFO).show();
- break;
- }
- }
- };
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java
deleted file mode 100644
index b738970f1..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.CursorLoader;
-import android.support.v4.content.Loader;
-import android.support.v4.widget.CursorAdapter;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.TextView;
-
-import org.spongycastle.openpgp.PGPSignature;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
-import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
-import org.sufficientlysecure.keychain.util.Log;
-
-import se.emilsjolander.stickylistheaders.ApiLevelTooLowException;
-import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
-import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
-
-
-public class ViewKeyCertsFragment extends Fragment
- implements LoaderManager.LoaderCallbacks<Cursor>, AdapterView.OnItemClickListener {
-
- // These are the rows that we will retrieve.
- static final String[] PROJECTION = new String[] {
- Certs._ID,
- Certs.MASTER_KEY_ID,
- Certs.VERIFIED,
- Certs.TYPE,
- Certs.RANK,
- Certs.KEY_ID_CERTIFIER,
- Certs.USER_ID,
- Certs.SIGNER_UID
- };
-
- // sort by our user id,
- static final String SORT_ORDER =
- Tables.CERTS + "." + Certs.RANK + " ASC, "
- + Certs.VERIFIED + " DESC, " + Certs.TYPE + " DESC, " + Certs.SIGNER_UID + " ASC";
-
- public static final String ARG_DATA_URI = "data_uri";
-
- private StickyListHeadersListView mStickyList;
- private CertListAdapter mAdapter;
-
- private Uri mDataUri;
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.view_key_certs_fragment, container, false);
-
- return view;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- mStickyList = (StickyListHeadersListView) getActivity().findViewById(R.id.list);
-
- if (!getArguments().containsKey(ARG_DATA_URI)) {
- Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
- getActivity().finish();
- return;
- }
-
- Uri uri = getArguments().getParcelable(ARG_DATA_URI);
- mDataUri = Certs.buildCertsUri(uri);
-
- mStickyList.setAreHeadersSticky(true);
- mStickyList.setDrawingListUnderStickyHeader(false);
- mStickyList.setFastScrollEnabled(true);
- mStickyList.setOnItemClickListener(this);
-
- try {
- mStickyList.setFastScrollAlwaysVisible(true);
- } catch (ApiLevelTooLowException e) {
- }
-
- mStickyList.setEmptyView(getActivity().findViewById(R.id.empty));
-
- // TODO this view is made visible if no data is available
- // mStickyList.setEmptyView(getActivity().findViewById(R.id.empty));
-
-
- // Create an empty adapter we will use to display the loaded data.
- mAdapter = new CertListAdapter(getActivity(), null);
- mStickyList.setAdapter(mAdapter);
-
- getLoaderManager().initLoader(0, null, this);
- }
-
- @Override
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- // Now create and return a CursorLoader that will take care of
- // creating a Cursor for the data being displayed.
- return new CursorLoader(getActivity(), mDataUri, PROJECTION, null, null, SORT_ORDER);
- }
-
- @Override
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- // Swap the new cursor in. (The framework will take care of closing the
- // old cursor once we return.)
- mAdapter.swapCursor(data);
-
- mStickyList.setAdapter(mAdapter);
- }
-
- /**
- * On click on item, start key view activity
- */
- @Override
- public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
- if(view.getTag(R.id.tag_mki) != null) {
- long masterKeyId = (Long) view.getTag(R.id.tag_mki);
- long rank = (Long) view.getTag(R.id.tag_rank);
- long certifierId = (Long) view.getTag(R.id.tag_certifierId);
-
- Intent viewIntent = new Intent(getActivity(), ViewCertActivity.class);
- viewIntent.setData(Certs.buildCertsSpecificUri(
- Long.toString(masterKeyId), Long.toString(rank), Long.toString(certifierId)));
- startActivity(viewIntent);
- }
- }
-
- @Override
- public void onLoaderReset(Loader<Cursor> loader) {
- // This is called when the last Cursor provided to onLoadFinished()
- // above is about to be closed. We need to make sure we are no
- // longer using it.
- mAdapter.swapCursor(null);
- }
-
- /**
- * Implements StickyListHeadersAdapter from library
- */
- private class CertListAdapter extends CursorAdapter implements StickyListHeadersAdapter {
- private LayoutInflater mInflater;
- private int mIndexMasterKeyId, mIndexUserId, mIndexRank;
- private int mIndexSignerKeyId, mIndexSignerUserId;
- private int mIndexVerified, mIndexType;
-
- public CertListAdapter(Context context, Cursor c) {
- super(context, c, 0);
-
- mInflater = LayoutInflater.from(context);
- initIndex(c);
- }
-
- @Override
- public Cursor swapCursor(Cursor newCursor) {
- initIndex(newCursor);
-
- return super.swapCursor(newCursor);
- }
-
- /**
- * Get column indexes for performance reasons just once in constructor and swapCursor. For a
- * performance comparison see http://stackoverflow.com/a/17999582
- *
- * @param cursor
- */
- private void initIndex(Cursor cursor) {
- if (cursor != null) {
- mIndexMasterKeyId = cursor.getColumnIndexOrThrow(Certs.MASTER_KEY_ID);
- mIndexUserId = cursor.getColumnIndexOrThrow(Certs.USER_ID);
- mIndexRank = cursor.getColumnIndexOrThrow(Certs.RANK);
- mIndexType = cursor.getColumnIndexOrThrow(Certs.TYPE);
- mIndexVerified = cursor.getColumnIndexOrThrow(Certs.VERIFIED);
- mIndexSignerKeyId = cursor.getColumnIndexOrThrow(Certs.KEY_ID_CERTIFIER);
- mIndexSignerUserId = cursor.getColumnIndexOrThrow(Certs.SIGNER_UID);
- }
- }
-
- /**
- * Bind cursor data to the item list view
- * <p/>
- * NOTE: CursorAdapter already implements the ViewHolder pattern in its getView() method.
- * Thus no ViewHolder is required here.
- */
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
-
- // set name and stuff, common to both key types
- TextView wSignerKeyId = (TextView) view.findViewById(R.id.signerKeyId);
- TextView wSignerUserId = (TextView) view.findViewById(R.id.signerUserId);
- TextView wSignStatus = (TextView) view.findViewById(R.id.signStatus);
-
- String signerKeyId = PgpKeyHelper.convertKeyIdToHex(cursor.getLong(mIndexSignerKeyId));
- String signerUserId = cursor.getString(mIndexSignerUserId);
- switch(cursor.getInt(mIndexType)) {
- case PGPSignature.DEFAULT_CERTIFICATION: // 0x10
- wSignStatus.setText(R.string.cert_default); break;
- case PGPSignature.NO_CERTIFICATION: // 0x11
- wSignStatus.setText(R.string.cert_none); break;
- case PGPSignature.CASUAL_CERTIFICATION: // 0x12
- wSignStatus.setText(R.string.cert_casual); break;
- case PGPSignature.POSITIVE_CERTIFICATION: // 0x13
- wSignStatus.setText(R.string.cert_positive); break;
- case PGPSignature.CERTIFICATION_REVOCATION: // 0x30
- wSignStatus.setText(R.string.cert_revoke); break;
- }
-
- wSignerUserId.setText(signerUserId);
- wSignerKeyId.setText(signerKeyId);
-
- view.setTag(R.id.tag_mki, cursor.getLong(mIndexMasterKeyId));
- view.setTag(R.id.tag_rank, cursor.getLong(mIndexRank));
- view.setTag(R.id.tag_certifierId, cursor.getLong(mIndexSignerKeyId));
- }
-
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(R.layout.view_key_certs_item, parent, false);
- }
-
- /**
- * Creates a new header view and binds the section headers to it. It uses the ViewHolder
- * pattern. Most functionality is similar to getView() from Android's CursorAdapter.
- * <p/>
- * NOTE: The variables mDataValid and mCursor are available due to the super class
- * CursorAdapter.
- */
- @Override
- public View getHeaderView(int position, View convertView, ViewGroup parent) {
- HeaderViewHolder holder;
- if (convertView == null) {
- holder = new HeaderViewHolder();
- convertView = mInflater.inflate(R.layout.view_key_certs_header, parent, false);
- holder.text = (TextView) convertView.findViewById(R.id.stickylist_header_text);
- holder.count = (TextView) convertView.findViewById(R.id.certs_num);
- convertView.setTag(holder);
- } else {
- holder = (HeaderViewHolder) convertView.getTag();
- }
-
- if (!mDataValid) {
- // no data available at this point
- Log.d(Constants.TAG, "getHeaderView: No data available at this point!");
- return convertView;
- }
-
- if (!mCursor.moveToPosition(position)) {
- throw new IllegalStateException("couldn't move cursor to position " + position);
- }
-
- // set header text as first char in user id
- String userId = mCursor.getString(mIndexUserId);
- holder.text.setText(userId);
- holder.count.setVisibility(View.GONE);
- return convertView;
- }
-
- /**
- * Header IDs should be static, position=1 should always return the same Id that is.
- */
- @Override
- public long getHeaderId(int position) {
- if (!mDataValid) {
- // no data available at this point
- Log.d(Constants.TAG, "getHeaderView: No data available at this point!");
- return -1;
- }
-
- if (!mCursor.moveToPosition(position)) {
- throw new IllegalStateException("couldn't move cursor to position " + position);
- }
-
- // otherwise, return the first character of the name as ID
- return mCursor.getInt(mIndexRank);
-
- // sort by the first four characters (should be enough I guess?)
- // return ByteBuffer.wrap(userId.getBytes()).asLongBuffer().get(0);
- }
-
- class HeaderViewHolder {
- TextView text;
- TextView count;
- }
-
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
deleted file mode 100644
index 6e96a338a..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-import android.content.Intent;
-import android.database.Cursor;
-import android.graphics.Color;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.CursorLoader;
-import android.support.v4.content.Loader;
-import android.text.format.DateFormat;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import com.beardedhen.androidbootstrap.BootstrapButton;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.ui.adapter.ViewKeyKeysAdapter;
-import org.sufficientlysecure.keychain.ui.adapter.ViewKeyUserIdsAdapter;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.util.Date;
-
-
-public class ViewKeyMainFragment extends Fragment implements
- LoaderManager.LoaderCallbacks<Cursor> {
-
- public static final String ARG_DATA_URI = "uri";
-
- private LinearLayout mContainer;
- private TextView mName;
- private TextView mEmail;
- private TextView mComment;
- private TextView mAlgorithm;
- private TextView mKeyId;
- private TextView mExpiry;
- private TextView mCreation;
- private TextView mFingerprint;
- private TextView mSecretKey;
- private BootstrapButton mActionEdit;
- private BootstrapButton mActionEncrypt;
- private BootstrapButton mActionCertify;
-
- private ListView mUserIds;
- private ListView mKeys;
-
- private static final int LOADER_ID_UNIFIED = 0;
- private static final int LOADER_ID_USER_IDS = 1;
- private static final int LOADER_ID_KEYS = 2;
-
- private ViewKeyUserIdsAdapter mUserIdsAdapter;
- private ViewKeyKeysAdapter mKeysAdapter;
-
- private Uri mDataUri;
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.view_key_main_fragment, container, false);
-
- mContainer = (LinearLayout) view.findViewById(R.id.container);
- mName = (TextView) view.findViewById(R.id.name);
- mEmail = (TextView) view.findViewById(R.id.email);
- mComment = (TextView) view.findViewById(R.id.comment);
- mKeyId = (TextView) view.findViewById(R.id.key_id);
- mAlgorithm = (TextView) view.findViewById(R.id.algorithm);
- mCreation = (TextView) view.findViewById(R.id.creation);
- mExpiry = (TextView) view.findViewById(R.id.expiry);
- mFingerprint = (TextView) view.findViewById(R.id.fingerprint);
- mSecretKey = (TextView) view.findViewById(R.id.secret_key);
- mUserIds = (ListView) view.findViewById(R.id.user_ids);
- mKeys = (ListView) view.findViewById(R.id.keys);
- mActionEdit = (BootstrapButton) view.findViewById(R.id.action_edit);
- mActionEncrypt = (BootstrapButton) view.findViewById(R.id.action_encrypt);
- mActionCertify = (BootstrapButton) view.findViewById(R.id.action_certify);
-
- return view;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
- if (dataUri == null) {
- Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
- getActivity().finish();
- return;
- }
-
- loadData(dataUri);
- }
-
- private void loadData(Uri dataUri) {
- if (dataUri.equals(mDataUri)) {
- Log.d(Constants.TAG, "Same URI, no need to load the data again!");
- return;
- }
-
- getActivity().setProgressBarIndeterminateVisibility(Boolean.TRUE);
- mContainer.setVisibility(View.GONE);
-
- mDataUri = dataUri;
-
- Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
-
- mActionEncrypt.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- encryptToContact(mDataUri);
- }
- });
- mActionCertify.setOnClickListener(new View.OnClickListener() {
- public void onClick(View view) {
- certifyKey(mDataUri);
- }
- });
-
- mUserIdsAdapter = new ViewKeyUserIdsAdapter(getActivity(), null, 0);
- mUserIds.setAdapter(mUserIdsAdapter);
-
- mKeysAdapter = new ViewKeyKeysAdapter(getActivity(), null, 0);
- mKeys.setAdapter(mKeysAdapter);
-
- // Prepare the loaders. Either re-connect with an existing ones,
- // or start new ones.
- getActivity().getSupportLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this);
- getActivity().getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
- getActivity().getSupportLoaderManager().initLoader(LOADER_ID_KEYS, null, this);
- }
-
- static final String[] UNIFIED_PROJECTION = new String[] {
- KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.HAS_SECRET,
- KeyRings.USER_ID, KeyRings.FINGERPRINT,
- KeyRings.ALGORITHM, KeyRings.KEY_SIZE, KeyRings.CREATION, KeyRings.EXPIRY,
-
- };
- static final int INDEX_UNIFIED_MKI = 1;
- static final int INDEX_UNIFIED_HAS_SECRET = 2;
- static final int INDEX_UNIFIED_UID = 3;
- static final int INDEX_UNIFIED_FINGERPRINT = 4;
- static final int INDEX_UNIFIED_ALGORITHM = 5;
- static final int INDEX_UNIFIED_KEY_SIZE = 6;
- static final int INDEX_UNIFIED_CREATION = 7;
- static final int INDEX_UNIFIED_EXPIRY = 8;
-
- static final String[] KEYS_PROJECTION = new String[] {
- Keys._ID,
- Keys.KEY_ID, Keys.RANK, Keys.ALGORITHM, Keys.KEY_SIZE,
- Keys.CAN_CERTIFY, Keys.CAN_ENCRYPT, Keys.CAN_SIGN, Keys.IS_REVOKED,
- Keys.CREATION, Keys.EXPIRY, Keys.FINGERPRINT
- };
- static final int KEYS_INDEX_CAN_ENCRYPT = 6;
-
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- switch (id) {
- case LOADER_ID_UNIFIED: {
- Uri baseUri = KeyRings.buildUnifiedKeyRingUri(mDataUri);
- return new CursorLoader(getActivity(), baseUri, UNIFIED_PROJECTION, null, null, null);
- }
- case LOADER_ID_USER_IDS: {
- Uri baseUri = UserIds.buildUserIdsUri(mDataUri);
- return new CursorLoader(getActivity(), baseUri, ViewKeyUserIdsAdapter.USER_IDS_PROJECTION, null, null, null);
- }
- case LOADER_ID_KEYS: {
- Uri baseUri = Keys.buildKeysUri(mDataUri);
- return new CursorLoader(getActivity(), baseUri, KEYS_PROJECTION, null, null, null);
- }
-
- default:
- return null;
- }
- }
-
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- /* TODO better error handling? May cause problems when a key is deleted,
- * because the notification triggers faster than the activity closes.
- */
- // Avoid NullPointerExceptions...
- if(data.getCount() == 0)
- return;
- // Swap the new cursor in. (The framework will take care of closing the
- // old cursor once we return.)
- switch (loader.getId()) {
- case LOADER_ID_UNIFIED: {
- if (data.moveToFirst()) {
- // get name, email, and comment from USER_ID
- String[] mainUserId = PgpKeyHelper.splitUserId(data.getString(INDEX_UNIFIED_UID));
- if (mainUserId[0] != null) {
- getActivity().setTitle(mainUserId[0]);
- mName.setText(mainUserId[0]);
- } else {
- getActivity().setTitle(R.string.user_id_no_name);
- mName.setText(R.string.user_id_no_name);
- }
- mEmail.setText(mainUserId[1]);
- mComment.setText(mainUserId[2]);
-
- if (data.getInt(INDEX_UNIFIED_HAS_SECRET) != 0) {
- mSecretKey.setTextColor(getResources().getColor(R.color.emphasis));
- mSecretKey.setText(R.string.secret_key_yes);
-
- // edit button
- mActionEdit.setVisibility(View.VISIBLE);
- mActionEdit.setOnClickListener(new View.OnClickListener() {
- public void onClick(View view) {
- Intent editIntent = new Intent(getActivity(), EditKeyActivity.class);
- editIntent.setData(mDataUri);
- editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
- startActivityForResult(editIntent, 0);
- }
- });
- } else {
- mSecretKey.setTextColor(Color.BLACK);
- mSecretKey.setText(getResources().getString(R.string.secret_key_no));
-
- // certify button
- mActionCertify.setVisibility(View.VISIBLE);
- // edit button
- mActionEdit.setVisibility(View.GONE);
- }
-
- // get key id from MASTER_KEY_ID
- long masterKeyId = data.getLong(INDEX_UNIFIED_MKI);
- String keyIdStr = PgpKeyHelper.convertKeyIdToHex(masterKeyId);
- mKeyId.setText(keyIdStr);
-
- // get creation date from CREATION
- if (data.isNull(INDEX_UNIFIED_CREATION)) {
- mCreation.setText(R.string.none);
- } else {
- Date creationDate = new Date(data.getLong(INDEX_UNIFIED_CREATION) * 1000);
-
- mCreation.setText(
- DateFormat.getDateFormat(getActivity().getApplicationContext()).format(
- creationDate));
- }
-
- // get expiry date from EXPIRY
- if (data.isNull(INDEX_UNIFIED_EXPIRY)) {
- mExpiry.setText(R.string.none);
- } else {
- Date expiryDate = new Date(data.getLong(INDEX_UNIFIED_EXPIRY) * 1000);
-
- mExpiry.setText(
- DateFormat.getDateFormat(getActivity().getApplicationContext()).format(
- expiryDate));
- }
-
- String algorithmStr = PgpKeyHelper.getAlgorithmInfo(
- data.getInt(INDEX_UNIFIED_ALGORITHM), data.getInt(INDEX_UNIFIED_KEY_SIZE));
- mAlgorithm.setText(algorithmStr);
-
- byte[] fingerprintBlob = data.getBlob(INDEX_UNIFIED_FINGERPRINT);
- String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob);
- mFingerprint.setText(PgpKeyHelper.colorizeFingerprint(fingerprint));
-
- break;
- }
- }
-
- case LOADER_ID_USER_IDS:
- mUserIdsAdapter.swapCursor(data);
- break;
-
- case LOADER_ID_KEYS:
- // hide encrypt button if no encryption key is available
- boolean canEncrypt = false;
- data.moveToFirst();
- do {
- if (data.getInt(KEYS_INDEX_CAN_ENCRYPT) == 1) {
- canEncrypt = true;
- break;
- }
- } while (data.moveToNext());
- if (!canEncrypt) {
- mActionEncrypt.setVisibility(View.GONE);
- }
-
- mKeysAdapter.swapCursor(data);
- break;
- }
- getActivity().setProgressBarIndeterminateVisibility(Boolean.FALSE);
- mContainer.setVisibility(View.VISIBLE);
- }
-
- /**
- * This is called when the last Cursor provided to onLoadFinished() above is about to be closed.
- * We need to make sure we are no longer using it.
- */
- public void onLoaderReset(Loader<Cursor> loader) {
- switch (loader.getId()) {
- case LOADER_ID_USER_IDS:
- mUserIdsAdapter.swapCursor(null);
- break;
- case LOADER_ID_KEYS:
- mKeysAdapter.swapCursor(null);
- break;
- }
- }
-
- private void encryptToContact(Uri dataUri) {
- // TODO preselect from uri? should be feasible without trivial query
- long keyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri);
-
- long[] encryptionKeyIds = new long[]{ keyId };
- Intent intent = new Intent(getActivity(), EncryptActivity.class);
- intent.setAction(EncryptActivity.ACTION_ENCRYPT);
- intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds);
- // used instead of startActivity set actionbar based on callingPackage
- startActivityForResult(intent, 0);
- }
-
- private void certifyKey(Uri dataUri) {
- Intent signIntent = new Intent(getActivity(), CertifyKeyActivity.class);
- signIntent.setData(dataUri);
- startActivity(signIntent);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/AsyncTaskResultWrapper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/AsyncTaskResultWrapper.java
deleted file mode 100644
index 5f2aec4fe..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/AsyncTaskResultWrapper.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.adapter;
-
-/**
- * The AsyncTaskResultWrapper is used to wrap a result from a AsyncTask (for example: Loader).
- * You can pass the result and an exception in it if an error occurred.
- * Concept found at:
- * https://stackoverflow.com/questions/19593577/how-to-handle-errors-in-custom-asynctaskloader
- *
- * @param <T> - Typ of the result which is wrapped
- */
-public class AsyncTaskResultWrapper<T> {
-
- private final T mResult;
- private final Exception mError;
-
- public AsyncTaskResultWrapper(T result, Exception error) {
- this.mResult = result;
- this.mError = error;
- }
-
- public T getResult() {
- return mResult;
- }
-
- public Exception getError() {
- return mError;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/HighlightQueryCursorAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/HighlightQueryCursorAdapter.java
deleted file mode 100644
index a3ed08a4c..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/HighlightQueryCursorAdapter.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.adapter;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.support.v4.widget.CursorAdapter;
-import android.text.Spannable;
-import android.text.style.ForegroundColorSpan;
-import org.sufficientlysecure.keychain.R;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public abstract class HighlightQueryCursorAdapter extends CursorAdapter {
-
- private String mCurQuery;
-
- public HighlightQueryCursorAdapter(Context context, Cursor c, int flags) {
- super(context, c, flags);
- mCurQuery = null;
- }
-
- public void setSearchQuery(String searchQuery) {
- mCurQuery = searchQuery;
- }
-
- public String getSearchQuery() {
- return mCurQuery;
- }
-
- protected Spannable highlightSearchQuery(String text) {
- Spannable highlight = Spannable.Factory.getInstance().newSpannable(text);
-
- if (mCurQuery != null) {
- Pattern pattern = Pattern.compile("(?i)" + mCurQuery);
- Matcher matcher = pattern.matcher(text);
- if (matcher.find()) {
- highlight.setSpan(
- new ForegroundColorSpan(mContext.getResources().getColor(R.color.emphasis)),
- matcher.start(),
- matcher.end(),
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- return highlight;
- } else {
- return highlight;
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
deleted file mode 100644
index f322ea980..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.adapter;
-
-import android.annotation.SuppressLint;
-import android.app.Activity;
-import android.content.Context;
-import android.graphics.Color;
-import android.os.Build;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.CheckBox;
-import android.widget.LinearLayout;
-import android.widget.LinearLayout.LayoutParams;
-import android.widget.TextView;
-
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
- protected LayoutInflater mInflater;
- protected Activity mActivity;
-
- protected List<ImportKeysListEntry> mData;
-
- static class ViewHolder {
- public TextView mainUserId;
- public TextView mainUserIdRest;
- public TextView keyId;
- public TextView fingerprint;
- public TextView algorithm;
- public TextView status;
- }
-
- public ImportKeysAdapter(Activity activity) {
- super(activity, -1);
- mActivity = activity;
- mInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- }
-
- @SuppressLint("NewApi")
- public void setData(List<ImportKeysListEntry> data) {
- clear();
- if (data != null) {
- this.mData = data;
-
- // add data to extended ArrayAdapter
- if (Build.VERSION.SDK_INT >= 11) {
- addAll(data);
- } else {
- for (ImportKeysListEntry entry : data) {
- add(entry);
- }
- }
- }
- }
-
- public List<ImportKeysListEntry> getData() {
- return mData;
- }
-
- public ArrayList<ImportKeysListEntry> getSelectedData() {
- ArrayList<ImportKeysListEntry> selectedData = new ArrayList<ImportKeysListEntry>();
- for (ImportKeysListEntry entry : mData) {
- if (entry.isSelected()) {
- selectedData.add(entry);
- }
- }
- return selectedData;
- }
-
- @Override
- public boolean hasStableIds() {
- return true;
- }
-
- public View getView(int position, View convertView, ViewGroup parent) {
- ImportKeysListEntry entry = mData.get(position);
- ViewHolder holder;
- if (convertView == null) {
- holder = new ViewHolder();
- convertView = mInflater.inflate(R.layout.import_keys_list_entry, null);
- holder.mainUserId = (TextView) convertView.findViewById(R.id.mainUserId);
- holder.mainUserIdRest = (TextView) convertView.findViewById(R.id.mainUserIdRest);
- holder.keyId = (TextView) convertView.findViewById(R.id.keyId);
- holder.fingerprint = (TextView) convertView.findViewById(R.id.fingerprint);
- holder.algorithm = (TextView) convertView.findViewById(R.id.algorithm);
- holder.status = (TextView) convertView.findViewById(R.id.status);
- convertView.setTag(holder);
- } else {
- holder = (ViewHolder) convertView.getTag();
- }
- // main user id
- String userId = entry.userIds.get(0);
- String[] userIdSplit = PgpKeyHelper.splitUserId(userId);
-
- // name
- if (userIdSplit[0] != null) {
- // show red user id if it is a secret key
- if (entry.secretKey) {
- userIdSplit[0] = mActivity.getString(R.string.secret_key) + " " + userIdSplit[0];
- holder.mainUserId.setTextColor(Color.RED);
- }
- holder.mainUserId.setText(userIdSplit[0]);
- } else {
- holder.mainUserId.setText(R.string.user_id_no_name);
- }
-
- // email
- if (userIdSplit[1] != null) {
- holder.mainUserIdRest.setText(userIdSplit[1]);
- holder.mainUserIdRest.setVisibility(View.VISIBLE);
- } else {
- holder.mainUserIdRest.setVisibility(View.GONE);
- }
-
- holder.keyId.setText(entry.keyIdHex);
-
- if (entry.fingerPrintHex != null) {
- holder.fingerprint.setText(PgpKeyHelper.colorizeFingerprint(entry.fingerPrintHex));
- holder.fingerprint.setVisibility(View.VISIBLE);
- } else {
- holder.fingerprint.setVisibility(View.GONE);
- }
-
- holder.algorithm.setText("" + entry.bitStrength + "/" + entry.algorithm);
-
- if (entry.revoked) {
- holder.status.setText(R.string.revoked);
- } else {
- holder.status.setVisibility(View.GONE);
- }
-
- LinearLayout ll = (LinearLayout) convertView.findViewById(R.id.list);
- ll.removeAllViews();
- if (entry.userIds.size() == 1) {
- ll.setVisibility(View.GONE);
- } else {
- boolean first = true;
- boolean second = true;
- for (String uid : entry.userIds) {
- if (first) {
- first = false;
- continue;
- }
- if (!second) {
- View sep = new View(mActivity);
- sep.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 1));
- sep.setBackgroundResource(android.R.drawable.divider_horizontal_dark);
- ll.addView(sep);
- }
- TextView uidView = (TextView) mInflater.inflate(
- R.layout.import_keys_list_entry_user_id, null);
- uidView.setText(uid);
- ll.addView(uidView);
- second = false;
- }
- }
-
- CheckBox cBox = (CheckBox) convertView.findViewById(R.id.selected);
- cBox.setChecked(entry.isSelected());
-
- return convertView;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java
deleted file mode 100644
index 5631d40ea..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.adapter;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.SparseArray;
-
-import org.spongycastle.openpgp.PGPKeyRing;
-import org.spongycastle.openpgp.PGPPublicKey;
-import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.util.IterableIterator;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Date;
-
-public class ImportKeysListEntry implements Serializable, Parcelable {
- private static final long serialVersionUID = -7797972103284992662L;
-
- public ArrayList<String> userIds;
- public long keyId;
- public String keyIdHex;
- public boolean revoked;
- public Date date; // TODO: not displayed
- public String fingerPrintHex;
- public int bitStrength;
- public String algorithm;
- public boolean secretKey;
-
- private boolean mSelected;
-
- private byte[] mBytes = new byte[]{};
-
- public ImportKeysListEntry(ImportKeysListEntry b) {
- this.userIds = b.userIds;
- this.keyId = b.keyId;
- this.revoked = b.revoked;
- this.date = b.date;
- this.fingerPrintHex = b.fingerPrintHex;
- this.keyIdHex = b.keyIdHex;
- this.bitStrength = b.bitStrength;
- this.algorithm = b.algorithm;
- this.secretKey = b.secretKey;
- this.mSelected = b.mSelected;
- this.mBytes = b.mBytes;
- }
-
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeStringList(userIds);
- dest.writeLong(keyId);
- dest.writeByte((byte) (revoked ? 1 : 0));
- dest.writeSerializable(date);
- dest.writeString(fingerPrintHex);
- dest.writeString(keyIdHex);
- dest.writeInt(bitStrength);
- dest.writeString(algorithm);
- dest.writeByte((byte) (secretKey ? 1 : 0));
- dest.writeByte((byte) (mSelected ? 1 : 0));
- dest.writeInt(mBytes.length);
- dest.writeByteArray(mBytes);
- }
-
- public static final Creator<ImportKeysListEntry> CREATOR = new Creator<ImportKeysListEntry>() {
- public ImportKeysListEntry createFromParcel(final Parcel source) {
- ImportKeysListEntry vr = new ImportKeysListEntry();
- vr.userIds = new ArrayList<String>();
- source.readStringList(vr.userIds);
- vr.keyId = source.readLong();
- vr.revoked = source.readByte() == 1;
- vr.date = (Date) source.readSerializable();
- vr.fingerPrintHex = source.readString();
- vr.keyIdHex = source.readString();
- vr.bitStrength = source.readInt();
- vr.algorithm = source.readString();
- vr.secretKey = source.readByte() == 1;
- vr.mSelected = source.readByte() == 1;
- vr.mBytes = new byte[source.readInt()];
- source.readByteArray(vr.mBytes);
-
- return vr;
- }
-
- public ImportKeysListEntry[] newArray(final int size) {
- return new ImportKeysListEntry[size];
- }
- };
-
- public String getKeyIdHex() {
- return keyIdHex;
- }
-
- public byte[] getBytes() {
- return mBytes;
- }
-
- public void setBytes(byte[] bytes) {
- this.mBytes = bytes;
- }
-
- public boolean isSelected() {
- return mSelected;
- }
-
- public void setSelected(boolean selected) {
- this.mSelected = selected;
- }
-
- public long getKeyId() {
- return keyId;
- }
-
- public void setKeyId(long keyId) {
- this.keyId = keyId;
- }
-
- public void setKeyIdHex(String keyIdHex) {
- this.keyIdHex = keyIdHex;
- }
-
- public boolean isRevoked() {
- return revoked;
- }
-
- public void setRevoked(boolean revoked) {
- this.revoked = revoked;
- }
-
- public Date getDate() {
- return date;
- }
-
- public void setDate(Date date) {
- this.date = date;
- }
-
- public String getFingerPrintHex() {
- return fingerPrintHex;
- }
-
- public void setFingerPrintHex(String fingerPrintHex) {
- this.fingerPrintHex = fingerPrintHex;
- }
-
- public int getBitStrength() {
- return bitStrength;
- }
-
- public void setBitStrength(int bitStrength) {
- this.bitStrength = bitStrength;
- }
-
- public String getAlgorithm() {
- return algorithm;
- }
-
- public void setAlgorithm(String algorithm) {
- this.algorithm = algorithm;
- }
-
- public boolean isSecretKey() {
- return secretKey;
- }
-
- public void setSecretKey(boolean secretKey) {
- this.secretKey = secretKey;
- }
-
- public ArrayList<String> getUserIds() {
- return userIds;
- }
-
- public void setUserIds(ArrayList<String> userIds) {
- this.userIds = userIds;
- }
-
- /**
- * Constructor for later querying from keyserver
- */
- public ImportKeysListEntry() {
- // keys from keyserver are always public keys
- secretKey = false;
- // do not select by default
- mSelected = false;
- userIds = new ArrayList<String>();
- }
-
- /**
- * Constructor based on key object, used for import from NFC, QR Codes, files
- */
- @SuppressWarnings("unchecked")
- public ImportKeysListEntry(PGPKeyRing pgpKeyRing) {
- // save actual key object into entry, used to import it later
- try {
- this.mBytes = pgpKeyRing.getEncoded();
- } catch (IOException e) {
- Log.e(Constants.TAG, "IOException on pgpKeyRing.getEncoded()", e);
- }
-
- // selected is default
- this.mSelected = true;
-
- if (pgpKeyRing instanceof PGPSecretKeyRing) {
- secretKey = true;
- } else {
- secretKey = false;
- }
-
- userIds = new ArrayList<String>();
- for (String userId : new IterableIterator<String>(pgpKeyRing.getPublicKey().getUserIDs())) {
- userIds.add(userId);
- }
-
- this.keyId = pgpKeyRing.getPublicKey().getKeyID();
- this.keyIdHex = PgpKeyHelper.convertKeyIdToHex(keyId);
-
- this.revoked = pgpKeyRing.getPublicKey().isRevoked();
- this.fingerPrintHex = PgpKeyHelper.convertFingerprintToHex(pgpKeyRing.getPublicKey()
- .getFingerprint());
- this.bitStrength = pgpKeyRing.getPublicKey().getBitStrength();
- final int algorithm = pgpKeyRing.getPublicKey().getAlgorithm();
- this.algorithm = getAlgorithmFromId(algorithm);
- }
-
- /**
- * Based on <a href="http://tools.ietf.org/html/rfc2440#section-9.1">OpenPGP Message Format</a>
- */
- private static final SparseArray<String> ALGORITHM_IDS = new SparseArray<String>() {{
- put(-1, "unknown"); // TODO: with resources
- put(0, "unencrypted");
- put(PGPPublicKey.RSA_GENERAL, "RSA");
- put(PGPPublicKey.RSA_ENCRYPT, "RSA");
- put(PGPPublicKey.RSA_SIGN, "RSA");
- put(PGPPublicKey.ELGAMAL_ENCRYPT, "ElGamal");
- put(PGPPublicKey.ELGAMAL_GENERAL, "ElGamal");
- put(PGPPublicKey.DSA, "DSA");
- put(PGPPublicKey.EC, "ECC");
- put(PGPPublicKey.ECDSA, "ECC");
- put(PGPPublicKey.ECDH, "ECC");
- }};
-
- /**
- * Based on <a href="http://tools.ietf.org/html/rfc2440#section-9.1">OpenPGP Message Format</a>
- */
- public static String getAlgorithmFromId(int algorithmId) {
- return (ALGORITHM_IDS.get(algorithmId) != null ?
- ALGORITHM_IDS.get(algorithmId) :
- ALGORITHM_IDS.get(-1));
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
deleted file mode 100644
index c9983213c..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.adapter;
-
-import android.content.Context;
-import android.support.v4.content.AsyncTaskLoader;
-import org.spongycastle.openpgp.PGPKeyRing;
-import org.spongycastle.openpgp.PGPObjectFactory;
-import org.spongycastle.openpgp.PGPUtil;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.util.InputData;
-import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.util.PositionAwareInputStream;
-
-import java.io.BufferedInputStream;
-import java.io.InputStream;
-import java.util.ArrayList;
-
-public class ImportKeysListLoader
- extends AsyncTaskLoader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> {
-
- public static class FileHasNoContent extends Exception {
-
- }
-
- public static class NonPgpPart extends Exception {
- private int mCount;
-
- public NonPgpPart(int count) {
- this.mCount = count;
- }
-
- public int getCount() {
- return mCount;
- }
- }
-
- Context mContext;
-
- InputData mInputData;
-
- ArrayList<ImportKeysListEntry> mData = new ArrayList<ImportKeysListEntry>();
- AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> mEntryListWrapper;
-
- public ImportKeysListLoader(Context context, InputData inputData) {
- super(context);
- this.mContext = context;
- this.mInputData = inputData;
- }
-
- @Override
- public AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> loadInBackground() {
-
- mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mData, null);
-
- if (mInputData == null) {
- Log.e(Constants.TAG, "Input data is null!");
- return mEntryListWrapper;
- }
-
- generateListOfKeyrings(mInputData);
-
- return mEntryListWrapper;
- }
-
- @Override
- protected void onReset() {
- super.onReset();
-
- // Ensure the loader is stopped
- onStopLoading();
- }
-
- @Override
- protected void onStartLoading() {
- forceLoad();
- }
-
- @Override
- protected void onStopLoading() {
- cancelLoad();
- }
-
- @Override
- public void deliverResult(AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> data) {
- super.deliverResult(data);
- }
-
- /**
- * Reads all PGPKeyRing objects from input
- *
- * @param inputData
- * @return
- */
- private void generateListOfKeyrings(InputData inputData) {
-
- boolean isEmpty = true;
- int nonPgpCounter = 0;
-
- PositionAwareInputStream progressIn = new PositionAwareInputStream(
- inputData.getInputStream());
-
- // need to have access to the bufferedInput, so we can reuse it for the possible
- // PGPObject chunks after the first one, e.g. files with several consecutive ASCII
- // armor blocks
- BufferedInputStream bufferedInput = new BufferedInputStream(progressIn);
- try {
-
- // read all available blocks... (asc files can contain many blocks with BEGIN END)
- while (bufferedInput.available() > 0) {
- isEmpty = false;
- InputStream in = PGPUtil.getDecoderStream(bufferedInput);
- PGPObjectFactory objectFactory = new PGPObjectFactory(in);
-
- // go through all objects in this block
- Object obj;
- while ((obj = objectFactory.nextObject()) != null) {
- Log.d(Constants.TAG, "Found class: " + obj.getClass());
-
- if (obj instanceof PGPKeyRing) {
- PGPKeyRing newKeyring = (PGPKeyRing) obj;
- addToData(newKeyring);
- } else {
- Log.e(Constants.TAG, "Object not recognized as PGPKeyRing!");
- nonPgpCounter++;
- }
- }
- }
- } catch (Exception e) {
- Log.e(Constants.TAG, "Exception on parsing key file!", e);
- mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mData, e);
- nonPgpCounter = 0;
- }
-
- if (isEmpty) {
- Log.e(Constants.TAG, "File has no content!", new FileHasNoContent());
- mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>
- (mData, new FileHasNoContent());
- }
-
- if (nonPgpCounter > 0) {
- mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>
- (mData, new NonPgpPart(nonPgpCounter));
- }
- }
-
- private void addToData(PGPKeyRing keyring) {
- ImportKeysListEntry item = new ImportKeysListEntry(keyring);
- mData.add(item);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java
deleted file mode 100644
index 259e14319..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.adapter;
-
-import android.content.Context;
-import android.support.v4.content.AsyncTaskLoader;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.util.HkpKeyServer;
-import org.sufficientlysecure.keychain.util.KeyServer;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.util.ArrayList;
-
-public class ImportKeysListServerLoader
- extends AsyncTaskLoader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> {
- Context mContext;
-
- String mServerQuery;
- String mKeyServer;
-
- private ArrayList<ImportKeysListEntry> mEntryList = new ArrayList<ImportKeysListEntry>();
- private AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> mEntryListWrapper;
-
- public ImportKeysListServerLoader(Context context, String serverQuery, String keyServer) {
- super(context);
- mContext = context;
- mServerQuery = serverQuery;
- mKeyServer = keyServer;
- }
-
- @Override
- public AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> loadInBackground() {
-
- mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mEntryList, null);
-
- if (mServerQuery == null) {
- Log.e(Constants.TAG, "mServerQuery is null!");
- return mEntryListWrapper;
- }
-
- if (mServerQuery.startsWith("0x") && mServerQuery.length() == 42) {
- Log.d(Constants.TAG, "This search is based on a unique fingerprint. Enforce a fingerprint check!");
- queryServer(mServerQuery, mKeyServer, true);
- } else {
- queryServer(mServerQuery, mKeyServer, false);
- }
-
- return mEntryListWrapper;
- }
-
- @Override
- protected void onReset() {
- super.onReset();
-
- // Ensure the loader is stopped
- onStopLoading();
- }
-
- @Override
- protected void onStartLoading() {
- forceLoad();
- }
-
- @Override
- protected void onStopLoading() {
- cancelLoad();
- }
-
- @Override
- public void deliverResult(AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> data) {
- super.deliverResult(data);
- }
-
- /**
- * Query keyserver
- */
- private void queryServer(String query, String keyServer, boolean enforceFingerprint) {
- HkpKeyServer server = new HkpKeyServer(keyServer);
- try {
- ArrayList<ImportKeysListEntry> searchResult = server.search(query);
-
- mEntryList.clear();
- // add result to data
- if (enforceFingerprint) {
- String fingerprint = query.substring(2);
- Log.d(Constants.TAG, "fingerprint: " + fingerprint);
- // query must return only one result!
- if (searchResult.size() > 0) {
- ImportKeysListEntry uniqueEntry = searchResult.get(0);
- /*
- * set fingerprint explicitly after query
- * to enforce a check when the key is imported by KeychainIntentService
- */
- uniqueEntry.setFingerPrintHex(fingerprint);
- uniqueEntry.setSelected(true);
- mEntryList.add(uniqueEntry);
- }
- } else {
- mEntryList.addAll(searchResult);
- }
- mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mEntryList, null);
- } catch (KeyServer.InsufficientQuery e) {
- Log.e(Constants.TAG, "InsufficientQuery", e);
- mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mEntryList, e);
- } catch (KeyServer.QueryException e) {
- Log.e(Constants.TAG, "QueryException", e);
- mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mEntryList, e);
- } catch (KeyServer.TooManyResponses e) {
- Log.e(Constants.TAG, "TooManyResponses", e);
- mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mEntryList, e);
- }
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyValueSpinnerAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyValueSpinnerAdapter.java
deleted file mode 100644
index 5b5d316b6..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyValueSpinnerAdapter.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.adapter;
-
-import android.content.Context;
-import android.widget.ArrayAdapter;
-
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-public class KeyValueSpinnerAdapter extends ArrayAdapter<String> {
- private final HashMap<Integer, String> mData;
- private final int[] mKeys;
- private final String[] mValues;
-
- static <K, V extends Comparable<? super V>> SortedSet<Map.Entry<K, V>> entriesSortedByValues(
- Map<K, V> map) {
- SortedSet<Map.Entry<K, V>> sortedEntries = new TreeSet<Map.Entry<K, V>>(
- new Comparator<Map.Entry<K, V>>() {
- @Override
- public int compare(Map.Entry<K, V> e1, Map.Entry<K, V> e2) {
- return e1.getValue().compareTo(e2.getValue());
- }
- });
- sortedEntries.addAll(map.entrySet());
- return sortedEntries;
- }
-
- public KeyValueSpinnerAdapter(Context context, HashMap<Integer, String> objects) {
- // To make the drop down a simple text box
- super(context, android.R.layout.simple_spinner_item);
- mData = objects;
-
- // To make the drop down view a radio button list
- setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-
- SortedSet<Map.Entry<Integer, String>> sorted = entriesSortedByValues(objects);
-
- // Assign hash keys with a position so that we can present and retrieve them
- int i = 0;
- mKeys = new int[mData.size()];
- mValues = new String[mData.size()];
- for (Map.Entry<Integer, String> entry : sorted) {
- mKeys[i] = entry.getKey();
- mValues[i] = entry.getValue();
- i++;
- }
- }
-
- public int getCount() {
- return mData.size();
- }
-
- /**
- * Returns the value
- */
- @Override
- public String getItem(int position) {
- // return the value based on the position. This is displayed in the list.
- return mValues[position];
- }
-
- /**
- * Returns item key
- */
- public long getItemId(int position) {
- // Return an id to represent the item.
-
- return mKeys[position];
- }
-
- /**
- * Find position from key
- */
- public int getPosition(long itemId) {
- for (int i = 0; i < mKeys.length; i++) {
- if ((int) itemId == mKeys[i]) {
- return i;
- }
- }
- return -1;
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java
deleted file mode 100644
index fd864eb09..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.adapter;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentPagerAdapter;
-import android.support.v7.app.ActionBarActivity;
-
-import java.util.ArrayList;
-
-public class PagerTabStripAdapter extends FragmentPagerAdapter {
- private final Context mContext;
- private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
-
- static final class TabInfo {
- public final Class<?> clss;
- public final Bundle args;
- public final String title;
-
- TabInfo(Class<?> clss, Bundle args, String title) {
- this.clss = clss;
- this.args = args;
- this.title = title;
- }
- }
-
- public PagerTabStripAdapter(ActionBarActivity activity) {
- super(activity.getSupportFragmentManager());
- mContext = activity;
- }
-
- public void addTab(Class<?> clss, Bundle args, String title) {
- TabInfo info = new TabInfo(clss, args, title);
- mTabs.add(info);
- notifyDataSetChanged();
- }
-
- @Override
- public int getCount() {
- return mTabs.size();
- }
-
- @Override
- public Fragment getItem(int position) {
- TabInfo info = mTabs.get(position);
- return Fragment.instantiate(mContext, info.clss.getName(), info.args);
- }
-
- @Override
- public CharSequence getPageTitle(int position) {
- return mTabs.get(position).title;
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
deleted file mode 100644
index fbbb9caa4..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.adapter;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CheckBox;
-import android.widget.ListView;
-import android.widget.TextView;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
-
-
-public class SelectKeyCursorAdapter extends HighlightQueryCursorAdapter {
-
- protected int mKeyType;
-
- private LayoutInflater mInflater;
- private ListView mListView;
-
- private int mIndexUserId;
- private int mIndexMasterKeyId;
- private int mIndexProjectionValid;
- private int mIndexProjectionAvailable;
-
- public static final String PROJECTION_ROW_AVAILABLE = "available";
- public static final String PROJECTION_ROW_VALID = "valid";
-
- public SelectKeyCursorAdapter(Context context, Cursor c, int flags, ListView listView,
- int keyType) {
- super(context, c, flags);
-
- mInflater = LayoutInflater.from(context);
- mListView = listView;
- mKeyType = keyType;
- initIndex(c);
- }
-
- @Override
- public Cursor swapCursor(Cursor newCursor) {
- initIndex(newCursor);
-
- return super.swapCursor(newCursor);
- }
-
- /**
- * Get column indexes for performance reasons just once in constructor and swapCursor. For a
- * performance comparison see http://stackoverflow.com/a/17999582
- *
- * @param cursor
- */
- private void initIndex(Cursor cursor) {
- if (cursor != null) {
- mIndexUserId = cursor.getColumnIndexOrThrow(UserIds.USER_ID);
- mIndexMasterKeyId = cursor.getColumnIndexOrThrow(KeyRings.MASTER_KEY_ID);
- mIndexProjectionValid = cursor.getColumnIndexOrThrow(PROJECTION_ROW_VALID);
- mIndexProjectionAvailable = cursor.getColumnIndexOrThrow(PROJECTION_ROW_AVAILABLE);
- }
- }
-
- public String getUserId(int position) {
- mCursor.moveToPosition(position);
- return mCursor.getString(mIndexUserId);
- }
-
- public long getMasterKeyId(int position) {
- mCursor.moveToPosition(position);
- return mCursor.getLong(mIndexMasterKeyId);
- }
-
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
- boolean valid = cursor.getInt(mIndexProjectionValid) > 0;
-
- TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId);
- TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest);
- TextView keyId = (TextView) view.findViewById(R.id.keyId);
- TextView status = (TextView) view.findViewById(R.id.status);
-
- String userId = cursor.getString(mIndexUserId);
- String[] userIdSplit = PgpKeyHelper.splitUserId(userId);
-
- if (userIdSplit[0] != null) {
- mainUserId.setText(highlightSearchQuery(userIdSplit[0]));
- } else {
- mainUserId.setText(R.string.user_id_no_name);
- }
- if (userIdSplit[1] != null) {
- mainUserIdRest.setText(highlightSearchQuery(userIdSplit[1]));
- } else {
- mainUserIdRest.setText("");
- }
-
- // TODO: needed to key id to no?
- keyId.setText(R.string.no_key);
- long masterKeyId = cursor.getLong(mIndexMasterKeyId);
- keyId.setText(PgpKeyHelper.convertKeyIdToHexShort(masterKeyId));
-
- // TODO: needed to set unknown_status?
- status.setText(R.string.unknown_status);
- if (valid) {
- if (mKeyType == Id.type.public_key) {
- status.setText(R.string.can_encrypt);
- } else {
- status.setText(R.string.can_sign);
- }
- } else {
- if (cursor.getInt(mIndexProjectionAvailable) > 0) {
- // has some CAN_ENCRYPT keys, but col(ROW_VALID) = 0, so must be revoked or
- // expired
- status.setText(R.string.expired);
- } else {
- status.setText(R.string.no_key);
- }
- }
-
- CheckBox selected = (CheckBox) view.findViewById(R.id.selected);
- if (mKeyType == Id.type.public_key) {
- selected.setVisibility(View.VISIBLE);
-
- if (!valid) {
- mListView.setItemChecked(cursor.getPosition(), false);
- }
-
- selected.setChecked(mListView.isItemChecked(cursor.getPosition()));
- selected.setEnabled(valid);
- } else {
- selected.setVisibility(View.GONE);
- }
-
- status.setText(status.getText() + " ");
-
- view.setEnabled(valid);
- mainUserId.setEnabled(valid);
- mainUserIdRest.setEnabled(valid);
- keyId.setEnabled(valid);
- status.setEnabled(valid);
- }
-
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(R.layout.select_key_item, null);
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java
deleted file mode 100644
index 9ddfa90be..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.adapter;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentStatePagerAdapter;
-import android.support.v4.app.FragmentTransaction;
-import android.support.v4.view.ViewPager;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
-
-import java.util.ArrayList;
-
-public class TabsAdapter extends FragmentStatePagerAdapter implements ActionBar.TabListener,
- ViewPager.OnPageChangeListener {
- private final Context mContext;
- private final ActionBar mActionBar;
- private final ViewPager mViewPager;
- private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
-
- static final class TabInfo {
- public final Class<?> clss;
- public final Bundle args;
-
- TabInfo(Class<?> clss, Bundle args) {
- this.clss = clss;
- this.args = args;
- }
- }
-
- public TabsAdapter(ActionBarActivity activity, ViewPager pager) {
- super(activity.getSupportFragmentManager());
- mContext = activity;
- mActionBar = activity.getSupportActionBar();
- mViewPager = pager;
- mViewPager.setAdapter(this);
- mViewPager.setOnPageChangeListener(this);
- }
-
- public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args, boolean selected) {
- TabInfo info = new TabInfo(clss, args);
- tab.setTag(info);
- tab.setTabListener(this);
- mTabs.add(info);
- mActionBar.addTab(tab, selected);
- notifyDataSetChanged();
- }
-
- @Override
- public int getCount() {
- return mTabs.size();
- }
-
- @Override
- public Fragment getItem(int position) {
- TabInfo info = mTabs.get(position);
- return Fragment.instantiate(mContext, info.clss.getName(), info.args);
- }
-
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- }
-
- public void onPageSelected(int position) {
- mActionBar.setSelectedNavigationItem(position);
- }
-
- public void onPageScrollStateChanged(int state) {
- }
-
- public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
- Object tag = tab.getTag();
- for (int i = 0; i < mTabs.size(); i++) {
- if (mTabs.get(i) == tag) {
- mViewPager.setCurrentItem(i);
- }
- }
- }
-
- public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
- }
-
- public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java
deleted file mode 100644
index 64b735bfa..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.adapter;
-
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.database.Cursor;
-import android.support.v4.widget.CursorAdapter;
-import android.text.format.DateFormat;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.OtherHelper;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
-
-import java.util.Date;
-
-public class ViewKeyKeysAdapter extends CursorAdapter {
- private LayoutInflater mInflater;
-
- private int mIndexKeyId;
- private int mIndexAlgorithm;
- private int mIndexKeySize;
- private int mIndexRank;
- private int mIndexCanCertify;
- private int mIndexCanEncrypt;
- private int mIndexCanSign;
- private int mIndexRevokedKey;
- private int mIndexExpiry;
-
- private ColorStateList mDefaultTextColor;
-
- public ViewKeyKeysAdapter(Context context, Cursor c, int flags) {
- super(context, c, flags);
-
- mInflater = LayoutInflater.from(context);
-
- initIndex(c);
- }
-
- @Override
- public Cursor swapCursor(Cursor newCursor) {
- initIndex(newCursor);
-
- return super.swapCursor(newCursor);
- }
-
- /**
- * Get column indexes for performance reasons just once in constructor and swapCursor. For a
- * performance comparison see http://stackoverflow.com/a/17999582
- *
- * @param cursor
- */
- private void initIndex(Cursor cursor) {
- if (cursor != null) {
- mIndexKeyId = cursor.getColumnIndexOrThrow(Keys.KEY_ID);
- mIndexAlgorithm = cursor.getColumnIndexOrThrow(Keys.ALGORITHM);
- mIndexKeySize = cursor.getColumnIndexOrThrow(Keys.KEY_SIZE);
- mIndexRank = cursor.getColumnIndexOrThrow(Keys.RANK);
- mIndexCanCertify = cursor.getColumnIndexOrThrow(Keys.CAN_CERTIFY);
- mIndexCanEncrypt = cursor.getColumnIndexOrThrow(Keys.CAN_ENCRYPT);
- mIndexCanSign = cursor.getColumnIndexOrThrow(Keys.CAN_SIGN);
- mIndexRevokedKey = cursor.getColumnIndexOrThrow(Keys.IS_REVOKED);
- mIndexExpiry = cursor.getColumnIndexOrThrow(Keys.EXPIRY);
- }
- }
-
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
- TextView keyId = (TextView) view.findViewById(R.id.keyId);
- TextView keyDetails = (TextView) view.findViewById(R.id.keyDetails);
- TextView keyExpiry = (TextView) view.findViewById(R.id.keyExpiry);
- ImageView masterKeyIcon = (ImageView) view.findViewById(R.id.ic_masterKey);
- ImageView certifyIcon = (ImageView) view.findViewById(R.id.ic_certifyKey);
- ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey);
- ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey);
- ImageView revokedKeyIcon = (ImageView) view.findViewById(R.id.ic_revokedKey);
-
- String keyIdStr = PgpKeyHelper.convertKeyIdToHexShort(cursor.getLong(mIndexKeyId));
- String algorithmStr = PgpKeyHelper.getAlgorithmInfo(cursor.getInt(mIndexAlgorithm),
- cursor.getInt(mIndexKeySize));
-
- keyId.setText(keyIdStr);
- keyDetails.setText("(" + algorithmStr + ")");
-
- if (cursor.getInt(mIndexRank) == 0) {
- masterKeyIcon.setVisibility(View.INVISIBLE);
- } else {
- masterKeyIcon.setVisibility(View.VISIBLE);
- }
-
- if (cursor.getInt(mIndexCanCertify) != 1) {
- certifyIcon.setVisibility(View.GONE);
- } else {
- certifyIcon.setVisibility(View.VISIBLE);
- }
-
- if (cursor.getInt(mIndexCanEncrypt) != 1) {
- encryptIcon.setVisibility(View.GONE);
- } else {
- encryptIcon.setVisibility(View.VISIBLE);
- }
-
- if (cursor.getInt(mIndexCanSign) != 1) {
- signIcon.setVisibility(View.GONE);
- } else {
- signIcon.setVisibility(View.VISIBLE);
- }
-
- boolean valid = true;
- if (cursor.getInt(mIndexRevokedKey) > 0) {
- revokedKeyIcon.setVisibility(View.VISIBLE);
-
- valid = false;
- } else {
- keyId.setTextColor(mDefaultTextColor);
- keyDetails.setTextColor(mDefaultTextColor);
- keyExpiry.setTextColor(mDefaultTextColor);
-
- revokedKeyIcon.setVisibility(View.GONE);
- }
-
- if (!cursor.isNull(mIndexExpiry)) {
- Date expiryDate = new Date(cursor.getLong(mIndexExpiry) * 1000);
-
- valid = valid && expiryDate.after(new Date());
- keyExpiry.setText("(" +
- context.getString(R.string.label_expiry) + ": " +
- DateFormat.getDateFormat(context).format(expiryDate) + ")");
-
- keyExpiry.setVisibility(View.VISIBLE);
- } else {
- keyExpiry.setVisibility(View.GONE);
- }
- // if key is expired or revoked, strike through text
- if (!valid) {
- keyId.setText(OtherHelper.strikeOutText(keyId.getText()));
- keyDetails.setText(OtherHelper.strikeOutText(keyDetails.getText()));
- keyExpiry.setText(OtherHelper.strikeOutText(keyExpiry.getText()));
- }
- keyId.setEnabled(valid);
- keyDetails.setEnabled(valid);
- keyExpiry.setEnabled(valid);
- }
-
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- View view = mInflater.inflate(R.layout.view_key_keys_item, null);
- if (mDefaultTextColor == null) {
- TextView keyId = (TextView) view.findViewById(R.id.keyId);
- mDefaultTextColor = keyId.getTextColors();
- }
- return view;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java
deleted file mode 100644
index 09137f745..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.adapter;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.support.v4.widget.CursorAdapter;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
-import android.widget.TextView;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
-import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
-
-import java.util.ArrayList;
-
-public class ViewKeyUserIdsAdapter extends CursorAdapter implements AdapterView.OnItemClickListener {
- private LayoutInflater mInflater;
-
- private int mIndexUserId, mIndexRank;
- private int mVerifiedId, mIsRevoked, mIsPrimary;
-
- private final ArrayList<Boolean> mCheckStates;
-
- public static final String[] USER_IDS_PROJECTION = new String[] {
- UserIds._ID, UserIds.USER_ID, UserIds.RANK,
- UserIds.VERIFIED, UserIds.IS_PRIMARY, UserIds.IS_REVOKED
- };
-
- public ViewKeyUserIdsAdapter(Context context, Cursor c, int flags, boolean showCheckBoxes) {
- super(context, c, flags);
-
- mInflater = LayoutInflater.from(context);
-
- mCheckStates = showCheckBoxes ? new ArrayList<Boolean>() : null;
-
- initIndex(c);
- }
- public ViewKeyUserIdsAdapter(Context context, Cursor c, int flags) {
- this(context, c, flags, false);
- }
-
- @Override
- public Cursor swapCursor(Cursor newCursor) {
- initIndex(newCursor);
- if (mCheckStates != null) {
- mCheckStates.clear();
- if (newCursor != null) {
- int count = newCursor.getCount();
- mCheckStates.ensureCapacity(count);
- // initialize to true (use case knowledge: we usually want to sign all uids)
- for(int i = 0; i < count; i++) {
- newCursor.moveToPosition(i);
- int verified = newCursor.getInt(mVerifiedId);
- mCheckStates.add(verified != Certs.VERIFIED_SECRET);
- }
- }
- }
-
- return super.swapCursor(newCursor);
- }
-
- /**
- * Get column indexes for performance reasons just once in constructor and swapCursor. For a
- * performance comparison see http://stackoverflow.com/a/17999582
- *
- * @param cursor
- */
- private void initIndex(Cursor cursor) {
- if (cursor != null) {
- mIndexUserId = cursor.getColumnIndexOrThrow(UserIds.USER_ID);
- mIndexRank = cursor.getColumnIndexOrThrow(UserIds.RANK);
- mVerifiedId = cursor.getColumnIndexOrThrow(UserIds.VERIFIED);
- mIsRevoked = cursor.getColumnIndexOrThrow(UserIds.IS_REVOKED);
- mIsPrimary = cursor.getColumnIndexOrThrow(UserIds.IS_PRIMARY);
- }
- }
-
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
-
- TextView vRank = (TextView) view.findViewById(R.id.rank);
- TextView vUserId = (TextView) view.findViewById(R.id.userId);
- TextView vAddress = (TextView) view.findViewById(R.id.address);
- ImageView vVerified = (ImageView) view.findViewById(R.id.certified);
-
- if(cursor.getInt(mIsPrimary) > 0) {
- vRank.setText("+");
- } else {
- vRank.setText(Integer.toString(cursor.getInt(mIndexRank)));
- }
-
- String[] userId = PgpKeyHelper.splitUserId(cursor.getString(mIndexUserId));
- if (userId[0] != null) {
- vUserId.setText(userId[0]);
- } else {
- vUserId.setText(R.string.user_id_no_name);
- }
- vAddress.setText(userId[1]);
-
- if(cursor.getInt(mIsRevoked) > 0) {
- vRank.setText(" ");
- vVerified.setImageResource(android.R.drawable.presence_away);
- } else {
- int verified = cursor.getInt(mVerifiedId);
- // TODO introduce own resources for this :)
- if(verified == Certs.VERIFIED_SECRET)
- vVerified.setImageResource(android.R.drawable.presence_online);
- else if(verified == Certs.VERIFIED_SELF)
- vVerified.setImageResource(android.R.drawable.presence_invisible);
- else
- vVerified.setImageResource(android.R.drawable.presence_busy);
- }
-
- // don't care further if checkboxes aren't shown
- if (mCheckStates == null) {
- return;
- }
-
- final CheckBox vCheckBox = (CheckBox) view.findViewById(R.id.checkBox);
- final int position = cursor.getPosition();
- vCheckBox.setOnCheckedChangeListener(null);
- vCheckBox.setChecked(mCheckStates.get(position));
- vCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
- mCheckStates.set(position, b);
- }
- });
- vCheckBox.setClickable(false);
-
- }
-
- public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
- CheckBox box = ((CheckBox) view.findViewById(R.id.checkBox));
- if(box != null) {
- box.toggle();
- }
- }
-
- public ArrayList<String> getSelectedUserIds() {
- ArrayList<String> result = new ArrayList<String>();
- for (int i = 0; i < mCheckStates.size(); i++) {
- if (mCheckStates.get(i)) {
- mCursor.moveToPosition(i);
- result.add(mCursor.getString(mIndexUserId));
- }
- }
- return result;
- }
-
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- View view = mInflater.inflate(R.layout.view_key_userids_item, null);
- // only need to do this once ever, since mShowCheckBoxes is final
- view.findViewById(R.id.checkBox).setVisibility(mCheckStates != null ? View.VISIBLE : View.GONE);
- return view;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/BadImportKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/BadImportKeyDialogFragment.java
deleted file mode 100644
index 20b70658c..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/BadImportKeyDialogFragment.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.dialog;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.app.FragmentActivity;
-import org.sufficientlysecure.keychain.R;
-
-public class BadImportKeyDialogFragment extends DialogFragment {
- private static final String ARG_BAD_IMPORT = "bad_import";
-
- /**
- * Creates a new instance of this Bad Import Key DialogFragment
- *
- * @param bad
- * @return
- */
- public static BadImportKeyDialogFragment newInstance(int bad) {
- BadImportKeyDialogFragment frag = new BadImportKeyDialogFragment();
- Bundle args = new Bundle();
-
- args.putInt(ARG_BAD_IMPORT, bad);
- frag.setArguments(args);
-
- return frag;
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final FragmentActivity activity = getActivity();
- final int badImport = getArguments().getInt(ARG_BAD_IMPORT);
-
- AlertDialog.Builder alert = new AlertDialog.Builder(activity);
- alert.setIcon(R.drawable.ic_dialog_alert_holo_light);
- alert.setTitle(R.string.warning);
- alert.setMessage(activity.getResources()
- .getQuantityString(R.plurals.bad_keys_encountered, badImport, badImport));
- alert.setPositiveButton(android.R.string.ok,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.cancel();
- }
- });
- alert.setCancelable(true);
-
- return alert.create();
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java
deleted file mode 100644
index ad558a81e..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.dialog;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.app.FragmentActivity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.Spinner;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.util.Choice;
-
-import java.util.ArrayList;
-
-public class CreateKeyDialogFragment extends DialogFragment {
-
- public interface OnAlgorithmSelectedListener {
- public void onAlgorithmSelected(Choice algorithmChoice, int keySize);
- }
-
- private static final String ARG_EDITOR_CHILD_COUNT = "child_count";
-
- private int mNewKeySize;
- private Choice mNewKeyAlgorithmChoice;
- private OnAlgorithmSelectedListener mAlgorithmSelectedListener;
-
- public void setOnAlgorithmSelectedListener(OnAlgorithmSelectedListener listener) {
- mAlgorithmSelectedListener = listener;
- }
-
- public static CreateKeyDialogFragment newInstance(int mEditorChildCount) {
- CreateKeyDialogFragment frag = new CreateKeyDialogFragment();
- Bundle args = new Bundle();
-
- args.putInt(ARG_EDITOR_CHILD_COUNT, mEditorChildCount);
-
- frag.setArguments(args);
-
- return frag;
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final FragmentActivity context = getActivity();
- final LayoutInflater mInflater;
-
- final int childCount = getArguments().getInt(ARG_EDITOR_CHILD_COUNT);
- mInflater = context.getLayoutInflater();
-
- AlertDialog.Builder dialog = new AlertDialog.Builder(context);
-
- View view = mInflater.inflate(R.layout.create_key_dialog, null);
- dialog.setView(view);
- dialog.setTitle(R.string.title_create_key);
-
- boolean wouldBeMasterKey = (childCount == 0);
-
- final Spinner algorithm = (Spinner) view.findViewById(R.id.create_key_algorithm);
- ArrayList<Choice> choices = new ArrayList<Choice>();
- choices.add(new Choice(Id.choice.algorithm.dsa, getResources().getString(
- R.string.dsa)));
- if (!wouldBeMasterKey) {
- choices.add(new Choice(Id.choice.algorithm.elgamal, getResources().getString(
- R.string.elgamal)));
- }
-
- choices.add(new Choice(Id.choice.algorithm.rsa, getResources().getString(
- R.string.rsa)));
-
- ArrayAdapter<Choice> adapter = new ArrayAdapter<Choice>(context,
- android.R.layout.simple_spinner_item, choices);
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- algorithm.setAdapter(adapter);
- // make RSA the default
- for (int i = 0; i < choices.size(); ++i) {
- if (choices.get(i).getId() == Id.choice.algorithm.rsa) {
- algorithm.setSelection(i);
- break;
- }
- }
-
- final Spinner keySize = (Spinner) view.findViewById(R.id.create_key_size);
- ArrayAdapter<CharSequence> keySizeAdapter = ArrayAdapter.createFromResource(
- context, R.array.key_size_spinner_values,
- android.R.layout.simple_spinner_item);
- keySizeAdapter
- .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- keySize.setAdapter(keySizeAdapter);
- keySize.setSelection(3); // Default to 4096 for the key length
- dialog.setPositiveButton(android.R.string.ok,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface di, int id) {
- di.dismiss();
- try {
- final String selectedItem = (String) keySize.getSelectedItem();
- mNewKeySize = Integer.parseInt(selectedItem);
- } catch (NumberFormatException e) {
- mNewKeySize = 0;
- }
-
- mNewKeyAlgorithmChoice = (Choice) algorithm.getSelectedItem();
- mAlgorithmSelectedListener.onAlgorithmSelected(mNewKeyAlgorithmChoice, mNewKeySize);
- }
- });
-
- dialog.setCancelable(true);
- dialog.setNegativeButton(android.R.string.cancel,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface di, int id) {
- di.dismiss();
- }
- });
-
- final AlertDialog alertDialog = dialog.create();
-
- final AdapterView.OnItemSelectedListener weakRsaListener = new AdapterView.OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- final Choice selectedAlgorithm = (Choice) algorithm.getSelectedItem();
- final int selectedKeySize = Integer.parseInt((String) keySize.getSelectedItem());
- final boolean isWeakRsa = (selectedAlgorithm.getId() == Id.choice.algorithm.rsa &&
- selectedKeySize <= 1024);
- alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(!isWeakRsa);
- }
-
- @Override
- public void onNothingSelected(AdapterView<?> parent) {
- }
- };
-
- keySize.setOnItemSelectedListener(weakRsaListener);
- algorithm.setOnItemSelectedListener(weakRsaListener);
-
- return alertDialog;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java
deleted file mode 100644
index b4c38184c..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.dialog;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Message;
-import android.os.Messenger;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.app.FragmentActivity;
-import android.widget.Toast;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-
-public class DeleteFileDialogFragment extends DialogFragment {
- private static final String ARG_DELETE_FILE = "delete_file";
-
- /**
- * Creates new instance of this delete file dialog fragment
- */
- public static DeleteFileDialogFragment newInstance(String deleteFile) {
- DeleteFileDialogFragment frag = new DeleteFileDialogFragment();
- Bundle args = new Bundle();
-
- args.putString(ARG_DELETE_FILE, deleteFile);
-
- frag.setArguments(args);
-
- return frag;
- }
-
- /**
- * Creates dialog
- */
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final FragmentActivity activity = getActivity();
-
- final String deleteFile = getArguments().getString(ARG_DELETE_FILE);
-
- AlertDialog.Builder alert = new AlertDialog.Builder(activity);
-
-
- alert.setIcon(R.drawable.ic_dialog_alert_holo_light);
- alert.setTitle(R.string.warning);
- alert.setMessage(this.getString(R.string.file_delete_confirmation, deleteFile));
-
- alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int id) {
- dismiss();
-
- // Send all information needed to service to edit key in other thread
- Intent intent = new Intent(activity, KeychainIntentService.class);
-
- // fill values for this action
- Bundle data = new Bundle();
-
- intent.setAction(KeychainIntentService.ACTION_DELETE_FILE_SECURELY);
- data.putString(KeychainIntentService.DELETE_FILE, deleteFile);
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
-
- ProgressDialogFragment deletingDialog = ProgressDialogFragment.newInstance(
- getString(R.string.progress_deleting_securely),
- ProgressDialog.STYLE_HORIZONTAL,
- false,
- null);
-
- // Message is received after deleting is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler =
- new KeychainIntentServiceHandler(activity, deletingDialog) {
- public void handleMessage(Message message) {
- // handle messages by standard KeychainIntentHandler first
- super.handleMessage(message);
-
- if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- Toast.makeText(activity, R.string.file_delete_successful,
- Toast.LENGTH_SHORT).show();
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
-
- // show progress dialog
- deletingDialog.show(activity.getSupportFragmentManager(), "deletingDialog");
-
- // start service with intent
- activity.startService(intent);
- }
- });
- alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dismiss();
- }
- });
- alert.setCancelable(true);
-
- return alert.create();
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
deleted file mode 100644
index 72ea4c013..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.dialog;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.app.FragmentActivity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.CheckBox;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.KeychainDatabase;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.util.HashMap;
-
-public class DeleteKeyDialogFragment extends DialogFragment {
- private static final String ARG_MESSENGER = "messenger";
- private static final String ARG_DELETE_MASTER_KEY_IDS = "delete_master_key_ids";
-
- public static final int MESSAGE_OKAY = 1;
- public static final int MESSAGE_ERROR = 0;
-
- private boolean mIsSingleSelection = false;
-
- private TextView mMainMessage;
- private CheckBox mCheckDeleteSecret;
- private LinearLayout mDeleteSecretKeyView;
- private View mInflateView;
-
- private Messenger mMessenger;
-
- /**
- * Creates new instance of this delete file dialog fragment
- */
- public static DeleteKeyDialogFragment newInstance(Messenger messenger,
- long[] masterKeyIds) {
- DeleteKeyDialogFragment frag = new DeleteKeyDialogFragment();
- Bundle args = new Bundle();
-
- args.putParcelable(ARG_MESSENGER, messenger);
- args.putLongArray(ARG_DELETE_MASTER_KEY_IDS, masterKeyIds);
- //We don't need the key type
-
- frag.setArguments(args);
-
- return frag;
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
-
- final FragmentActivity activity = getActivity();
- mMessenger = getArguments().getParcelable(ARG_MESSENGER);
-
- final long[] masterKeyIds = getArguments().getLongArray(ARG_DELETE_MASTER_KEY_IDS);
-
- AlertDialog.Builder builder = new AlertDialog.Builder(activity);
-
- //Setup custom View to display in AlertDialog
- LayoutInflater inflater = activity.getLayoutInflater();
- mInflateView = inflater.inflate(R.layout.view_key_delete_fragment, null);
- builder.setView(mInflateView);
-
- mDeleteSecretKeyView = (LinearLayout) mInflateView.findViewById(R.id.deleteSecretKeyView);
- mMainMessage = (TextView) mInflateView.findViewById(R.id.mainMessage);
- mCheckDeleteSecret = (CheckBox) mInflateView.findViewById(R.id.checkDeleteSecret);
-
- builder.setTitle(R.string.warning);
-
- // If only a single key has been selected
- if (masterKeyIds.length == 1) {
- mIsSingleSelection = true;
-
- long masterKeyId = masterKeyIds[0];
-
- HashMap<String, Object> data = ProviderHelper.getUnifiedData(activity, masterKeyId, new String[]{
- KeyRings.USER_ID,
- KeyRings.HAS_SECRET
- }, new int[] { ProviderHelper.FIELD_TYPE_STRING, ProviderHelper.FIELD_TYPE_INTEGER });
- String userId = (String) data.get(KeyRings.USER_ID);
- boolean hasSecret = ((Long) data.get(KeyRings.HAS_SECRET)) == 1;
-
- // Hide the Checkbox and TextView since this is a single selection,user will be notified through message
- mDeleteSecretKeyView.setVisibility(View.GONE);
- // Set message depending on which key it is.
- mMainMessage.setText(getString(
- hasSecret ? R.string.secret_key_deletion_confirmation
- : R.string.public_key_deletetion_confirmation,
- userId));
- } else {
- mDeleteSecretKeyView.setVisibility(View.VISIBLE);
- mMainMessage.setText(R.string.key_deletion_confirmation_multi);
- }
-
- builder.setIcon(R.drawable.ic_dialog_alert_holo_light);
- builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
-
- boolean success = false;
- for(long masterKeyId : masterKeyIds) {
- int count = activity.getContentResolver().delete(
- KeyRingData.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null
- );
- success = count > 0;
- }
- if (success) {
- sendMessageToHandler(MESSAGE_OKAY, null);
- } else {
- sendMessageToHandler(MESSAGE_ERROR, null);
- }
- dismiss();
- }
- });
- builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int id) {
- dismiss();
- }
- });
-
- return builder.create();
- }
-
- /**
- * Send message back to handler which is initialized in a activity
- *
- * @param what Message integer you want to send
- */
- private void sendMessageToHandler(Integer what, Bundle data) {
- Message msg = Message.obtain();
- msg.what = what;
- if (data != null) {
- msg.setData(data);
- }
- try {
- mMessenger.send(msg);
- } catch (RemoteException e) {
- Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
- } catch (NullPointerException e) {
- Log.w(Constants.TAG, "Messenger is null!", e);
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java
deleted file mode 100644
index a4285c8e9..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.dialog;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.support.v4.app.DialogFragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.CheckBox;
-import android.widget.EditText;
-import android.widget.TextView;
-import com.beardedhen.androidbootstrap.BootstrapButton;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.FileHelper;
-import org.sufficientlysecure.keychain.util.Log;
-
-public class FileDialogFragment extends DialogFragment {
- private static final String ARG_MESSENGER = "messenger";
- private static final String ARG_TITLE = "title";
- private static final String ARG_MESSAGE = "message";
- private static final String ARG_DEFAULT_FILE = "default_file";
- private static final String ARG_CHECKBOX_TEXT = "checkbox_text";
-
- public static final int MESSAGE_OKAY = 1;
-
- public static final String MESSAGE_DATA_FILENAME = "filename";
- public static final String MESSAGE_DATA_CHECKED = "checked";
-
- private Messenger mMessenger;
-
- private EditText mFilename;
- private BootstrapButton mBrowse;
- private CheckBox mCheckBox;
- private TextView mMessageTextView;
-
- private static final int REQUEST_CODE = 0x00007004;
-
- /**
- * Creates new instance of this file dialog fragment
- */
- public static FileDialogFragment newInstance(Messenger messenger, String title, String message,
- String defaultFile, String checkboxText) {
- FileDialogFragment frag = new FileDialogFragment();
- Bundle args = new Bundle();
- args.putParcelable(ARG_MESSENGER, messenger);
-
- args.putString(ARG_TITLE, title);
- args.putString(ARG_MESSAGE, message);
- args.putString(ARG_DEFAULT_FILE, defaultFile);
- args.putString(ARG_CHECKBOX_TEXT, checkboxText);
-
- frag.setArguments(args);
-
- return frag;
- }
-
- /**
- * Creates dialog
- */
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final Activity activity = getActivity();
-
- mMessenger = getArguments().getParcelable(ARG_MESSENGER);
-
- String title = getArguments().getString(ARG_TITLE);
- String message = getArguments().getString(ARG_MESSAGE);
- String defaultFile = getArguments().getString(ARG_DEFAULT_FILE);
- String checkboxText = getArguments().getString(ARG_CHECKBOX_TEXT);
-
- LayoutInflater inflater = (LayoutInflater) activity
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- AlertDialog.Builder alert = new AlertDialog.Builder(activity);
- alert.setTitle(title);
-
- View view = inflater.inflate(R.layout.file_dialog, null);
-
- mMessageTextView = (TextView) view.findViewById(R.id.message);
- mMessageTextView.setText(message);
-
- mFilename = (EditText) view.findViewById(R.id.input);
- mFilename.setText(defaultFile);
- mBrowse = (BootstrapButton) view.findViewById(R.id.btn_browse);
- mBrowse.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- // only .asc or .gpg files
- // setting it to text/plain prevents Cynaogenmod's file manager from selecting asc
- // or gpg types!
- FileHelper.openFile(FileDialogFragment.this, mFilename.getText().toString(), "*/*",
- REQUEST_CODE);
- }
- });
-
- mCheckBox = (CheckBox) view.findViewById(R.id.checkbox);
- if (checkboxText == null) {
- mCheckBox.setEnabled(false);
- mCheckBox.setVisibility(View.GONE);
- } else {
- mCheckBox.setEnabled(true);
- mCheckBox.setVisibility(View.VISIBLE);
- mCheckBox.setText(checkboxText);
- }
-
- alert.setView(view);
-
- alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int id) {
- dismiss();
-
- boolean checked = false;
- if (mCheckBox.isEnabled()) {
- checked = mCheckBox.isChecked();
- }
-
- // return resulting data back to activity
- Bundle data = new Bundle();
- data.putString(MESSAGE_DATA_FILENAME, mFilename.getText().toString());
- data.putBoolean(MESSAGE_DATA_CHECKED, checked);
-
- sendMessageToHandler(MESSAGE_OKAY, data);
- }
- });
-
- alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int id) {
- dismiss();
- }
- });
- return alert.create();
- }
-
- /**
- * Updates filename in dialog, normally called in onActivityResult in activity using the
- * FileDialog
- */
- private void setFilename(String filename) {
- AlertDialog dialog = (AlertDialog) getDialog();
- EditText filenameEditText = (EditText) dialog.findViewById(R.id.input);
-
- if (filenameEditText != null) {
- filenameEditText.setText(filename);
- }
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode & 0xFFFF) {
- case REQUEST_CODE: {
- if (resultCode == Activity.RESULT_OK && data != null) {
- try {
- String path = data.getData().getPath();
- Log.d(Constants.TAG, "path=" + path);
-
- // set filename used in export/import dialogs
- setFilename(path);
- } catch (NullPointerException e) {
- Log.e(Constants.TAG, "Nullpointer while retrieving path!", e);
- }
- }
-
- break;
- }
-
- default:
- super.onActivityResult(requestCode, resultCode, data);
-
- break;
- }
- }
-
- /**
- * Send message back to handler which is initialized in a activity
- *
- * @param what Message integer you want to send
- */
- private void sendMessageToHandler(Integer what, Bundle data) {
- Message msg = Message.obtain();
- msg.what = what;
- if (data != null) {
- msg.setData(data);
- }
-
- try {
- mMessenger.send(msg);
- } catch (RemoteException e) {
- Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
- } catch (NullPointerException e) {
- Log.w(Constants.TAG, "Messenger is null!", e);
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
deleted file mode 100644
index a3feab959..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.dialog;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.app.FragmentActivity;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.WindowManager.LayoutParams;
-import android.view.inputmethod.EditorInfo;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
-import android.widget.TextView.OnEditorActionListener;
-import android.widget.Toast;
-import org.spongycastle.openpgp.PGPException;
-import org.spongycastle.openpgp.PGPPrivateKey;
-import org.spongycastle.openpgp.PGPSecretKey;
-import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
-import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.service.PassphraseCacheService;
-import org.sufficientlysecure.keychain.util.Log;
-
-public class PassphraseDialogFragment extends DialogFragment implements OnEditorActionListener {
- private static final String ARG_MESSENGER = "messenger";
- private static final String ARG_SECRET_KEY_ID = "secret_key_id";
-
- public static final int MESSAGE_OKAY = 1;
- public static final int MESSAGE_CANCEL = 2;
-
- public static final String MESSAGE_DATA_PASSPHRASE = "passphrase";
-
- private Messenger mMessenger;
- private EditText mPassphraseEditText;
- private boolean mCanKB;
-
- /**
- * Shows passphrase dialog to cache a new passphrase the user enters for using it later for
- * encryption. Based on mSecretKeyId it asks for a passphrase to open a private key or it asks
- * for a symmetric passphrase
- */
- public static void show(FragmentActivity context, long keyId, Handler returnHandler) {
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(returnHandler);
-
- try {
- PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(context,
- messenger, keyId);
-
- passphraseDialog.show(context.getSupportFragmentManager(), "passphraseDialog");
- } catch (PgpGeneralException e) {
- Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
- // send message to handler to start encryption directly
- returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
- }
- }
-
- /**
- * Creates new instance of this dialog fragment
- *
- * @param secretKeyId secret key id you want to use
- * @param messenger to communicate back after caching the passphrase
- * @return
- * @throws PgpGeneralException
- */
- public static PassphraseDialogFragment newInstance(Context context, Messenger messenger,
- long secretKeyId) throws PgpGeneralException {
- // check if secret key has a passphrase
- if (!(secretKeyId == Id.key.symmetric || secretKeyId == Id.key.none)) {
- if (!PassphraseCacheService.hasPassphrase(context, secretKeyId)) {
- throw new PgpGeneralException("No passphrase! No passphrase dialog needed!");
- }
- }
-
- PassphraseDialogFragment frag = new PassphraseDialogFragment();
- Bundle args = new Bundle();
- args.putLong(ARG_SECRET_KEY_ID, secretKeyId);
- args.putParcelable(ARG_MESSENGER, messenger);
-
- frag.setArguments(args);
-
- return frag;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- }
-
- /**
- * Creates dialog
- */
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final Activity activity = getActivity();
- final long secretKeyId = getArguments().getLong(ARG_SECRET_KEY_ID);
- mMessenger = getArguments().getParcelable(ARG_MESSENGER);
-
- AlertDialog.Builder alert = new AlertDialog.Builder(activity);
-
- alert.setTitle(R.string.title_authentication);
-
- final PGPSecretKey secretKey;
-
- if (secretKeyId == Id.key.symmetric || secretKeyId == Id.key.none) {
- secretKey = null;
- alert.setMessage(R.string.passphrase_for_symmetric_encryption);
- } else {
- secretKey = ProviderHelper.getPGPSecretKeyRing(activity, secretKeyId).getSecretKey();
-
- if (secretKey == null) {
- alert.setTitle(R.string.title_key_not_found);
- alert.setMessage(getString(R.string.key_not_found, secretKeyId));
- alert.setPositiveButton(android.R.string.ok, new OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dismiss();
- }
- });
- alert.setCancelable(false);
- mCanKB = false;
- return alert.create();
- }
- String userId = PgpKeyHelper.getMainUserIdSafe(activity, secretKey);
-
- Log.d(Constants.TAG, "User id: '" + userId + "'");
- alert.setMessage(getString(R.string.passphrase_for, userId));
- }
-
- LayoutInflater inflater = activity.getLayoutInflater();
- View view = inflater.inflate(R.layout.passphrase_dialog, null);
- alert.setView(view);
-
- mPassphraseEditText = (EditText) view.findViewById(R.id.passphrase_passphrase);
-
- alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int id) {
- dismiss();
- long curKeyIndex = 1;
- boolean keyOK = true;
- String passphrase = mPassphraseEditText.getText().toString();
- long keyId;
- PGPSecretKey clickSecretKey = secretKey;
-
- if (clickSecretKey != null) {
- while (keyOK) {
- if (clickSecretKey != null) { // check again for loop
- try {
- PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
- passphrase.toCharArray());
- PGPPrivateKey testKey = clickSecretKey
- .extractPrivateKey(keyDecryptor);
- if (testKey == null) {
- if (!clickSecretKey.isMasterKey()) {
- Toast.makeText(activity,
- R.string.error_could_not_extract_private_key,
- Toast.LENGTH_SHORT).show();
-
- sendMessageToHandler(MESSAGE_CANCEL);
- return;
- } else {
- clickSecretKey = PgpKeyHelper.getKeyNum(ProviderHelper
- .getPGPSecretKeyRingWithKeyId(activity, secretKeyId),
- curKeyIndex);
- curKeyIndex++; // does post-increment work like C?
- continue;
- }
- } else {
- keyOK = false;
- }
- } catch (PGPException e) {
- Toast.makeText(activity, R.string.wrong_passphrase,
- Toast.LENGTH_SHORT).show();
-
- sendMessageToHandler(MESSAGE_CANCEL);
- return;
- }
- } else {
- Toast.makeText(activity, R.string.error_could_not_extract_private_key,
- Toast.LENGTH_SHORT).show();
-
- sendMessageToHandler(MESSAGE_CANCEL);
- return; // ran out of keys to try
- }
- }
- keyId = secretKey.getKeyID();
- } else {
- keyId = Id.key.symmetric;
- }
-
- // cache the new passphrase
- Log.d(Constants.TAG, "Everything okay! Caching entered passphrase");
- PassphraseCacheService.addCachedPassphrase(activity, keyId, passphrase);
- if (!keyOK && clickSecretKey.getKeyID() != keyId) {
- PassphraseCacheService.addCachedPassphrase(activity, clickSecretKey.getKeyID(),
- passphrase);
- }
-
- // also return passphrase back to activity
- Bundle data = new Bundle();
- data.putString(MESSAGE_DATA_PASSPHRASE, passphrase);
-
- sendMessageToHandler(MESSAGE_OKAY, data);
- }
- });
-
- alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int id) {
- dialog.cancel();
- }
- });
-
- mCanKB = true;
- return alert.create();
- }
-
- @Override
- public void onActivityCreated(Bundle arg0) {
- super.onActivityCreated(arg0);
- if (mCanKB) {
- // request focus and open soft keyboard
- mPassphraseEditText.requestFocus();
- getDialog().getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
-
- mPassphraseEditText.setOnEditorActionListener(this);
- }
- }
-
- @Override
- public void onCancel(DialogInterface dialog) {
- super.onCancel(dialog);
-
- dismiss();
- sendMessageToHandler(MESSAGE_CANCEL);
- }
-
- /**
- * Associate the "done" button on the soft keyboard with the okay button in the view
- */
- @Override
- public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- if (EditorInfo.IME_ACTION_DONE == actionId) {
- AlertDialog dialog = ((AlertDialog) getDialog());
- Button bt = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
-
- bt.performClick();
- return true;
- }
- return false;
- }
-
- /**
- * Send message back to handler which is initialized in a activity
- *
- * @param what Message integer you want to send
- */
- private void sendMessageToHandler(Integer what) {
- Message msg = Message.obtain();
- msg.what = what;
-
- try {
- mMessenger.send(msg);
- } catch (RemoteException e) {
- Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
- } catch (NullPointerException e) {
- Log.w(Constants.TAG, "Messenger is null!", e);
- }
- }
-
- /**
- * Send message back to handler which is initialized in a activity
- *
- * @param what Message integer you want to send
- */
- private void sendMessageToHandler(Integer what, Bundle data) {
- Message msg = Message.obtain();
- msg.what = what;
- if (data != null) {
- msg.setData(data);
- }
-
- try {
- mMessenger.send(msg);
- } catch (RemoteException e) {
- Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
- } catch (NullPointerException e) {
- Log.w(Constants.TAG, "Messenger is null!", e);
- }
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java
deleted file mode 100644
index 132a2ce86..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.dialog;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.DialogInterface.OnKeyListener;
-import android.os.Bundle;
-import android.support.v4.app.DialogFragment;
-import android.view.KeyEvent;
-import org.sufficientlysecure.keychain.R;
-
-public class ProgressDialogFragment extends DialogFragment {
- private static final String ARG_MESSAGE = "message";
- private static final String ARG_STYLE = "style";
- private static final String ARG_CANCELABLE = "cancelable";
-
- private OnCancelListener mOnCancelListener;
-
- /**
- * Creates new instance of this fragment
- *
- * @param message
- * @param style
- * @param cancelable
- * @return
- */
- public static ProgressDialogFragment newInstance(String message, int style, boolean cancelable,
- OnCancelListener onCancelListener) {
- ProgressDialogFragment frag = new ProgressDialogFragment();
- Bundle args = new Bundle();
- args.putString(ARG_MESSAGE, message);
- args.putInt(ARG_STYLE, style);
- args.putBoolean(ARG_CANCELABLE, cancelable);
-
- frag.setArguments(args);
- frag.mOnCancelListener = onCancelListener;
-
- return frag;
- }
-
- /**
- * Updates progress of dialog
- *
- * @param messageId
- * @param progress
- * @param max
- */
- public void setProgress(int messageId, int progress, int max) {
- setProgress(getString(messageId), progress, max);
- }
-
- /**
- * Updates progress of dialog
- *
- * @param progress
- * @param max
- */
- public void setProgress(int progress, int max) {
- ProgressDialog dialog = (ProgressDialog) getDialog();
-
- dialog.setProgress(progress);
- dialog.setMax(max);
- }
-
- /**
- * Updates progress of dialog
- *
- * @param message
- * @param progress
- * @param max
- */
- public void setProgress(String message, int progress, int max) {
- ProgressDialog dialog = (ProgressDialog) getDialog();
-
- dialog.setMessage(message);
- dialog.setProgress(progress);
- dialog.setMax(max);
- }
-
- @Override
- public void onCancel(DialogInterface dialog) {
- super.onCancel(dialog);
-
- if (this.mOnCancelListener != null) {
- this.mOnCancelListener.onCancel(dialog);
- }
- }
-
- /**
- * Creates dialog
- */
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final Activity activity = getActivity();
-
- ProgressDialog dialog = new ProgressDialog(activity);
- dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
- dialog.setCancelable(false);
- dialog.setCanceledOnTouchOutside(false);
-
- String message = getArguments().getString(ARG_MESSAGE);
- int style = getArguments().getInt(ARG_STYLE);
- boolean cancelable = getArguments().getBoolean(ARG_CANCELABLE);
-
- dialog.setMessage(message);
- dialog.setProgressStyle(style);
-
- if (cancelable) {
- dialog.setButton(DialogInterface.BUTTON_NEGATIVE,
- activity.getString(R.string.progress_cancel),
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.cancel();
- }
- });
- }
-
- // Disable the back button
- OnKeyListener keyListener = new OnKeyListener() {
-
- @Override
- public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK) {
- return true;
- }
- return false;
- }
-
- };
- dialog.setOnKeyListener(keyListener);
-
- return dialog;
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
deleted file mode 100644
index ae61c1470..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.dialog;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.support.v4.app.DialogFragment;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.WindowManager.LayoutParams;
-import android.view.inputmethod.EditorInfo;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
-import android.widget.TextView.OnEditorActionListener;
-import android.widget.Toast;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.util.Log;
-
-public class SetPassphraseDialogFragment extends DialogFragment implements OnEditorActionListener {
- private static final String ARG_MESSENGER = "messenger";
- private static final String ARG_TITLE = "title";
-
- public static final int MESSAGE_OKAY = 1;
-
- public static final String MESSAGE_NEW_PASSPHRASE = "new_passphrase";
-
- private Messenger mMessenger;
- private EditText mPassphraseEditText;
- private EditText mPassphraseAgainEditText;
-
- /**
- * Creates new instance of this dialog fragment
- *
- * @param title title of dialog
- * @param messenger to communicate back after setting the passphrase
- * @return
- */
- public static SetPassphraseDialogFragment newInstance(Messenger messenger, int title) {
- SetPassphraseDialogFragment frag = new SetPassphraseDialogFragment();
- Bundle args = new Bundle();
- args.putInt(ARG_TITLE, title);
- args.putParcelable(ARG_MESSENGER, messenger);
-
- frag.setArguments(args);
-
- return frag;
- }
-
- /**
- * Creates dialog
- */
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final Activity activity = getActivity();
-
- int title = getArguments().getInt(ARG_TITLE);
- mMessenger = getArguments().getParcelable(ARG_MESSENGER);
-
- AlertDialog.Builder alert = new AlertDialog.Builder(activity);
-
- alert.setTitle(title);
- alert.setMessage(R.string.enter_passphrase_twice);
-
- LayoutInflater inflater = activity.getLayoutInflater();
- View view = inflater.inflate(R.layout.passphrase_repeat_dialog, null);
- alert.setView(view);
-
- mPassphraseEditText = (EditText) view.findViewById(R.id.passphrase_passphrase);
- mPassphraseAgainEditText = (EditText) view.findViewById(R.id.passphrase_passphrase_again);
-
- alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int id) {
- dismiss();
-
- String passphrase1 = mPassphraseEditText.getText().toString();
- String passphrase2 = mPassphraseAgainEditText.getText().toString();
- if (!passphrase1.equals(passphrase2)) {
- Toast.makeText(
- activity,
- getString(R.string.error_message,
- getString(R.string.passphrases_do_not_match)), Toast.LENGTH_SHORT)
- .show();
- return;
- }
-
- if (passphrase1.equals("")) {
- Toast.makeText(
- activity,
- getString(R.string.error_message,
- getString(R.string.passphrase_must_not_be_empty)),
- Toast.LENGTH_SHORT).show();
- return;
- }
-
- // return resulting data back to activity
- Bundle data = new Bundle();
- data.putString(MESSAGE_NEW_PASSPHRASE, passphrase1);
-
- sendMessageToHandler(MESSAGE_OKAY, data);
- }
- });
-
- alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int id) {
- dismiss();
- }
- });
-
- return alert.create();
- }
-
- @Override
- public void onActivityCreated(Bundle arg0) {
- super.onActivityCreated(arg0);
-
- // request focus and open soft keyboard
- mPassphraseEditText.requestFocus();
- getDialog().getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
-
- mPassphraseAgainEditText.setOnEditorActionListener(this);
- }
-
- /**
- * Associate the "done" button on the soft keyboard with the okay button in the view
- */
- @Override
- public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- if (EditorInfo.IME_ACTION_DONE == actionId) {
- AlertDialog dialog = ((AlertDialog) getDialog());
- Button bt = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
-
- bt.performClick();
- return true;
- }
- return false;
- }
-
- /**
- * Send message back to handler which is initialized in a activity
- *
- * @param what Message integer you want to send
- */
- private void sendMessageToHandler(Integer what, Bundle data) {
- Message msg = Message.obtain();
- msg.what = what;
- if (data != null) {
- msg.setData(data);
- }
-
- try {
- mMessenger.send(msg);
- } catch (RemoteException e) {
- Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
- } catch (NullPointerException e) {
- Log.w(Constants.TAG, "Messenger is null!", e);
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java
deleted file mode 100644
index 741530b1d..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.dialog;
-
-import android.annotation.TargetApi;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.nfc.NfcAdapter;
-import android.os.Build;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.app.FragmentActivity;
-import org.sufficientlysecure.htmltextview.HtmlTextView;
-import org.sufficientlysecure.keychain.R;
-
-@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
-public class ShareNfcDialogFragment extends DialogFragment {
-
- /**
- * Creates new instance of this fragment
- */
- public static ShareNfcDialogFragment newInstance() {
- ShareNfcDialogFragment frag = new ShareNfcDialogFragment();
-
- return frag;
- }
-
- /**
- * Creates dialog
- */
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final FragmentActivity activity = getActivity();
-
- AlertDialog.Builder alert = new AlertDialog.Builder(activity);
-
- alert.setTitle(R.string.share_nfc_dialog);
- alert.setCancelable(true);
-
- alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int id) {
- dismiss();
- }
- });
-
- HtmlTextView textView = new HtmlTextView(getActivity());
- textView.setPadding(8, 8, 8, 8);
- alert.setView(textView);
-
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
- textView.setText(getString(R.string.error) + ": "
- + getString(R.string.error_jelly_bean_needed));
- } else {
- // check if NFC Adapter is available
- NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
- if (nfcAdapter == null) {
- textView.setText(getString(R.string.error) + ": "
- + getString(R.string.error_nfc_needed));
- } else {
- // nfc works...
- textView.setHtmlFromRawResource(getActivity(), R.raw.nfc_beam_share);
-
- alert.setNegativeButton(R.string.menu_beam_preferences,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int id) {
- Intent intentSettings = new Intent(
- Settings.ACTION_NFCSHARING_SETTINGS);
- startActivity(intentSettings);
- }
- });
- }
- }
-
- // no flickering when clicking textview for Android < 4
- // aboutTextView.setTextColor(getResources().getColor(android.R.color.black));
-
- return alert.create();
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
deleted file mode 100644
index b6ff139df..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.dialog;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.DialogFragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.TextView;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.util.QrCodeUtils;
-
-import java.util.ArrayList;
-
-public class ShareQrCodeDialogFragment extends DialogFragment {
- private static final String ARG_KEY_URI = "uri";
- private static final String ARG_FINGERPRINT_ONLY = "fingerprint_only";
-
- private ImageView mImage;
- private TextView mText;
-
- private boolean mFingerprintOnly;
-
- private ArrayList<String> mContentList;
- private int mCounter;
-
- private static final int QR_CODE_SIZE = 1000;
-
- /**
- * Creates new instance of this dialog fragment
- */
- public static ShareQrCodeDialogFragment newInstance(Uri dataUri, boolean fingerprintOnly) {
- ShareQrCodeDialogFragment frag = new ShareQrCodeDialogFragment();
- Bundle args = new Bundle();
- args.putParcelable(ARG_KEY_URI, dataUri);
- args.putBoolean(ARG_FINGERPRINT_ONLY, fingerprintOnly);
-
- frag.setArguments(args);
-
- return frag;
- }
-
- /**
- * Creates dialog
- */
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final Activity activity = getActivity();
-
- Uri dataUri = getArguments().getParcelable(ARG_KEY_URI);
- mFingerprintOnly = getArguments().getBoolean(ARG_FINGERPRINT_ONLY);
-
- AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
-
- alert.setTitle(R.string.share_qr_code_dialog_title);
-
- LayoutInflater inflater = activity.getLayoutInflater();
- View view = inflater.inflate(R.layout.share_qr_code_dialog, null);
- alert.setView(view);
-
- mImage = (ImageView) view.findViewById(R.id.share_qr_code_dialog_image);
- mText = (TextView) view.findViewById(R.id.share_qr_code_dialog_text);
-
- String content = null;
- if (mFingerprintOnly) {
- alert.setPositiveButton(R.string.btn_okay, null);
-
- byte[] blob = (byte[]) ProviderHelper.getGenericData(
- getActivity(), KeyRings.buildUnifiedKeyRingUri(dataUri),
- KeyRings.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB);
- if(blob == null) {
- // TODO error handling?!
- return null;
- }
-
- String fingerprint = PgpKeyHelper.convertFingerprintToHex(blob);
- mText.setText(getString(R.string.share_qr_code_dialog_fingerprint_text) + " " + fingerprint);
- content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
- setQrCode(content);
- } else {
- mText.setText(R.string.share_qr_code_dialog_start);
-
- // TODO works, but
- long masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri);
- // get public keyring as ascii armored string
- ArrayList<String> keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(
- getActivity(), new long[] { masterKeyId });
-
- // TODO: binary?
-
- content = keyringArmored.get(0);
-
- // OnClickListener are set in onResume to prevent automatic dismissing of Dialogs
- // http://bit.ly/O5vfaR
- alert.setPositiveButton(R.string.btn_next, null);
- alert.setNegativeButton(android.R.string.cancel, null);
-
- mContentList = splitString(content, 1000);
-
- // start with first
- mCounter = 0;
- updatePartsQrCode();
- }
-
- return alert.create();
- }
-
- @Override
- public void onResume() {
- super.onResume();
-
- if (!mFingerprintOnly) {
- AlertDialog alertDialog = (AlertDialog) getDialog();
- final Button backButton = alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
- final Button nextButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
-
- backButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (mCounter > 0) {
- mCounter--;
- updatePartsQrCode();
- updateDialog(backButton, nextButton);
- } else {
- dismiss();
- }
- }
- });
- nextButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
-
- if (mCounter < mContentList.size() - 1) {
- mCounter++;
- updatePartsQrCode();
- updateDialog(backButton, nextButton);
- } else {
- dismiss();
- }
- }
- });
- }
- }
-
- private void updatePartsQrCode() {
- // Content: <counter>,<size>,<content>
- setQrCode(mCounter + "," + mContentList.size() + "," + mContentList.get(mCounter));
- }
-
- private void setQrCode(String data) {
- mImage.setImageBitmap(QrCodeUtils.getQRCodeBitmap(data, QR_CODE_SIZE));
- }
-
- private void updateDialog(Button backButton, Button nextButton) {
- if (mCounter == 0) {
- backButton.setText(android.R.string.cancel);
- } else {
- backButton.setText(R.string.btn_back);
- }
- if (mCounter == mContentList.size() - 1) {
- nextButton.setText(android.R.string.ok);
- } else {
- nextButton.setText(R.string.btn_next);
- }
-
- mText.setText(getResources().getString(R.string.share_qr_code_dialog_progress,
- mCounter + 1, mContentList.size()));
- }
-
- /**
- * Split String by number of characters
- *
- * @param text
- * @param size
- * @return
- */
- private ArrayList<String> splitString(String text, int size) {
- ArrayList<String> strings = new ArrayList<String>();
- int index = 0;
- while (index < text.length()) {
- strings.add(text.substring(index, Math.min(index + size, text.length())));
- index += size;
- }
-
- return strings;
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/Editor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/Editor.java
deleted file mode 100644
index 7b21c189d..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/Editor.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui.widget;
-
-public interface Editor {
- public interface EditorListener {
- public void onDeleted(Editor editor, boolean wasNewItem);
- public void onEdited();
- }
-
- public void setEditorListener(EditorListener listener);
- public boolean needsSaving();
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FixedListView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FixedListView.java
deleted file mode 100644
index da29f808a..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FixedListView.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.widget;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.ListView;
-
-/**
- * Automatically calculate height of ListView based on contained items. This enables to put this
- * ListView into a ScrollView without messing up.
- * <p/>
- * from
- * http://stackoverflow.com/questions/2419246/how-do-i-create-a-listview-thats-not-in-a-scrollview-
- * or-has-the-scrollview-dis
- */
-public class FixedListView extends ListView {
-
- public FixedListView(Context context) {
- super(context);
- }
-
- public FixedListView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-
- public FixedListView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- // Calculate height of the entire list by providing a very large
- // height hint. But do not use the highest 2 bits of this integer;
- // those are reserved for the MeasureSpec mode.
- int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
- super.onMeasure(widthMeasureSpec, expandSpec);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java
deleted file mode 100644
index 6b2f3bf06..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui.widget;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import com.beardedhen.androidbootstrap.FontAwesomeText;
-import org.sufficientlysecure.keychain.R;
-
-/**
- * Class representing a LinearLayout that can fold and hide it's content when pressed
- * To use just add the following to your xml layout
-
- <org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- custom:foldedLabel="@string/TEXT_TO_DISPLAY_WHEN_FOLDED"
- custom:unFoldedLabel="@string/TEXT_TO_DISPLAY_WHEN_UNFOLDED"
- custom:foldedIcon="ICON_NAME_FROM_FontAwesomeText_TO_USE_WHEN_FOLDED"
- custom:unFoldedIcon="ICON_NAME_FROM_FontAwesomeText_TO_USE_WHEN_UNFOLDED">
-
- <include layout="@layout/ELEMENTS_TO_BE_FOLDED"/>
-
- </org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout>
-
- */
-public class FoldableLinearLayout extends LinearLayout {
-
- private FontAwesomeText mFoldableIcon;
- private boolean mFolded;
- private boolean mHasMigrated = false;
- private Integer mShortAnimationDuration = null;
- private TextView mFoldableTextView = null;
- private LinearLayout mFoldableContainer = null;
- private View mFoldableLayout = null;
-
- private String mFoldedIconName;
- private String mUnFoldedIconName;
- private String mFoldedLabel;
- private String mUnFoldedLabel;
-
- public FoldableLinearLayout(Context context) {
- super(context);
- processAttributes(context, null);
- }
-
- public FoldableLinearLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- processAttributes(context, attrs);
- }
-
- public FoldableLinearLayout(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs);
- processAttributes(context, attrs);
- }
-
- /**
- * Load given attributes to inner variables,
- * @param context
- * @param attrs
- */
- private void processAttributes(Context context, AttributeSet attrs) {
- if (attrs != null) {
- TypedArray a = context.obtainStyledAttributes(attrs,
- R.styleable.FoldableLinearLayout, 0, 0);
- mFoldedIconName = a.getString(R.styleable.FoldableLinearLayout_foldedIcon);
- mUnFoldedIconName = a.getString(R.styleable.FoldableLinearLayout_unFoldedIcon);
- mFoldedLabel = a.getString(R.styleable.FoldableLinearLayout_foldedLabel);
- mUnFoldedLabel = a.getString(R.styleable.FoldableLinearLayout_unFoldedLabel);
- a.recycle();
- }
- // If any attribute isn't found then set a default one
- mFoldedIconName = (mFoldedIconName == null) ? "fa-chevron-right" : mFoldedIconName;
- mUnFoldedIconName = (mUnFoldedIconName == null) ? "fa-chevron-down" : mUnFoldedIconName;
- mFoldedLabel = (mFoldedLabel == null) ? context.getString(R.id.none) : mFoldedLabel;
- mUnFoldedLabel = (mUnFoldedLabel == null) ? context.getString(R.id.none) : mUnFoldedLabel;
- }
-
- @Override
- protected void onFinishInflate() {
- // if the migration has already happened
- // there is no need to move any children
- if (!mHasMigrated) {
- migrateChildrenToContainer();
- mHasMigrated = true;
- }
-
- initialiseInnerViews();
-
- super.onFinishInflate();
- }
-
- /**
- * Migrates Child views as declared in xml to the inner foldableContainer
- */
- private void migrateChildrenToContainer() {
- // Collect children of FoldableLinearLayout as declared in XML
- int childNum = getChildCount();
- View[] children = new View[childNum];
-
- for (int i = 0; i < childNum; i++) {
- children[i] = getChildAt(i);
- }
- if (children[0].getId() == R.id.foldableControl) {
-
- }
-
- // remove all of them from FoldableLinearLayout
- detachAllViewsFromParent();
-
- // Inflate the inner foldable_linearlayout.xml
- LayoutInflater inflator = (LayoutInflater) getContext().getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
-
- mFoldableLayout = inflator.inflate(R.layout.foldable_linearlayout, this, true);
- mFoldableContainer = (LinearLayout) mFoldableLayout.findViewById(R.id.foldableContainer);
-
- // Push previously collected children into foldableContainer.
- for (int i = 0; i < childNum; i++) {
- addView(children[i]);
- }
- }
-
- private void initialiseInnerViews() {
- mFoldableIcon = (FontAwesomeText) mFoldableLayout.findViewById(R.id.foldableIcon);
- mFoldableIcon.setIcon(mFoldedIconName);
- mFoldableTextView = (TextView) mFoldableLayout.findViewById(R.id.foldableText);
- mFoldableTextView.setText(mFoldedLabel);
-
- // retrieve and cache the system's short animation time
- mShortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime);
-
- LinearLayout foldableControl = (LinearLayout) mFoldableLayout.findViewById(R.id.foldableControl);
- foldableControl.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- mFolded = !mFolded;
- if (mFolded) {
- mFoldableIcon.setIcon(mUnFoldedIconName);
- mFoldableContainer.setVisibility(View.VISIBLE);
- AlphaAnimation animation = new AlphaAnimation(0f, 1f);
- animation.setDuration(mShortAnimationDuration);
- mFoldableContainer.startAnimation(animation);
- mFoldableTextView.setText(mUnFoldedLabel);
-
- } else {
- mFoldableIcon.setIcon(mFoldedIconName);
- AlphaAnimation animation = new AlphaAnimation(1f, 0f);
- animation.setDuration(mShortAnimationDuration);
- animation.setAnimationListener(new Animation.AnimationListener() {
- @Override
- public void onAnimationStart(Animation animation) { }
-
- @Override
- public void onAnimationEnd(Animation animation) {
- // making sure that at the end the container is completely removed from view
- mFoldableContainer.setVisibility(View.GONE);
- }
-
- @Override
- public void onAnimationRepeat(Animation animation) { }
- });
- mFoldableContainer.startAnimation(animation);
- mFoldableTextView.setText(mFoldedLabel);
- }
- }
- });
-
- }
-
- /**
- * Adds provided child view to foldableContainer View
- * @param child
- */
- @Override
- public void addView(View child) {
- if (mFoldableContainer != null) {
- mFoldableContainer.addView(child);
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/IntegerListPreference.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/IntegerListPreference.java
deleted file mode 100644
index 6e1e4c678..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/IntegerListPreference.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package org.sufficientlysecure.keychain.ui.widget;
-
-import android.content.Context;
-import android.preference.ListPreference;
-import android.util.AttributeSet;
-
-/**
- * A list preference which persists its values as integers instead of strings. Code reading the
- * values should use {@link android.content.SharedPreferences#getInt}. When using XML-declared
- * arrays for entry values, the arrays should be regular string arrays containing valid integer
- * values.
- *
- * @author Rodrigo Damazio
- */
-public class IntegerListPreference extends ListPreference {
-
- public IntegerListPreference(Context context) {
- super(context);
-
- verifyEntryValues(null);
- }
-
- public IntegerListPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- verifyEntryValues(null);
- }
-
- @Override
- public void setEntryValues(CharSequence[] entryValues) {
- CharSequence[] oldValues = getEntryValues();
- super.setEntryValues(entryValues);
- verifyEntryValues(oldValues);
- }
-
- @Override
- public void setEntryValues(int entryValuesResId) {
- CharSequence[] oldValues = getEntryValues();
- super.setEntryValues(entryValuesResId);
- verifyEntryValues(oldValues);
- }
-
- @Override
- protected String getPersistedString(String defaultReturnValue) {
- // During initial load, there's no known default value
- int defaultIntegerValue = Integer.MIN_VALUE;
- if (defaultReturnValue != null) {
- defaultIntegerValue = Integer.parseInt(defaultReturnValue);
- }
-
- // When the list preference asks us to read a string, instead read an
- // integer.
- int value = getPersistedInt(defaultIntegerValue);
- return Integer.toString(value);
- }
-
- @Override
- protected boolean persistString(String value) {
- // When asked to save a string, instead save an integer
- return persistInt(Integer.parseInt(value));
- }
-
- private void verifyEntryValues(CharSequence[] oldValues) {
- CharSequence[] entryValues = getEntryValues();
- if (entryValues == null) {
- return;
- }
-
- for (CharSequence entryValue : entryValues) {
- try {
- Integer.parseInt(entryValue.toString());
- } catch (NumberFormatException nfe) {
- super.setEntryValues(oldValues);
- throw nfe;
- }
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java
deleted file mode 100644
index c7bd1c987..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui.widget;
-
-import android.annotation.TargetApi;
-import android.app.DatePickerDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.text.format.DateUtils;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.DatePicker;
-import android.widget.LinearLayout;
-import android.widget.TableLayout;
-import android.widget.TableRow;
-import android.widget.TextView;
-
-import com.beardedhen.androidbootstrap.BootstrapButton;
-
-import org.spongycastle.bcpg.sig.KeyFlags;
-import org.spongycastle.openpgp.PGPPublicKey;
-import org.spongycastle.openpgp.PGPSecretKey;
-
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.util.Choice;
-
-import java.text.DateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.TimeZone;
-import java.util.Vector;
-
-public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
- private PGPSecretKey mKey;
-
- private EditorListener mEditorListener = null;
-
- private boolean mIsMasterKey;
- BootstrapButton mDeleteButton;
- TextView mAlgorithm;
- TextView mKeyId;
- TextView mCreationDate;
- BootstrapButton mExpiryDateButton;
- GregorianCalendar mCreatedDate;
- GregorianCalendar mExpiryDate;
- GregorianCalendar mOriginalExpiryDate = null;
- CheckBox mChkCertify;
- CheckBox mChkSign;
- CheckBox mChkEncrypt;
- CheckBox mChkAuthenticate;
- int mUsage;
- int mOriginalUsage;
- boolean mIsNewKey;
-
- private CheckBox.OnCheckedChangeListener mCheckChanged = new CheckBox.OnCheckedChangeListener()
- {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
- {
- if (mEditorListener != null) {
- mEditorListener.onEdited();
- }
- }
- };
-
-
- private int mDatePickerResultCount = 0;
- private DatePickerDialog.OnDateSetListener mExpiryDateSetListener =
- new DatePickerDialog.OnDateSetListener() {
- public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
- // Note: Ignore results after the first one - android sends multiples.
- if (mDatePickerResultCount++ == 0) {
- GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
- date.set(year, monthOfYear, dayOfMonth);
- if (mOriginalExpiryDate != null) {
- long numDays = (date.getTimeInMillis() / 86400000) -
- (mOriginalExpiryDate.getTimeInMillis() / 86400000);
- if (numDays == 0) {
- setExpiryDate(mOriginalExpiryDate);
- } else {
- setExpiryDate(date);
- }
- } else {
- setExpiryDate(date);
- }
- if (mEditorListener != null) {
- mEditorListener.onEdited();
- }
- }
- }
- };
-
- public KeyEditor(Context context) {
- super(context);
- }
-
- public KeyEditor(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected void onFinishInflate() {
- setDrawingCacheEnabled(true);
- setAlwaysDrawnWithCacheEnabled(true);
-
- mAlgorithm = (TextView) findViewById(R.id.algorithm);
- mKeyId = (TextView) findViewById(R.id.keyId);
- mCreationDate = (TextView) findViewById(R.id.creation);
- mExpiryDateButton = (BootstrapButton) findViewById(R.id.expiry);
-
- mDeleteButton = (BootstrapButton) findViewById(R.id.delete);
- mDeleteButton.setOnClickListener(this);
- mChkCertify = (CheckBox) findViewById(R.id.chkCertify);
- mChkCertify.setOnCheckedChangeListener(mCheckChanged);
- mChkSign = (CheckBox) findViewById(R.id.chkSign);
- mChkSign.setOnCheckedChangeListener(mCheckChanged);
- mChkEncrypt = (CheckBox) findViewById(R.id.chkEncrypt);
- mChkEncrypt.setOnCheckedChangeListener(mCheckChanged);
- mChkAuthenticate = (CheckBox) findViewById(R.id.chkAuthenticate);
- mChkAuthenticate.setOnCheckedChangeListener(mCheckChanged);
-
- setExpiryDate(null);
-
- mExpiryDateButton.setOnClickListener(new OnClickListener() {
- @TargetApi(11)
- public void onClick(View v) {
- GregorianCalendar date = mExpiryDate;
- if (date == null) {
- date = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
- }
- /*
- * Using custom DatePickerDialog which overrides the setTitle because
- * the DatePickerDialog title is buggy (unix warparound bug).
- * See: https://code.google.com/p/android/issues/detail?id=49066
- */
- DatePickerDialog dialog = new ExpiryDatePickerDialog(getContext(),
- mExpiryDateSetListener, date.get(Calendar.YEAR), date.get(Calendar.MONTH),
- date.get(Calendar.DAY_OF_MONTH));
- mDatePickerResultCount = 0;
- dialog.setCancelable(true);
- dialog.setButton(Dialog.BUTTON_NEGATIVE,
- getContext().getString(R.string.btn_no_date),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- // Note: Ignore results after the first one - android sends multiples.
- if (mDatePickerResultCount++ == 0) {
- setExpiryDate(null);
- if (mEditorListener != null) {
- mEditorListener.onEdited();
- }
- }
- }
- });
-
- // setCalendarViewShown() is supported from API 11 onwards.
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
- // Hide calendarView in tablets because of the unix warparound bug.
- dialog.getDatePicker().setCalendarViewShown(false);
- }
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
- if (dialog != null && mCreatedDate != null) {
- dialog.getDatePicker()
- .setMinDate(
- mCreatedDate.getTime().getTime() + DateUtils.DAY_IN_MILLIS);
- } else {
- //When created date isn't available
- dialog.getDatePicker().setMinDate(date.getTime().getTime() + DateUtils.DAY_IN_MILLIS);
- }
- }
-
- dialog.show();
- }
- });
-
- super.onFinishInflate();
- }
-
- public void setCanBeEdited(boolean canBeEdited) {
- if (!canBeEdited) {
- mDeleteButton.setVisibility(View.INVISIBLE);
- mExpiryDateButton.setEnabled(false);
- mChkSign.setEnabled(false); //certify is always disabled
- mChkEncrypt.setEnabled(false);
- mChkAuthenticate.setEnabled(false);
- }
- }
-
- public void setValue(PGPSecretKey key, boolean isMasterKey, int usage, boolean isNewKey) {
- mKey = key;
-
- mIsMasterKey = isMasterKey;
- if (mIsMasterKey) {
- mDeleteButton.setVisibility(View.INVISIBLE);
- }
-
- mAlgorithm.setText(PgpKeyHelper.getAlgorithmInfo(key));
- String keyIdStr = PgpKeyHelper.convertKeyIdToHex(key.getKeyID());
- mKeyId.setText(keyIdStr);
-
- Vector<Choice> choices = new Vector<Choice>();
- boolean isElGamalKey = (key.getPublicKey().getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT);
- boolean isDSAKey = (key.getPublicKey().getAlgorithm() == PGPPublicKey.DSA);
- if (isElGamalKey) {
- mChkSign.setVisibility(View.INVISIBLE);
- TableLayout table = (TableLayout) findViewById(R.id.table_keylayout);
- TableRow row = (TableRow) findViewById(R.id.row_sign);
- table.removeView(row);
- }
- if (isDSAKey) {
- mChkEncrypt.setVisibility(View.INVISIBLE);
- TableLayout table = (TableLayout) findViewById(R.id.table_keylayout);
- TableRow row = (TableRow) findViewById(R.id.row_encrypt);
- table.removeView(row);
- }
- if (!mIsMasterKey) {
- mChkCertify.setVisibility(View.INVISIBLE);
- TableLayout table = (TableLayout) findViewById(R.id.table_keylayout);
- TableRow row = (TableRow) findViewById(R.id.row_certify);
- table.removeView(row);
- } else {
- TextView mLabelUsage2 = (TextView) findViewById(R.id.label_usage2);
- mLabelUsage2.setVisibility(View.INVISIBLE);
- }
-
- int selectId = 0;
- mIsNewKey = isNewKey;
- if (isNewKey) {
- mUsage = usage;
- mChkCertify.setChecked((usage & KeyFlags.CERTIFY_OTHER) == KeyFlags.CERTIFY_OTHER);
- mChkSign.setChecked((usage & KeyFlags.SIGN_DATA) == KeyFlags.SIGN_DATA);
- mChkEncrypt.setChecked(((usage & KeyFlags.ENCRYPT_COMMS) == KeyFlags.ENCRYPT_COMMS) ||
- ((usage & KeyFlags.ENCRYPT_STORAGE) == KeyFlags.ENCRYPT_STORAGE));
- mChkAuthenticate.setChecked((usage & KeyFlags.AUTHENTICATION) == KeyFlags.AUTHENTICATION);
- } else {
- mUsage = PgpKeyHelper.getKeyUsage(key);
- mOriginalUsage = mUsage;
- if (key.isMasterKey()) {
- mChkCertify.setChecked(PgpKeyHelper.isCertificationKey(key));
- }
- mChkSign.setChecked(PgpKeyHelper.isSigningKey(key));
- mChkEncrypt.setChecked(PgpKeyHelper.isEncryptionKey(key));
- mChkAuthenticate.setChecked(PgpKeyHelper.isAuthenticationKey(key));
- }
-
- GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
- cal.setTime(PgpKeyHelper.getCreationDate(key));
- setCreatedDate(cal);
- cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
- Date expiryDate = PgpKeyHelper.getExpiryDate(key);
- if (expiryDate == null) {
- setExpiryDate(null);
- } else {
- cal.setTime(PgpKeyHelper.getExpiryDate(key));
- setExpiryDate(cal);
- mOriginalExpiryDate = cal;
- }
-
- }
-
- public PGPSecretKey getValue() {
- return mKey;
- }
-
- public void onClick(View v) {
- final ViewGroup parent = (ViewGroup) getParent();
- if (v == mDeleteButton) {
- parent.removeView(this);
- if (mEditorListener != null) {
- mEditorListener.onDeleted(this, mIsNewKey);
- }
- }
- }
-
- public void setEditorListener(EditorListener listener) {
- mEditorListener = listener;
- }
-
- private void setCreatedDate(GregorianCalendar date) {
- mCreatedDate = date;
- if (date == null) {
- mCreationDate.setText(getContext().getString(R.string.none));
- } else {
- mCreationDate.setText(DateFormat.getDateInstance().format(date.getTime()));
- }
- }
-
- private void setExpiryDate(GregorianCalendar date) {
- mExpiryDate = date;
- if (date == null) {
- mExpiryDateButton.setText(getContext().getString(R.string.none));
- } else {
- mExpiryDateButton.setText(DateFormat.getDateInstance().format(date.getTime()));
- }
- }
-
- public GregorianCalendar getExpiryDate() {
- return mExpiryDate;
- }
-
- public int getUsage() {
- mUsage = (mUsage & ~KeyFlags.CERTIFY_OTHER) |
- (mChkCertify.isChecked() ? KeyFlags.CERTIFY_OTHER : 0);
- mUsage = (mUsage & ~KeyFlags.SIGN_DATA) |
- (mChkSign.isChecked() ? KeyFlags.SIGN_DATA : 0);
- mUsage = (mUsage & ~KeyFlags.ENCRYPT_COMMS) |
- (mChkEncrypt.isChecked() ? KeyFlags.ENCRYPT_COMMS : 0);
- mUsage = (mUsage & ~KeyFlags.ENCRYPT_STORAGE) |
- (mChkEncrypt.isChecked() ? KeyFlags.ENCRYPT_STORAGE : 0);
- mUsage = (mUsage & ~KeyFlags.AUTHENTICATION) |
- (mChkAuthenticate.isChecked() ? KeyFlags.AUTHENTICATION : 0);
-
- return mUsage;
- }
-
- public boolean needsSaving() {
- if (mIsNewKey) {
- return true;
- }
-
- boolean retval = (getUsage() != mOriginalUsage);
-
- boolean dateChanged;
- boolean mOEDNull = (mOriginalExpiryDate == null);
- boolean mEDNull = (mExpiryDate == null);
- if (mOEDNull != mEDNull) {
- dateChanged = true;
- } else {
- if (mOEDNull) {
- //both null, no change
- dateChanged = false;
- } else {
- dateChanged = ((mExpiryDate.compareTo(mOriginalExpiryDate)) != 0);
- }
- }
- retval |= dateChanged;
-
- return retval;
- }
-
- public boolean getIsNewKey() {
- return mIsNewKey;
- }
-}
-
-class ExpiryDatePickerDialog extends DatePickerDialog {
-
- public ExpiryDatePickerDialog(Context context, OnDateSetListener callBack,
- int year, int monthOfYear, int dayOfMonth) {
- super(context, callBack, year, monthOfYear, dayOfMonth);
- }
-
- //Set permanent title.
- public void setTitle(CharSequence title) {
- super.setTitle(getContext().getString(R.string.expiry_date_dialog_title));
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyServerEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyServerEditor.java
deleted file mode 100644
index 171763672..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyServerEditor.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui.widget;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import com.beardedhen.androidbootstrap.BootstrapButton;
-import org.sufficientlysecure.keychain.R;
-
-public class KeyServerEditor extends LinearLayout implements Editor, OnClickListener {
- private EditorListener mEditorListener = null;
-
- BootstrapButton mDeleteButton;
- TextView mServer;
-
- public KeyServerEditor(Context context) {
- super(context);
- }
-
- public KeyServerEditor(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected void onFinishInflate() {
- setDrawingCacheEnabled(true);
- setAlwaysDrawnWithCacheEnabled(true);
-
- mServer = (TextView) findViewById(R.id.server);
-
- mDeleteButton = (BootstrapButton) findViewById(R.id.delete);
- mDeleteButton.setOnClickListener(this);
-
- super.onFinishInflate();
- }
-
- public void setValue(String value) {
- mServer.setText(value);
- }
-
- public String getValue() {
- return mServer.getText().toString().trim();
- }
-
- public void onClick(View v) {
- final ViewGroup parent = (ViewGroup) getParent();
- if (v == mDeleteButton) {
- parent.removeView(this);
- if (mEditorListener != null) {
- mEditorListener.onDeleted(this, false);
- }
- }
- }
-
- @Override
- public boolean needsSaving() {
- return false;
- }
-
- public void setEditorListener(EditorListener listener) {
- mEditorListener = listener;
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java
deleted file mode 100644
index fb59cd3b7..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui.widget;
-
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Message;
-import android.os.Messenger;
-import android.support.v7.app.ActionBarActivity;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import com.beardedhen.androidbootstrap.BootstrapButton;
-
-import org.spongycastle.openpgp.PGPKeyFlags;
-import org.spongycastle.openpgp.PGPSecretKey;
-
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.service.PassphraseCacheService;
-import org.sufficientlysecure.keychain.ui.dialog.CreateKeyDialogFragment;
-import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
-import org.sufficientlysecure.keychain.ui.widget.Editor.EditorListener;
-import org.sufficientlysecure.keychain.util.Choice;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Vector;
-
-public class SectionView extends LinearLayout implements OnClickListener, EditorListener, Editor {
- private LayoutInflater mInflater;
- private BootstrapButton mPlusButton;
- private ViewGroup mEditors;
- private TextView mTitle;
- private int mType = 0;
- private EditorListener mEditorListener = null;
-
- private Choice mNewKeyAlgorithmChoice;
- private int mNewKeySize;
- private boolean mOldItemDeleted = false;
- private ArrayList<String> mDeletedIDs = new ArrayList<String>();
- private ArrayList<PGPSecretKey> mDeletedKeys = new ArrayList<PGPSecretKey>();
- private boolean mCanBeEdited = true;
-
- private ActionBarActivity mActivity;
-
- private ProgressDialogFragment mGeneratingDialog;
-
- public void setEditorListener(EditorListener listener) {
- mEditorListener = listener;
- }
-
- public SectionView(Context context) {
- super(context);
- mActivity = (ActionBarActivity) context;
- }
-
- public SectionView(Context context, AttributeSet attrs) {
- super(context, attrs);
- mActivity = (ActionBarActivity) context;
- }
-
- public ViewGroup getEditors() {
- return mEditors;
- }
-
- public void setType(int type) {
- mType = type;
- switch (type) {
- case Id.type.user_id: {
- mTitle.setText(R.string.section_user_ids);
- break;
- }
-
- case Id.type.key: {
- mTitle.setText(R.string.section_keys);
- break;
- }
-
- default: {
- break;
- }
- }
- }
-
- public void setCanBeEdited(boolean canBeEdited) {
- mCanBeEdited = canBeEdited;
- if (!mCanBeEdited) {
- mPlusButton.setVisibility(View.INVISIBLE);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void onFinishInflate() {
- mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- setDrawingCacheEnabled(true);
- setAlwaysDrawnWithCacheEnabled(true);
-
- mPlusButton = (BootstrapButton) findViewById(R.id.plusbutton);
- mPlusButton.setOnClickListener(this);
-
- mEditors = (ViewGroup) findViewById(R.id.editors);
- mTitle = (TextView) findViewById(R.id.title);
-
- updateEditorsVisible();
- super.onFinishInflate();
- }
-
- /**
- * {@inheritDoc}
- */
- public void onDeleted(Editor editor, boolean wasNewItem) {
- mOldItemDeleted |= !wasNewItem;
- if (mOldItemDeleted) {
- if (mType == Id.type.user_id) {
- mDeletedIDs.add(((UserIdEditor) editor).getOriginalID());
- } else if (mType == Id.type.key) {
- mDeletedKeys.add(((KeyEditor) editor).getValue());
- }
- }
- this.updateEditorsVisible();
- if (mEditorListener != null) {
- mEditorListener.onEdited();
- }
- }
-
- @Override
- public void onEdited() {
- if (mEditorListener != null) {
- mEditorListener.onEdited();
- }
- }
-
- protected void updateEditorsVisible() {
- final boolean hasChildren = mEditors.getChildCount() > 0;
- mEditors.setVisibility(hasChildren ? View.VISIBLE : View.GONE);
- }
-
- public boolean needsSaving() {
- //check each view for needs saving, take account of deleted items
- boolean ret = mOldItemDeleted;
- for (int i = 0; i < mEditors.getChildCount(); ++i) {
- Editor editor = (Editor) mEditors.getChildAt(i);
- ret |= editor.needsSaving();
- if (mType == Id.type.user_id) {
- ret |= ((UserIdEditor) editor).primarySwapped();
- }
- }
- return ret;
- }
-
- public boolean primaryChanged() {
- boolean ret = false;
- for (int i = 0; i < mEditors.getChildCount(); ++i) {
- Editor editor = (Editor) mEditors.getChildAt(i);
- if (mType == Id.type.user_id) {
- ret |= ((UserIdEditor) editor).primarySwapped();
- }
- }
- return ret;
- }
-
- public String getOriginalPrimaryID() {
- //NB: this will have to change when we change how Primary IDs are chosen, and so we need to be
- // careful about where Master key capabilities are stored... multiple primaries and
- // revoked ones make this harder than the simple case we are continuing to assume here
- for (int i = 0; i < mEditors.getChildCount(); ++i) {
- Editor editor = (Editor) mEditors.getChildAt(i);
- if (mType == Id.type.user_id) {
- if (((UserIdEditor) editor).getIsOriginallyMainUserID()) {
- return ((UserIdEditor) editor).getOriginalID();
- }
- }
- }
- return null;
- }
-
- public ArrayList<String> getOriginalIDs() {
- ArrayList<String> orig = new ArrayList<String>();
- if (mType == Id.type.user_id) {
- for (int i = 0; i < mEditors.getChildCount(); ++i) {
- UserIdEditor editor = (UserIdEditor) mEditors.getChildAt(i);
- if (editor.isMainUserId()) {
- orig.add(0, editor.getOriginalID());
- } else {
- orig.add(editor.getOriginalID());
- }
- }
- return orig;
- } else {
- return null;
- }
- }
-
- public ArrayList<String> getDeletedIDs() {
- return mDeletedIDs;
- }
-
- public ArrayList<PGPSecretKey> getDeletedKeys() {
- return mDeletedKeys;
- }
-
- public List<Boolean> getNeedsSavingArray() {
- ArrayList<Boolean> mList = new ArrayList<Boolean>();
- for (int i = 0; i < mEditors.getChildCount(); ++i) {
- Editor editor = (Editor) mEditors.getChildAt(i);
- mList.add(editor.needsSaving());
- }
- return mList;
- }
-
- public List<Boolean> getNewIDFlags() {
- ArrayList<Boolean> mList = new ArrayList<Boolean>();
- for (int i = 0; i < mEditors.getChildCount(); ++i) {
- UserIdEditor editor = (UserIdEditor) mEditors.getChildAt(i);
- if (editor.isMainUserId()) {
- mList.add(0, editor.getIsNewID());
- } else {
- mList.add(editor.getIsNewID());
- }
- }
- return mList;
- }
-
- public List<Boolean> getNewKeysArray() {
- ArrayList<Boolean> mList = new ArrayList<Boolean>();
- if (mType == Id.type.key) {
- for (int i = 0; i < mEditors.getChildCount(); ++i) {
- KeyEditor editor = (KeyEditor) mEditors.getChildAt(i);
- mList.add(editor.getIsNewKey());
- }
- }
- return mList;
- }
-
- /**
- * {@inheritDoc}
- */
- public void onClick(View v) {
- if (mCanBeEdited) {
- switch (mType) {
- case Id.type.user_id: {
- UserIdEditor view = (UserIdEditor) mInflater.inflate(
- R.layout.edit_key_user_id_item, mEditors, false);
- view.setEditorListener(this);
- view.setValue("", mEditors.getChildCount() == 0, true);
- mEditors.addView(view);
- if (mEditorListener != null) {
- mEditorListener.onEdited();
- }
- break;
- }
-
- case Id.type.key: {
- CreateKeyDialogFragment mCreateKeyDialogFragment =
- CreateKeyDialogFragment.newInstance(mEditors.getChildCount());
- mCreateKeyDialogFragment
- .setOnAlgorithmSelectedListener(
- new CreateKeyDialogFragment.OnAlgorithmSelectedListener() {
- @Override
- public void onAlgorithmSelected(Choice algorithmChoice, int keySize) {
- mNewKeyAlgorithmChoice = algorithmChoice;
- mNewKeySize = keySize;
- createKey();
- }
- });
- mCreateKeyDialogFragment.show(mActivity.getSupportFragmentManager(), "createKeyDialog");
- break;
- }
-
- default: {
- break;
- }
- }
- this.updateEditorsVisible();
- }
- }
-
- public void setUserIds(Vector<String> list) {
- if (mType != Id.type.user_id) {
- return;
- }
-
- mEditors.removeAllViews();
- for (String userId : list) {
- UserIdEditor view = (UserIdEditor) mInflater.inflate(R.layout.edit_key_user_id_item,
- mEditors, false);
- view.setEditorListener(this);
- view.setValue(userId, mEditors.getChildCount() == 0, false);
- view.setCanBeEdited(mCanBeEdited);
- mEditors.addView(view);
- }
-
- this.updateEditorsVisible();
- }
-
- public void setKeys(Vector<PGPSecretKey> list, Vector<Integer> usages, boolean newKeys) {
- if (mType != Id.type.key) {
- return;
- }
-
- mEditors.removeAllViews();
-
- // go through all keys and set view based on them
- for (int i = 0; i < list.size(); i++) {
- KeyEditor view = (KeyEditor) mInflater.inflate(R.layout.edit_key_key_item, mEditors,
- false);
- view.setEditorListener(this);
- boolean isMasterKey = (mEditors.getChildCount() == 0);
- view.setValue(list.get(i), isMasterKey, usages.get(i), newKeys);
- view.setCanBeEdited(mCanBeEdited);
- mEditors.addView(view);
- }
-
- this.updateEditorsVisible();
- }
-
- private void createKey() {
- // Send all information needed to service to edit key in other thread
- final Intent intent = new Intent(mActivity, KeychainIntentService.class);
-
- intent.setAction(KeychainIntentService.ACTION_GENERATE_KEY);
-
- // fill values for this action
- Bundle data = new Bundle();
- Boolean isMasterKey;
-
- String passphrase;
- if (mEditors.getChildCount() > 0) {
- PGPSecretKey masterKey = ((KeyEditor) mEditors.getChildAt(0)).getValue();
- passphrase = PassphraseCacheService
- .getCachedPassphrase(mActivity, masterKey.getKeyID());
- isMasterKey = false;
- } else {
- passphrase = "";
- isMasterKey = true;
- }
- data.putBoolean(KeychainIntentService.GENERATE_KEY_MASTER_KEY, isMasterKey);
- data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passphrase);
- data.putInt(KeychainIntentService.GENERATE_KEY_ALGORITHM, mNewKeyAlgorithmChoice.getId());
- data.putInt(KeychainIntentService.GENERATE_KEY_KEY_SIZE, mNewKeySize);
-
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
-
- // show progress dialog
- mGeneratingDialog = ProgressDialogFragment.newInstance(
- getResources().getQuantityString(R.plurals.progress_generating, 1),
- ProgressDialog.STYLE_SPINNER,
- true,
- new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- mActivity.stopService(intent);
- }
- });
-
- // Message is received after generating is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(mActivity,
- mGeneratingDialog) {
- public void handleMessage(Message message) {
- // handle messages by standard KeychainIntentServiceHandler first
- super.handleMessage(message);
-
- if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- // get new key from data bundle returned from service
- Bundle data = message.getData();
- PGPSecretKey newKey = (PGPSecretKey) PgpConversionHelper
- .BytesToPGPSecretKey(data
- .getByteArray(KeychainIntentService.RESULT_NEW_KEY));
- addGeneratedKeyToView(newKey);
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
-
- mGeneratingDialog.show(mActivity.getSupportFragmentManager(), "dialog");
-
- // start service with intent
- mActivity.startService(intent);
- }
-
- private void addGeneratedKeyToView(PGPSecretKey newKey) {
- // add view with new key
- KeyEditor view = (KeyEditor) mInflater.inflate(R.layout.edit_key_key_item,
- mEditors, false);
- view.setEditorListener(SectionView.this);
- int usage = 0;
- if (mEditors.getChildCount() == 0) {
- usage = PGPKeyFlags.CAN_CERTIFY;
- }
- view.setValue(newKey, newKey.isMasterKey(), usage, true);
- mEditors.addView(view);
- SectionView.this.updateEditorsVisible();
- if (mEditorListener != null) {
- mEditorListener.onEdited();
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UnderlineTextView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UnderlineTextView.java
deleted file mode 100644
index 937a48e48..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UnderlineTextView.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2013 Eric Frohnhoefer
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui.widget;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.widget.TextView;
-
-/**
- * Copied from StickyListHeaders lib example
- *
- * @author Eric Frohnhoefer
- */
-public class UnderlineTextView extends TextView {
- private final Paint mPaint = new Paint();
- private int mUnderlineHeight = 0;
-
- public UnderlineTextView(Context context) {
- this(context, null);
- }
-
- public UnderlineTextView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public UnderlineTextView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
-
- init(context, attrs);
- }
-
- private void init(Context context, AttributeSet attrs) {
- Resources r = getResources();
- mUnderlineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2,
- r.getDisplayMetrics());
- }
-
- @Override
- public void setPadding(int left, int top, int right, int bottom) {
- super.setPadding(left, top, right, bottom + mUnderlineHeight);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- // Draw the underline the same color as the text
- mPaint.setColor(getTextColors().getDefaultColor());
- canvas.drawRect(0, getHeight() - mUnderlineHeight, getWidth(), getHeight(), mPaint);
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java
deleted file mode 100644
index 2253872d5..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui.widget;
-
-import android.content.Context;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.util.AttributeSet;
-import android.util.Patterns;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.AutoCompleteTextView;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.RadioButton;
-import com.beardedhen.androidbootstrap.BootstrapButton;
-
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.ContactHelper;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-
-import java.util.regex.Matcher;
-
-public class UserIdEditor extends LinearLayout implements Editor, OnClickListener {
- private EditorListener mEditorListener = null;
-
- private BootstrapButton mDeleteButton;
- private RadioButton mIsMainUserId;
- private String mOriginalID;
- private EditText mName;
- private String mOriginalName;
- private AutoCompleteTextView mEmail;
- private String mOriginalEmail;
- private EditText mComment;
- private String mOriginalComment;
- private boolean mOriginallyMainUserID;
- private boolean mIsNewId;
-
- public void setCanBeEdited(boolean canBeEdited) {
- if (!canBeEdited) {
- mDeleteButton.setVisibility(View.INVISIBLE);
- mName.setEnabled(false);
- mIsMainUserId.setEnabled(false);
- mEmail.setEnabled(false);
- mComment.setEnabled(false);
- }
- }
-
- public static class InvalidEmailException extends Exception {
- static final long serialVersionUID = 0xf812773345L;
-
- public InvalidEmailException(String message) {
- super(message);
- }
- }
-
- public UserIdEditor(Context context) {
- super(context);
- }
-
- public UserIdEditor(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- TextWatcher mTextWatcher = new TextWatcher() {
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- }
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- if (mEditorListener != null) {
- mEditorListener.onEdited();
- }
- }
- };
-
- @Override
- protected void onFinishInflate() {
- setDrawingCacheEnabled(true);
- setAlwaysDrawnWithCacheEnabled(true);
-
- mDeleteButton = (BootstrapButton) findViewById(R.id.delete);
- mDeleteButton.setOnClickListener(this);
- mIsMainUserId = (RadioButton) findViewById(R.id.isMainUserId);
- mIsMainUserId.setOnClickListener(this);
-
- mName = (EditText) findViewById(R.id.name);
- mName.addTextChangedListener(mTextWatcher);
- mEmail = (AutoCompleteTextView) findViewById(R.id.email);
- mComment = (EditText) findViewById(R.id.comment);
- mComment.addTextChangedListener(mTextWatcher);
-
-
- mEmail.setThreshold(1); // Start working from first character
- mEmail.setAdapter(
- new ArrayAdapter<String>
- (this.getContext(), android.R.layout.simple_dropdown_item_1line,
- ContactHelper.getMailAccounts(getContext())
- ));
- mEmail.addTextChangedListener(new TextWatcher(){
- @Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { }
-
- @Override
- public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { }
-
- @Override
- public void afterTextChanged(Editable editable) {
- String email = editable.toString();
- if (email.length() > 0) {
- Matcher emailMatcher = Patterns.EMAIL_ADDRESS.matcher(email);
- if (emailMatcher.matches()) {
- mEmail.setCompoundDrawablesWithIntrinsicBounds(0, 0,
- android.R.drawable.presence_online, 0);
- } else {
- mEmail.setCompoundDrawablesWithIntrinsicBounds(0, 0,
- android.R.drawable.presence_offline, 0);
- }
- } else {
- // remove drawable if email is empty
- mEmail.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
- }
- if (mEditorListener != null) {
- mEditorListener.onEdited();
- }
- }
- });
-
- super.onFinishInflate();
- }
-
- public void setValue(String userId, boolean isMainID, boolean isNewId) {
-
- mName.setText("");
- mOriginalName = "";
- mComment.setText("");
- mOriginalComment = "";
- mEmail.setText("");
- mOriginalEmail = "";
- mIsNewId = isNewId;
- mOriginalID = userId;
-
- String[] result = PgpKeyHelper.splitUserId(userId);
- if (result[0] != null) {
- mName.setText(result[0]);
- mOriginalName = result[0];
- }
- if (result[1] != null) {
- mEmail.setText(result[1]);
- mOriginalEmail = result[1];
- }
- if (result[2] != null) {
- mComment.setText(result[2]);
- mOriginalComment = result[2];
- }
-
- mOriginallyMainUserID = isMainID;
- setIsMainUserId(isMainID);
- }
-
- public String getValue() {
- String name = ("" + mName.getText()).trim();
- String email = ("" + mEmail.getText()).trim();
- String comment = ("" + mComment.getText()).trim();
-
- String userId = name;
- if (comment.length() > 0) {
- userId += " (" + comment + ")";
- }
- if (email.length() > 0) {
- userId += " <" + email + ">";
- }
-
- if (userId.equals("")) {
- // ok, empty one...
- return userId;
- }
- //TODO: check gpg accepts an entirely empty ID packet. specs say this is allowed
- return userId;
- }
-
- public void onClick(View v) {
- final ViewGroup parent = (ViewGroup) getParent();
- if (v == mDeleteButton) {
- boolean wasMainUserId = mIsMainUserId.isChecked();
- parent.removeView(this);
- if (mEditorListener != null) {
- mEditorListener.onDeleted(this, mIsNewId);
- }
- if (wasMainUserId && parent.getChildCount() > 0) {
- UserIdEditor editor = (UserIdEditor) parent.getChildAt(0);
- editor.setIsMainUserId(true);
- }
- } else if (v == mIsMainUserId) {
- for (int i = 0; i < parent.getChildCount(); ++i) {
- UserIdEditor editor = (UserIdEditor) parent.getChildAt(i);
- if (editor == this) {
- editor.setIsMainUserId(true);
- } else {
- editor.setIsMainUserId(false);
- }
- }
- if (mEditorListener != null) {
- mEditorListener.onEdited();
- }
- }
- }
-
- public void setIsMainUserId(boolean value) {
- mIsMainUserId.setChecked(value);
- }
-
- public boolean isMainUserId() {
- return mIsMainUserId.isChecked();
- }
-
- public void setEditorListener(EditorListener listener) {
- mEditorListener = listener;
- }
-
- @Override
- public boolean needsSaving() {
- boolean retval = false; //(mOriginallyMainUserID != isMainUserId());
- retval |= !(mOriginalName.equals(("" + mName.getText()).trim()));
- retval |= !(mOriginalEmail.equals(("" + mEmail.getText()).trim()));
- retval |= !(mOriginalComment.equals(("" + mComment.getText()).trim()));
- retval |= mIsNewId;
- return retval;
- }
-
- public boolean getIsOriginallyMainUserID() {
- return mOriginallyMainUserID;
- }
-
- public boolean primarySwapped() {
- return (mOriginallyMainUserID != isMainUserId());
- }
-
- public String getOriginalID() {
- return mOriginalID;
- }
-
- public boolean getIsNewID() { return mIsNewId; }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/AlgorithmNames.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/AlgorithmNames.java
deleted file mode 100644
index d2f4cc003..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/AlgorithmNames.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.util;
-
-import android.annotation.SuppressLint;
-import android.app.Activity;
-import org.spongycastle.bcpg.HashAlgorithmTags;
-import org.spongycastle.openpgp.PGPEncryptedData;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-
-import java.util.HashMap;
-
-@SuppressLint("UseSparseArrays")
-public class AlgorithmNames {
- Activity mActivity;
-
- HashMap<Integer, String> mEncryptionNames = new HashMap<Integer, String>();
- HashMap<Integer, String> mHashNames = new HashMap<Integer, String>();
- HashMap<Integer, String> mCompressionNames = new HashMap<Integer, String>();
-
- public AlgorithmNames(Activity context) {
- super();
- this.mActivity = context;
-
- mEncryptionNames.put(PGPEncryptedData.AES_128, "AES-128");
- mEncryptionNames.put(PGPEncryptedData.AES_192, "AES-192");
- mEncryptionNames.put(PGPEncryptedData.AES_256, "AES-256");
- mEncryptionNames.put(PGPEncryptedData.BLOWFISH, "Blowfish");
- mEncryptionNames.put(PGPEncryptedData.TWOFISH, "Twofish");
- mEncryptionNames.put(PGPEncryptedData.CAST5, "CAST5");
- mEncryptionNames.put(PGPEncryptedData.DES, "DES");
- mEncryptionNames.put(PGPEncryptedData.TRIPLE_DES, "Triple DES");
- mEncryptionNames.put(PGPEncryptedData.IDEA, "IDEA");
-
- mHashNames.put(HashAlgorithmTags.MD5, "MD5");
- mHashNames.put(HashAlgorithmTags.RIPEMD160, "RIPEMD-160");
- mHashNames.put(HashAlgorithmTags.SHA1, "SHA-1");
- mHashNames.put(HashAlgorithmTags.SHA224, "SHA-224");
- mHashNames.put(HashAlgorithmTags.SHA256, "SHA-256");
- mHashNames.put(HashAlgorithmTags.SHA384, "SHA-384");
- mHashNames.put(HashAlgorithmTags.SHA512, "SHA-512");
-
- mCompressionNames.put(Id.choice.compression.none, mActivity.getString(R.string.choice_none)
- + " (" + mActivity.getString(R.string.compression_fast) + ")");
- mCompressionNames.put(Id.choice.compression.zip,
- "ZIP (" + mActivity.getString(R.string.compression_fast) + ")");
- mCompressionNames.put(Id.choice.compression.zlib,
- "ZLIB (" + mActivity.getString(R.string.compression_fast) + ")");
- mCompressionNames.put(Id.choice.compression.bzip2,
- "BZIP2 (" + mActivity.getString(R.string.compression_very_slow) + ")");
- }
-
- public HashMap<Integer, String> getEncryptionNames() {
- return mEncryptionNames;
- }
-
- public void setEncryptionNames(HashMap<Integer, String> encryptionNames) {
- this.mEncryptionNames = encryptionNames;
- }
-
- public HashMap<Integer, String> getHashNames() {
- return mHashNames;
- }
-
- public void setHashNames(HashMap<Integer, String> hashNames) {
- this.mHashNames = hashNames;
- }
-
- public HashMap<Integer, String> getCompressionNames() {
- return mCompressionNames;
- }
-
- public void setCompressionNames(HashMap<Integer, String> compressionNames) {
- this.mCompressionNames = compressionNames;
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/Choice.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/Choice.java
deleted file mode 100644
index 1a6184d9c..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/Choice.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.util;
-
-public class Choice {
- private String mName;
- private int mId;
-
- public Choice() {
- mId = -1;
- mName = "";
- }
-
- public Choice(int id, String name) {
- mId = id;
- mName = name;
- }
-
- public int getId() {
- return mId;
- }
-
- public String getName() {
- return mName;
- }
-
- @Override
- public String toString() {
- return mName;
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java
deleted file mode 100644
index 5efc732e4..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2011 Thialfihar <thi@thialfihar.org>
- * Copyright (C) 2011 Senecaso
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.util;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.util.EntityUtils;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.pgp.PgpHelper;
-import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.HttpURLConnection;
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.GregorianCalendar;
-import java.util.List;
-import java.util.Locale;
-import java.util.TimeZone;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class HkpKeyServer extends KeyServer {
- private static class HttpError extends Exception {
- private static final long serialVersionUID = 1718783705229428893L;
- private int mCode;
- private String mData;
-
- public HttpError(int code, String data) {
- super("" + code + ": " + data);
- mCode = code;
- mData = data;
- }
-
- public int getCode() {
- return mCode;
- }
-
- public String getData() {
- return mData;
- }
- }
-
- private String mHost;
- private short mPort;
-
- /**
- * pub:%keyid%:%algo%:%keylen%:%creationdate%:%expirationdate%:%flags%
- * <ul>
- * <li>%<b>keyid</b>% = this is either the fingerprint or the key ID of the key.
- * Either the 16-digit or 8-digit key IDs are acceptable, but obviously the fingerprint is best.
- * </li>
- * <li>%<b>algo</b>% = the algorithm number, (i.e. 1==RSA, 17==DSA, etc).
- * See <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a></li>
- * <li>%<b>keylen</b>% = the key length (i.e. 1024, 2048, 4096, etc.)</li>
- * <li>%<b>creationdate</b>% = creation date of the key in standard
- * <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of
- * seconds since 1/1/1970 UTC time)</li>
- * <li>%<b>expirationdate</b>% = expiration date of the key in standard
- * <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of
- * seconds since 1/1/1970 UTC time)</li>
- * <li>%<b>flags</b>% = letter codes to indicate details of the key, if any. Flags may be in any
- * order. The meaning of "disabled" is implementation-specific. Note that individual flags may
- * be unimplemented, so the absence of a given flag does not necessarily mean the absence of the
- * detail.
- * <ul>
- * <li>r == revoked</li>
- * <li>d == disabled</li>
- * <li>e == expired</li>
- * </ul>
- * </li>
- * </ul>
- *
- * @see <a href="http://tools.ietf.org/html/draft-shaw-openpgp-hkp-00#section-5.2">
- * 5.2. Machine Readable Indexes</a>
- * in Internet-Draft OpenPGP HTTP Keyserver Protocol Document
- */
- public static final Pattern PUB_KEY_LINE = Pattern
- .compile("pub:([0-9a-fA-F]+):([0-9]+):([0-9]+):([0-9]+):([0-9]*):([rde]*)[ \n\r]*" // pub line
- + "(uid:(.*):([0-9]+):([0-9]*):([rde]*))+", // one or more uid lines
- Pattern.CASE_INSENSITIVE);
-
- /**
- * uid:%escaped uid string%:%creationdate%:%expirationdate%:%flags%
- * <ul>
- * <li>%<b>escaped uid string</b>% = the user ID string, with HTTP %-escaping for anything that
- * isn't 7-bit safe as well as for the ":" character. Any other characters may be escaped, as
- * desired.</li>
- * <li>%<b>creationdate</b>% = creation date of the key in standard
- * <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of
- * seconds since 1/1/1970 UTC time)</li>
- * <li>%<b>expirationdate</b>% = expiration date of the key in standard
- * <a href="http://tools.ietf.org/html/rfc2440#section-9.1">RFC-2440</a> form (i.e. number of
- * seconds since 1/1/1970 UTC time)</li>
- * <li>%<b>flags</b>% = letter codes to indicate details of the key, if any. Flags may be in any
- * order. The meaning of "disabled" is implementation-specific. Note that individual flags may
- * be unimplemented, so the absence of a given flag does not necessarily mean the absence of
- * the detail.
- * <ul>
- * <li>r == revoked</li>
- * <li>d == disabled</li>
- * <li>e == expired</li>
- * </ul>
- * </li>
- * </ul>
- */
- public static final Pattern UID_LINE = Pattern
- .compile("uid:(.*):([0-9]+):([0-9]*):([rde]*)",
- Pattern.CASE_INSENSITIVE);
-
- private static final short PORT_DEFAULT = 11371;
-
- /**
- * @param hostAndPort may be just
- * "<code>hostname</code>" (eg. "<code>pool.sks-keyservers.net</code>"), then it will
- * connect using {@link #PORT_DEFAULT}. However, port may be specified after colon
- * ("<code>hostname:port</code>", eg. "<code>p80.pool.sks-keyservers.net:80</code>").
- */
- public HkpKeyServer(String hostAndPort) {
- String host = hostAndPort;
- short port = PORT_DEFAULT;
- final int colonPosition = hostAndPort.lastIndexOf(':');
- if (colonPosition > 0) {
- host = hostAndPort.substring(0, colonPosition);
- final String portStr = hostAndPort.substring(colonPosition + 1);
- port = Short.decode(portStr);
- }
- mHost = host;
- mPort = port;
- }
-
- public HkpKeyServer(String host, short port) {
- mHost = host;
- mPort = port;
- }
-
- private static String readAll(InputStream in, String encoding) throws IOException {
- ByteArrayOutputStream raw = new ByteArrayOutputStream();
-
- byte buffer[] = new byte[1 << 16];
- int n = 0;
- while ((n = in.read(buffer)) != -1) {
- raw.write(buffer, 0, n);
- }
-
- if (encoding == null) {
- encoding = "utf8";
- }
- return raw.toString(encoding);
- }
-
- private String query(String request) throws QueryException, HttpError {
- InetAddress ips[];
- try {
- ips = InetAddress.getAllByName(mHost);
- } catch (UnknownHostException e) {
- throw new QueryException(e.toString());
- }
- for (int i = 0; i < ips.length; ++i) {
- try {
- String url = "http://" + ips[i].getHostAddress() + ":" + mPort + request;
- Log.d(Constants.TAG, "hkp keyserver query: " + url);
- URL realUrl = new URL(url);
- HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
- conn.setConnectTimeout(5000);
- conn.setReadTimeout(25000);
- conn.connect();
- int response = conn.getResponseCode();
- if (response >= 200 && response < 300) {
- return readAll(conn.getInputStream(), conn.getContentEncoding());
- } else {
- String data = readAll(conn.getErrorStream(), conn.getContentEncoding());
- throw new HttpError(response, data);
- }
- } catch (MalformedURLException e) {
- // nothing to do, try next IP
- } catch (IOException e) {
- // nothing to do, try next IP
- }
- }
-
- throw new QueryException("querying server(s) for '" + mHost + "' failed");
- }
-
- @Override
- public ArrayList<ImportKeysListEntry> search(String query) throws QueryException, TooManyResponses,
- InsufficientQuery {
- ArrayList<ImportKeysListEntry> results = new ArrayList<ImportKeysListEntry>();
-
- if (query.length() < 3) {
- throw new InsufficientQuery();
- }
-
- String encodedQuery;
- try {
- encodedQuery = URLEncoder.encode(query, "utf8");
- } catch (UnsupportedEncodingException e) {
- return null;
- }
- String request = "/pks/lookup?op=index&options=mr&search=" + encodedQuery;
-
- String data;
- try {
- data = query(request);
- } catch (HttpError e) {
- if (e.getCode() == 404) {
- return results;
- } else {
- if (e.getData().toLowerCase(Locale.US).contains("no keys found")) {
- return results;
- } else if (e.getData().toLowerCase(Locale.US).contains("too many")) {
- throw new TooManyResponses();
- } else if (e.getData().toLowerCase(Locale.US).contains("insufficient")) {
- throw new InsufficientQuery();
- }
- }
- throw new QueryException("querying server(s) for '" + mHost + "' failed");
- }
-
- final Matcher matcher = PUB_KEY_LINE.matcher(data);
- while (matcher.find()) {
- final ImportKeysListEntry entry = new ImportKeysListEntry();
-
- entry.setBitStrength(Integer.parseInt(matcher.group(3)));
-
- final int algorithmId = Integer.decode(matcher.group(2));
- entry.setAlgorithm(ImportKeysListEntry.getAlgorithmFromId(algorithmId));
-
- // group 1 contains the full fingerprint (v4) or the long key id if available
- // see http://bit.ly/1d4bxbk and http://bit.ly/1gD1wwr
- String fingerprintOrKeyId = matcher.group(1);
- if (fingerprintOrKeyId.length() > 16) {
- entry.setFingerPrintHex(fingerprintOrKeyId.toLowerCase(Locale.US));
- entry.setKeyIdHex("0x" + fingerprintOrKeyId.substring(fingerprintOrKeyId.length()
- - 16, fingerprintOrKeyId.length()));
- } else {
- // set key id only
- entry.setKeyIdHex("0x" + fingerprintOrKeyId);
- }
-
- final long creationDate = Long.parseLong(matcher.group(4));
- final GregorianCalendar tmpGreg = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
- tmpGreg.setTimeInMillis(creationDate * 1000);
- entry.setDate(tmpGreg.getTime());
-
- entry.setRevoked(matcher.group(6).contains("r"));
-
- ArrayList<String> userIds = new ArrayList<String>();
- final String uidLines = matcher.group(7);
- final Matcher uidMatcher = UID_LINE.matcher(uidLines);
- while (uidMatcher.find()) {
- String tmp = uidMatcher.group(1).trim();
- if (tmp.contains("%")) {
- try {
- // converts Strings like "Universit%C3%A4t" to a proper encoding form "Universität".
- tmp = (URLDecoder.decode(tmp, "UTF8"));
- } catch (UnsupportedEncodingException ignored) {
- // will never happen, because "UTF8" is supported
- }
- }
- userIds.add(tmp);
- }
- entry.setUserIds(userIds);
-
- results.add(entry);
- }
- return results;
- }
-
- @Override
- public String get(String keyIdHex) throws QueryException {
- HttpClient client = new DefaultHttpClient();
- try {
- String query = "http://" + mHost + ":" + mPort +
- "/pks/lookup?op=get&options=mr&search=" + keyIdHex;
- Log.d(Constants.TAG, "hkp keyserver get: " + query);
- HttpGet get = new HttpGet(query);
- HttpResponse response = client.execute(get);
- if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
- throw new QueryException("not found");
- }
-
- HttpEntity entity = response.getEntity();
- InputStream is = entity.getContent();
- String data = readAll(is, EntityUtils.getContentCharSet(entity));
- Matcher matcher = PgpHelper.PGP_PUBLIC_KEY.matcher(data);
- if (matcher.find()) {
- return matcher.group(1);
- }
- } catch (IOException e) {
- // nothing to do, better luck on the next keyserver
- } finally {
- client.getConnectionManager().shutdown();
- }
-
- return null;
- }
-
- @Override
- public void add(String armoredKey) throws AddKeyException {
- HttpClient client = new DefaultHttpClient();
- try {
- String query = "http://" + mHost + ":" + mPort + "/pks/add";
- HttpPost post = new HttpPost(query);
- Log.d(Constants.TAG, "hkp keyserver add: " + query);
- List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
- nameValuePairs.add(new BasicNameValuePair("keytext", armoredKey));
- post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
-
- HttpResponse response = client.execute(post);
- if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
- throw new AddKeyException();
- }
- } catch (IOException e) {
- // nothing to do, better luck on the next keyserver
- } finally {
- client.getConnectionManager().shutdown();
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java
deleted file mode 100644
index 28cfa11f2..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/InputData.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.util;
-
-import java.io.InputStream;
-
-public class InputData {
- private PositionAwareInputStream mInputStream;
- private long mSize;
-
- public InputData(InputStream inputStream, long size) {
- mInputStream = new PositionAwareInputStream(inputStream);
- mSize = size;
- }
-
- public InputStream getInputStream() {
- return mInputStream;
- }
-
- public long getSize() {
- return mSize;
- }
-
- public long getStreamPosition() {
- return mInputStream.position();
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/IntentIntegratorSupportV4.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/IntentIntegratorSupportV4.java
deleted file mode 100644
index ae87deb31..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/IntentIntegratorSupportV4.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2012 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.util;
-
-import com.google.zxing.integration.android.IntentIntegrator;
-
-import android.content.Intent;
-import android.support.v4.app.Fragment;
-
-/**
- * IntentIntegrator for the V4 Android compatibility package.
- *
- * @author Lachezar Dobrev
- */
-public final class IntentIntegratorSupportV4 extends IntentIntegrator {
-
- private final Fragment mFragment;
-
- /**
- * @param fragment Fragment to handle activity response.
- */
- public IntentIntegratorSupportV4(Fragment fragment) {
- super(fragment.getActivity());
- this.mFragment = fragment;
- }
-
- @Override
- protected void startActivityForResult(Intent intent, int code) {
- mFragment.startActivityForResult(intent, code);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/IterableIterator.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/IterableIterator.java
deleted file mode 100644
index 3af674526..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/IterableIterator.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.util;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-public class IterableIterator<T> implements Iterable<T> {
- private Iterator<T> mIter;
-
- public IterableIterator(Iterator<T> iter, boolean failsafe) {
- mIter = iter;
- if (failsafe && mIter == null) {
- // is there a better way?
- mIter = new ArrayList<T>().iterator();
- }
- }
- public IterableIterator(Iterator<T> iter) {
- this(iter, false);
- }
-
- public Iterator<T> iterator() {
- return mIter;
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java
deleted file mode 100644
index 7f70867a5..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeyServer.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2011 Thialfihar <thi@thialfihar.org>
- * Copyright (C) 2011 Senecaso
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.util;
-
-import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
-
-import java.util.List;
-
-public abstract class KeyServer {
- public static class QueryException extends Exception {
- private static final long serialVersionUID = 2703768928624654512L;
-
- public QueryException(String message) {
- super(message);
- }
- }
-
- public static class TooManyResponses extends Exception {
- private static final long serialVersionUID = 2703768928624654513L;
- }
-
- public static class InsufficientQuery extends Exception {
- private static final long serialVersionUID = 2703768928624654514L;
- }
-
- public static class AddKeyException extends Exception {
- private static final long serialVersionUID = -507574859137295530L;
- }
-
- abstract List<ImportKeysListEntry> search(String query) throws QueryException, TooManyResponses,
- InsufficientQuery;
-
- abstract String get(String keyIdHex) throws QueryException;
-
- abstract void add(String armoredKey) throws AddKeyException;
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeychainServiceListener.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeychainServiceListener.java
deleted file mode 100644
index b205bd556..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/KeychainServiceListener.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.util;
-
-public interface KeychainServiceListener {
- boolean hasServiceStopped();
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/Log.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/Log.java
deleted file mode 100644
index f58f1757a..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/Log.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.util;
-
-import org.sufficientlysecure.keychain.Constants;
-
-/**
- * Wraps Android Logging to enable or disable debug output using Constants
- */
-public final class Log {
-
- public static void v(String tag, String msg) {
- if (Constants.DEBUG) {
- android.util.Log.v(tag, msg);
- }
- }
-
- public static void v(String tag, String msg, Throwable tr) {
- if (Constants.DEBUG) {
- android.util.Log.v(tag, msg, tr);
- }
- }
-
- public static void d(String tag, String msg) {
- if (Constants.DEBUG) {
- android.util.Log.d(tag, msg);
- }
- }
-
- public static void d(String tag, String msg, Throwable tr) {
- if (Constants.DEBUG) {
- android.util.Log.d(tag, msg, tr);
- }
- }
-
- public static void i(String tag, String msg) {
- if (Constants.DEBUG) {
- android.util.Log.i(tag, msg);
- }
- }
-
- public static void i(String tag, String msg, Throwable tr) {
- if (Constants.DEBUG) {
- android.util.Log.i(tag, msg, tr);
- }
- }
-
- public static void w(String tag, String msg) {
- android.util.Log.w(tag, msg);
- }
-
- public static void w(String tag, String msg, Throwable tr) {
- android.util.Log.w(tag, msg, tr);
- }
-
- public static void w(String tag, Throwable tr) {
- android.util.Log.w(tag, tr);
- }
-
- public static void e(String tag, String msg) {
- android.util.Log.e(tag, msg);
- }
-
- public static void e(String tag, String msg, Throwable tr) {
- android.util.Log.e(tag, msg, tr);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PRNGFixes.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PRNGFixes.java
deleted file mode 100644
index 2d8fbcd81..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PRNGFixes.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will Google be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, as long as the origin is not misrepresented.
- */
-
-package org.sufficientlysecure.keychain.util;
-
-import android.os.Build;
-import android.os.Process;
-import android.util.Log;
-
-import java.io.*;
-import java.security.*;
-
-/**
- * Fixes for the output of the default PRNG having low entropy.
- * <p/>
- * The fixes need to be applied via {@link #apply()} before any use of Java Cryptography
- * Architecture primitives. A good place to invoke them is in the application's {@code onCreate}.
- * <p/>
- * copied from http://android-developers.blogspot.de/2013/08/some-securerandom-thoughts.html
- * <p/>
- * <p/>
- * More information on these Android bugs:
- * http://blog.k3170makan.com/2013/08/more-details-on-android-jca-prng-flaw.html
- * Paper: "Randomly failed! Weaknesses in Java Pseudo Random Number Generators (PRNGs)"
- * <p/>
- * <p/>
- * Sep 15, 2013:
- * On some devices /dev/urandom is non-writable!
- * No need to seed /dev/urandom. urandom should have enough seeds from the OS and kernel.
- * Only OpenSSL seeds are broken. See http://emboss.github.io/blog/2013/08/21/openssl-prng-is-not-really-fork-safe
- * <p/>
- * see also:
- * https://github.com/k9mail/k-9/commit/dda8f64276d4d29c43f86237cd77819c28f22f21
- * In addition to a couple of custom ROMs linking /dev/urandom to a non-writable
- * random version, now Samsung's SELinux policy also prevents apps from opening
- * /dev/urandom for writing. Since we shouldn't need to write to /dev/urandom anyway
- * we now simply don't.
- * <p/>
- * <p/>
- * Sep 17, 2013:
- * Updated from official blogpost:
- * Update: the original code sample below crashed on a small fraction of Android
- * devices due to /dev/urandom not being writable. We have now updated the code sample to handle this case gracefully.
- */
-public final class PRNGFixes {
-
- private static final int VERSION_CODE_JELLY_BEAN = 16;
- private static final int VERSION_CODE_JELLY_BEAN_MR2 = 18;
- private static final byte[] BUILD_FINGERPRINT_AND_DEVICE_SERIAL =
- getBuildFingerprintAndDeviceSerial();
-
- /**
- * Hidden constructor to prevent instantiation.
- */
- private PRNGFixes() {
- }
-
- /**
- * Applies all fixes.
- *
- * @throws SecurityException if a fix is needed but could not be applied.
- */
- public static void apply() {
- applyOpenSSLFix();
- installLinuxPRNGSecureRandom();
- }
-
- /**
- * Applies the fix for OpenSSL PRNG having low entropy. Does nothing if the
- * fix is not needed.
- *
- * @throws SecurityException if the fix is needed but could not be applied.
- */
- private static void applyOpenSSLFix() throws SecurityException {
- if ((Build.VERSION.SDK_INT < VERSION_CODE_JELLY_BEAN)
- || (Build.VERSION.SDK_INT > VERSION_CODE_JELLY_BEAN_MR2)) {
- // No need to apply the fix
- return;
- }
-
- try {
- // Mix in the device- and invocation-specific seed.
- Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto")
- .getMethod("RAND_seed", byte[].class)
- .invoke(null, generateSeed());
-
- // Mix output of Linux PRNG into OpenSSL's PRNG
- int bytesRead = (Integer) Class.forName(
- "org.apache.harmony.xnet.provider.jsse.NativeCrypto")
- .getMethod("RAND_load_file", String.class, long.class)
- .invoke(null, "/dev/urandom", 1024);
- if (bytesRead != 1024) {
- throw new IOException(
- "Unexpected number of bytes read from Linux PRNG: "
- + bytesRead);
- }
- } catch (Exception e) {
- throw new SecurityException("Failed to seed OpenSSL PRNG", e);
- }
- }
-
- /**
- * Installs a Linux PRNG-backed {@code SecureRandom} implementation as the
- * default. Does nothing if the implementation is already the default or if
- * there is not need to install the implementation.
- *
- * @throws SecurityException if the fix is needed but could not be applied.
- */
- private static void installLinuxPRNGSecureRandom()
- throws SecurityException {
- if (Build.VERSION.SDK_INT > VERSION_CODE_JELLY_BEAN_MR2) {
- // No need to apply the fix
- return;
- }
-
- // Install a Linux PRNG-based SecureRandom implementation as the
- // default, if not yet installed.
- Provider[] secureRandomProviders =
- Security.getProviders("SecureRandom.SHA1PRNG");
- if ((secureRandomProviders == null)
- || (secureRandomProviders.length < 1)
- || (!LinuxPRNGSecureRandomProvider.class.equals(
- secureRandomProviders[0].getClass()))) {
- Security.insertProviderAt(new LinuxPRNGSecureRandomProvider(), 1);
- }
-
- // Assert that new SecureRandom() and
- // SecureRandom.getInstance("SHA1PRNG") return a SecureRandom backed
- // by the Linux PRNG-based SecureRandom implementation.
- SecureRandom rng1 = new SecureRandom();
- if (!LinuxPRNGSecureRandomProvider.class.equals(
- rng1.getProvider().getClass())) {
- throw new SecurityException(
- "new SecureRandom() backed by wrong Provider: "
- + rng1.getProvider().getClass());
- }
-
- SecureRandom rng2;
- try {
- rng2 = SecureRandom.getInstance("SHA1PRNG");
- } catch (NoSuchAlgorithmException e) {
- throw new SecurityException("SHA1PRNG not available", e);
- }
- if (!LinuxPRNGSecureRandomProvider.class.equals(
- rng2.getProvider().getClass())) {
- throw new SecurityException(
- "SecureRandom.getInstance(\"SHA1PRNG\") backed by wrong"
- + " Provider: " + rng2.getProvider().getClass());
- }
- }
-
- /**
- * {@code Provider} of {@code SecureRandom} engines which pass through
- * all requests to the Linux PRNG.
- */
- private static class LinuxPRNGSecureRandomProvider extends Provider {
-
- public LinuxPRNGSecureRandomProvider() {
- super("LinuxPRNG",
- 1.0,
- "A Linux-specific random number provider that uses"
- + " /dev/urandom");
- // Although /dev/urandom is not a SHA-1 PRNG, some apps
- // explicitly request a SHA1PRNG SecureRandom and we thus need to
- // prevent them from getting the default implementation whose output
- // may have low entropy.
- put("SecureRandom.SHA1PRNG", LinuxPRNGSecureRandom.class.getName());
- put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
- }
- }
-
- /**
- * {@link SecureRandomSpi} which passes all requests to the Linux PRNG
- * ({@code /dev/urandom}).
- */
- public static class LinuxPRNGSecureRandom extends SecureRandomSpi {
-
- /*
- * IMPLEMENTATION NOTE: Requests to generate bytes and to mix in a seed
- * are passed through to the Linux PRNG (/dev/urandom). Instances of
- * this class seed themselves by mixing in the current time, PID, UID,
- * build fingerprint, and hardware serial number (where available) into
- * Linux PRNG.
- *
- * Concurrency: Read requests to the underlying Linux PRNG are
- * serialized (on sLock) to ensure that multiple threads do not get
- * duplicated PRNG output.
- */
-
- private static final File URANDOM_FILE = new File("/dev/urandom");
-
- private static final Object sLock = new Object();
-
- /**
- * Input stream for reading from Linux PRNG or {@code null} if not yet
- * opened.
- *
- * @GuardedBy("sLock")
- */
- private static DataInputStream sUrandomIn;
-
- /**
- * Output stream for writing to Linux PRNG or {@code null} if not yet
- * opened.
- *
- * @GuardedBy("sLock")
- */
- private static OutputStream sUrandomOut;
-
- /**
- * Whether this engine instance has been seeded. This is needed because
- * each instance needs to seed itself if the client does not explicitly
- * seed it.
- */
- private boolean mSeeded;
-
- @Override
- protected void engineSetSeed(byte[] bytes) {
- try {
- OutputStream out;
- synchronized (sLock) {
- out = getUrandomOutputStream();
- }
- out.write(bytes);
- out.flush();
- } catch (IOException e) {
- // On a small fraction of devices /dev/urandom is not writable.
- // Log and ignore.
- Log.w(PRNGFixes.class.getSimpleName(),
- "Failed to mix seed into " + URANDOM_FILE);
- } finally {
- mSeeded = true;
- }
- }
-
- @Override
- protected void engineNextBytes(byte[] bytes) {
- if (!mSeeded) {
- // Mix in the device- and invocation-specific seed.
- engineSetSeed(generateSeed());
- }
-
- try {
- DataInputStream in;
- synchronized (sLock) {
- in = getUrandomInputStream();
- }
- synchronized (in) {
- in.readFully(bytes);
- }
- } catch (IOException e) {
- throw new SecurityException(
- "Failed to read from " + URANDOM_FILE, e);
- }
- }
-
- @Override
- protected byte[] engineGenerateSeed(int size) {
- byte[] seed = new byte[size];
- engineNextBytes(seed);
- return seed;
- }
-
- private DataInputStream getUrandomInputStream() {
- synchronized (sLock) {
- if (sUrandomIn == null) {
- // NOTE: Consider inserting a BufferedInputStream between
- // DataInputStream and FileInputStream if you need higher
- // PRNG output performance and can live with future PRNG
- // output being pulled into this process prematurely.
- try {
- sUrandomIn = new DataInputStream(
- new FileInputStream(URANDOM_FILE));
- } catch (IOException e) {
- throw new SecurityException("Failed to open "
- + URANDOM_FILE + " for reading", e);
- }
- }
- return sUrandomIn;
- }
- }
-
- private OutputStream getUrandomOutputStream() throws IOException {
- synchronized (sLock) {
- if (sUrandomOut == null) {
- sUrandomOut = new FileOutputStream(URANDOM_FILE);
- }
- return sUrandomOut;
- }
- }
- }
-
- /**
- * Generates a device- and invocation-specific seed to be mixed into the
- * Linux PRNG.
- */
- private static byte[] generateSeed() {
- try {
- ByteArrayOutputStream seedBuffer = new ByteArrayOutputStream();
- DataOutputStream seedBufferOut =
- new DataOutputStream(seedBuffer);
- seedBufferOut.writeLong(System.currentTimeMillis());
- seedBufferOut.writeLong(System.nanoTime());
- seedBufferOut.writeInt(Process.myPid());
- seedBufferOut.writeInt(Process.myUid());
- seedBufferOut.write(BUILD_FINGERPRINT_AND_DEVICE_SERIAL);
- seedBufferOut.close();
- return seedBuffer.toByteArray();
- } catch (IOException e) {
- throw new SecurityException("Failed to generate seed", e);
- }
- }
-
- /**
- * Gets the hardware serial number of this device.
- *
- * @return serial number or {@code null} if not available.
- */
- private static String getDeviceSerialNumber() {
- // We're using the Reflection API because Build.SERIAL is only available
- // since API Level 9 (Gingerbread, Android 2.3).
- try {
- return (String) Build.class.getField("SERIAL").get(null);
- } catch (Exception ignored) {
- return null;
- }
- }
-
- private static byte[] getBuildFingerprintAndDeviceSerial() {
- StringBuilder result = new StringBuilder();
- String fingerprint = Build.FINGERPRINT;
- if (fingerprint != null) {
- result.append(fingerprint);
- }
- String serial = getDeviceSerialNumber();
- if (serial != null) {
- result.append(serial);
- }
- try {
- return result.toString().getBytes("UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException("UTF-8 encoding not supported");
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PausableThreadPoolExecutor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PausableThreadPoolExecutor.java
deleted file mode 100644
index 5ec915810..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PausableThreadPoolExecutor.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.util;
-
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.RejectedExecutionHandler;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.locks.ReentrantLock;
-
-/**
- * Example from
- * http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html
- */
-public class PausableThreadPoolExecutor extends ThreadPoolExecutor {
-
- public PausableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
- TimeUnit unit, BlockingQueue<Runnable> workQueue,
- RejectedExecutionHandler handler) {
- super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
- }
-
- public PausableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
- TimeUnit unit, BlockingQueue<Runnable> workQueue,
- ThreadFactory threadFactory,
- RejectedExecutionHandler handler) {
- super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
- }
-
- public PausableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
- TimeUnit unit, BlockingQueue<Runnable> workQueue,
- ThreadFactory threadFactory) {
- super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
- }
-
- public PausableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
- TimeUnit unit, BlockingQueue<Runnable> workQueue) {
- super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
- }
-
- private boolean mIsPaused;
- private ReentrantLock mPauseLock = new ReentrantLock();
- private Condition mUnPaused = mPauseLock.newCondition();
-
- protected void beforeExecute(Thread t, Runnable r) {
- super.beforeExecute(t, r);
- mPauseLock.lock();
- try {
- while (mIsPaused) {
- mUnPaused.await();
- }
- } catch (InterruptedException ie) {
- t.interrupt();
- } finally {
- mPauseLock.unlock();
- }
- }
-
- public void pause() {
- mPauseLock.lock();
- try {
- mIsPaused = true;
- } finally {
- mPauseLock.unlock();
- }
- }
-
- public void resume() {
- mPauseLock.lock();
- try {
- mIsPaused = false;
- mUnPaused.signalAll();
- } finally {
- mPauseLock.unlock();
- }
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PositionAwareInputStream.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PositionAwareInputStream.java
deleted file mode 100644
index 4fcd3047f..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/PositionAwareInputStream.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-public class PositionAwareInputStream extends InputStream {
- private InputStream mStream;
- private long mPosition;
-
- public PositionAwareInputStream(InputStream in) {
- mStream = in;
- mPosition = 0;
- }
-
- @Override
- public int read() throws IOException {
- int ch = mStream.read();
- ++mPosition;
- return ch;
- }
-
- @Override
- public int available() throws IOException {
- return mStream.available();
- }
-
- @Override
- public void close() throws IOException {
- mStream.close();
- }
-
- @Override
- public boolean markSupported() {
- return false;
- }
-
- @Override
- public int read(byte[] b) throws IOException {
- int result = mStream.read(b);
- mPosition += result;
- return result;
- }
-
- @Override
- public int read(byte[] b, int offset, int length) throws IOException {
- int result = mStream.read(b, offset, length);
- mPosition += result;
- return result;
- }
-
- @Override
- public synchronized void reset() throws IOException {
- mStream.reset();
- mPosition = 0;
- }
-
- @Override
- public long skip(long n) throws IOException {
- long result = mStream.skip(n);
- mPosition += result;
- return result;
- }
-
- public long position() {
- return mPosition;
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/Primes.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/Primes.java
deleted file mode 100644
index 28a12bf37..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/Primes.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.util;
-
-import java.math.BigInteger;
-
-/**
- * Primes for ElGamal
- */
-public final class Primes {
- // taken from http://www.ietf.org/rfc/rfc3526.txt
- public static final String P1536 =
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" +
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" +
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" +
- "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" +
- "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" +
- "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" +
- "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" +
- "670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF";
-
- public static final String P2048 =
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" +
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" +
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" +
- "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" +
- "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" +
- "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" +
- "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" +
- "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" +
- "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" +
- "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" +
- "15728E5A 8AACAA68 FFFFFFFF FFFFFFFF";
-
- public static final String P3072 =
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" +
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" +
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" +
- "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" +
- "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" +
- "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" +
- "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" +
- "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" +
- "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" +
- "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" +
- "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" +
- "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" +
- "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" +
- "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" +
- "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" +
- "43DB5BFC E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF";
-
- public static final String P4096 =
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" +
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" +
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" +
- "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" +
- "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" +
- "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" +
- "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" +
- "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" +
- "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" +
- "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" +
- "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" +
- "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" +
- "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" +
- "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" +
- "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" +
- "43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" +
- "88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" +
- "2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" +
- "287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" +
- "1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" +
- "93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199" +
- "FFFFFFFF FFFFFFFF";
-
- public static final String P6144 =
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" +
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" +
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" +
- "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" +
- "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" +
- "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" +
- "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" +
- "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" +
- "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" +
- "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" +
- "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" +
- "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" +
- "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" +
- "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" +
- "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" +
- "43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" +
- "88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" +
- "2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" +
- "287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" +
- "1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" +
- "93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492" +
- "36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD" +
- "F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831" +
- "179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B" +
- "DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF" +
- "5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6" +
- "D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3" +
- "23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA" +
- "CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328" +
- "06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C" +
- "DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE" +
- "12BF2D5B 0B7474D6 E694F91E 6DCC4024 FFFFFFFF FFFFFFFF";
-
- public static final String P8192 =
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" +
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" +
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" +
- "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" +
- "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" +
- "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" +
- "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" +
- "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" +
- "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" +
- "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" +
- "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" +
- "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" +
- "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" +
- "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" +
- "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" +
- "43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" +
- "88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" +
- "2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" +
- "287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" +
- "1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" +
- "93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492" +
- "36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD" +
- "F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831" +
- "179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B" +
- "DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF" +
- "5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6" +
- "D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3" +
- "23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA" +
- "CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328" +
- "06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C" +
- "DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE" +
- "12BF2D5B 0B7474D6 E694F91E 6DBE1159 74A3926F 12FEE5E4" +
- "38777CB6 A932DF8C D8BEC4D0 73B931BA 3BC832B6 8D9DD300" +
- "741FA7BF 8AFC47ED 2576F693 6BA42466 3AAB639C 5AE4F568" +
- "3423B474 2BF1C978 238F16CB E39D652D E3FDB8BE FC848AD9" +
- "22222E04 A4037C07 13EB57A8 1A23F0C7 3473FC64 6CEA306B" +
- "4BCBC886 2F8385DD FA9D4B7F A2C087E8 79683303 ED5BDD3A" +
- "062B3CF5 B3A278A6 6D2A13F8 3F44F82D DF310EE0 74AB6A36" +
- "4597E899 A0255DC1 64F31CC5 0846851D F9AB4819 5DED7EA1" +
- "B1D510BD 7EE74D73 FAF36BC3 1ECFA268 359046F4 EB879F92" +
- "4009438B 481C6CD7 889A002E D5EE382B C9190DA6 FC026E47" +
- "9558E447 5677E9AA 9E3050E2 765694DF C81F56E8 80B96E71" +
- "60C980DD 98EDD3DF FFFFFFFF FFFFFFFF";
-
- public static BigInteger getBestPrime(int keySize) {
- String primeString;
- if (keySize >= (8192 + 6144) / 2) {
- primeString = P8192;
- } else if (keySize >= (6144 + 4096) / 2) {
- primeString = P6144;
- } else if (keySize >= (4096 + 3072) / 2) {
- primeString = P4096;
- } else if (keySize >= (3072 + 2048) / 2) {
- primeString = P3072;
- } else if (keySize >= (2048 + 1536) / 2) {
- primeString = P2048;
- } else {
- primeString = P1536;
- }
-
- return new BigInteger(primeString.replaceAll(" ", ""), 16);
- }
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressDialogUpdater.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressDialogUpdater.java
deleted file mode 100644
index 26c05ad0a..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressDialogUpdater.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.util;
-
-public interface ProgressDialogUpdater {
- void setProgress(String message, int current, int total);
-
- void setProgress(int resourceId, int current, int total);
-
- void setProgress(int current, int total);
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressScaler.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressScaler.java
deleted file mode 100644
index 23961c05f..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/ProgressScaler.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.util;
-
-/** This is a simple class that wraps a ProgressDialogUpdater, scaling the progress
- * values into a specified range.
- */
-public class ProgressScaler implements ProgressDialogUpdater {
-
- final ProgressDialogUpdater mWrapped;
- final int mFrom, mTo, mMax;
-
- public ProgressScaler(ProgressDialogUpdater wrapped, int from, int to, int max) {
- this.mWrapped = wrapped;
- this.mFrom = from;
- this.mTo = to;
- this.mMax = max;
- }
-
- /**
- * Set progressDialogUpdater of ProgressDialog by sending message to handler on UI thread
- */
- public void setProgress(String message, int progress, int max) {
- mWrapped.setProgress(message, mFrom + progress * (mTo - mFrom) / max, mMax);
- }
-
- public void setProgress(int resourceId, int progress, int max) {
- mWrapped.setProgress(resourceId, progress, mMax);
- }
-
- public void setProgress(int progress, int max) {
- mWrapped.setProgress(progress, max);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/QrCodeUtils.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/QrCodeUtils.java
deleted file mode 100644
index af9034aa7..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/QrCodeUtils.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2011 Andreas Schildbach
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.util;
-
-import com.google.zxing.BarcodeFormat;
-import com.google.zxing.EncodeHintType;
-import com.google.zxing.WriterException;
-import com.google.zxing.common.BitMatrix;
-import com.google.zxing.qrcode.QRCodeWriter;
-import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
-
-import android.graphics.Bitmap;
-import android.graphics.Color;
-
-import org.sufficientlysecure.keychain.Constants;
-
-import java.util.Hashtable;
-
-public class QrCodeUtils {
- public static final QRCodeWriter QR_CODE_WRITER = new QRCodeWriter();
-
- /**
- * Generate Bitmap with QR Code based on input.
- *
- * @param input
- * @param size
- * @return QR Code as Bitmap
- */
- public static Bitmap getQRCodeBitmap(final String input, final int size) {
- try {
- final Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
- hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
- final BitMatrix result = QR_CODE_WRITER.encode(input, BarcodeFormat.QR_CODE, size,
- size, hints);
-
- final int width = result.getWidth();
- final int height = result.getHeight();
- final int[] pixels = new int[width * height];
-
- for (int y = 0; y < height; y++) {
- final int offset = y * width;
- for (int x = 0; x < width; x++) {
- pixels[offset + x] = result.get(x, y) ? Color.BLACK : Color.TRANSPARENT;
- }
- }
-
- final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
- return bitmap;
- } catch (final WriterException e) {
- Log.e(Constants.TAG, "QrCodeUtils", e);
- return null;
- }
- }
-
-}