diff --git a/AndroidManifest.xml b/AndroidManifest.xml index fc7625216..b3f818239 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -3,7 +3,7 @@ @@ -33,7 +33,7 @@ android:icon="@drawable/icon" android:label="@string/app_name" > @@ -43,7 +43,7 @@ @@ -56,7 +56,7 @@ android:resource="@xml/searchable_public_keys" /> @@ -69,11 +69,11 @@ android:resource="@xml/searchable_secret_keys" /> @@ -91,7 +91,7 @@ android:resource="@xml/searchable_public_keys" /> @@ -109,7 +109,7 @@ android:resource="@xml/searchable_secret_keys" /> @@ -124,7 +124,7 @@ @@ -138,7 +138,7 @@ @@ -170,31 +170,31 @@ @@ -215,11 +215,11 @@ diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/COPYING @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/res/layout/edit_key_section.xml b/res/layout/edit_key_section.xml index e57b3b8df..d14748d4b 100644 --- a/res/layout/edit_key_section.xml +++ b/res/layout/edit_key_section.xml @@ -14,7 +14,7 @@ limitations under the License. --> - - + diff --git a/res/layout/edit_key_user_id_item.xml b/res/layout/edit_key_user_id_item.xml index d5c7c0fa5..6e7b552dd 100644 --- a/res/layout/edit_key_user_id_item.xml +++ b/res/layout/edit_key_user_id_item.xml @@ -14,7 +14,7 @@ limitations under the License. --> - - + diff --git a/res/layout/key_server_editor.xml b/res/layout/key_server_editor.xml index e4c25b316..a02540c2c 100644 --- a/res/layout/key_server_editor.xml +++ b/res/layout/key_server_editor.xml @@ -14,7 +14,7 @@ limitations under the License. --> - - + diff --git a/res/values/styles.xml b/res/values/styles.xml index 720f7aedb..2a2a69341 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -1,5 +1,6 @@ - + - + + \ No newline at end of file diff --git a/res/xml/apg_preferences.xml b/res/xml/apg_preferences.xml index 5527cda1a..7c0dd2206 100644 --- a/res/xml/apg_preferences.xml +++ b/res/xml/apg_preferences.xml @@ -1,5 +1,6 @@ - - - - + + + android:key="language" + android:title="@string/label_language" /> - - - - - - + - - - - - - + - - - - - - + + + - - + \ No newline at end of file diff --git a/res/xml/searchable_public_keys.xml b/res/xml/searchable_public_keys.xml index 6bb934fec..e9602b121 100644 --- a/res/xml/searchable_public_keys.xml +++ b/res/xml/searchable_public_keys.xml @@ -1,5 +1,6 @@ - - - + + + \ No newline at end of file diff --git a/res/xml/searchable_secret_keys.xml b/res/xml/searchable_secret_keys.xml index e196b4664..a7e8873d6 100644 --- a/res/xml/searchable_secret_keys.xml +++ b/res/xml/searchable_secret_keys.xml @@ -1,5 +1,6 @@ - - - + + + \ No newline at end of file diff --git a/src/org/thialfihar/android/apg/Apg.java b/src/org/apg/Apg.java similarity index 77% rename from src/org/thialfihar/android/apg/Apg.java rename to src/org/apg/Apg.java index 5b9ba6241..d0e54f4d8 100644 --- a/src/org/thialfihar/android/apg/Apg.java +++ b/src/org/apg/Apg.java @@ -14,8 +14,19 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg; +import org.apg.KeyServer.AddKeyException; +import org.apg.provider.DataProvider; +import org.apg.provider.Database; +import org.apg.provider.KeyRings; +import org.apg.provider.Keys; +import org.apg.provider.UserIds; +import org.apg.ui.BaseActivity; +import org.apg.ui.widget.KeyEditor; +import org.apg.ui.widget.SectionView; +import org.apg.ui.widget.UserIdEditor; +import org.apg.util.IterableIterator; import org.spongycastle.bcpg.ArmoredInputStream; import org.spongycastle.bcpg.ArmoredOutputStream; import org.spongycastle.bcpg.BCPGOutputStream; @@ -53,16 +64,7 @@ import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator; import org.spongycastle.openpgp.PGPSignatureSubpacketVector; import org.spongycastle.openpgp.PGPUtil; import org.spongycastle.openpgp.PGPV3SignatureGenerator; -import org.thialfihar.android.apg.KeyServer.AddKeyException; -import org.thialfihar.android.apg.provider.DataProvider; -import org.thialfihar.android.apg.provider.Database; -import org.thialfihar.android.apg.provider.KeyRings; -import org.thialfihar.android.apg.provider.Keys; -import org.thialfihar.android.apg.provider.UserIds; -import org.thialfihar.android.apg.ui.widget.KeyEditor; -import org.thialfihar.android.apg.ui.widget.SectionView; -import org.thialfihar.android.apg.ui.widget.UserIdEditor; -import org.thialfihar.android.apg.utils.IterableIterator; +import org.apg.R; import android.app.Activity; import android.content.Context; @@ -155,54 +157,45 @@ public class Apg { public static final String AUTHORITY = DataProvider.AUTHORITY; - public static final Uri CONTENT_URI_SECRET_KEY_RINGS = - Uri.parse("content://" + AUTHORITY + "/key_rings/secret/"); - public static final Uri CONTENT_URI_SECRET_KEY_RING_BY_KEY_ID = - Uri.parse("content://" + AUTHORITY + "/key_rings/secret/key_id/"); - public static final Uri CONTENT_URI_SECRET_KEY_RING_BY_EMAILS = - Uri.parse("content://" + AUTHORITY + "/key_rings/secret/emails/"); + public static final Uri CONTENT_URI_SECRET_KEY_RINGS = Uri.parse("content://" + AUTHORITY + + "/key_rings/secret/"); + public static final Uri CONTENT_URI_SECRET_KEY_RING_BY_KEY_ID = Uri.parse("content://" + + AUTHORITY + "/key_rings/secret/key_id/"); + public static final Uri CONTENT_URI_SECRET_KEY_RING_BY_EMAILS = Uri.parse("content://" + + AUTHORITY + "/key_rings/secret/emails/"); - public static final Uri CONTENT_URI_PUBLIC_KEY_RINGS = - Uri.parse("content://" + AUTHORITY + "/key_rings/public/"); - public static final Uri CONTENT_URI_PUBLIC_KEY_RING_BY_KEY_ID = - Uri.parse("content://" + AUTHORITY + "/key_rings/public/key_id/"); - public static final Uri CONTENT_URI_PUBLIC_KEY_RING_BY_EMAILS = - Uri.parse("content://" + AUTHORITY + "/key_rings/public/emails/"); + public static final Uri CONTENT_URI_PUBLIC_KEY_RINGS = Uri.parse("content://" + AUTHORITY + + "/key_rings/public/"); + public static final Uri CONTENT_URI_PUBLIC_KEY_RING_BY_KEY_ID = Uri.parse("content://" + + AUTHORITY + "/key_rings/public/key_id/"); + public static final Uri CONTENT_URI_PUBLIC_KEY_RING_BY_EMAILS = Uri.parse("content://" + + AUTHORITY + "/key_rings/public/emails/"); private static String VERSION = null; - 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 }; + 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 static Pattern PGP_MESSAGE = - Pattern.compile(".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", - Pattern.DOTALL); + public static Pattern PGP_MESSAGE = Pattern.compile( + ".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", Pattern.DOTALL); - public static Pattern PGP_SIGNED_MESSAGE = - Pattern.compile(".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*", - Pattern.DOTALL); + public static Pattern PGP_SIGNED_MESSAGE = Pattern + .compile( + ".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*", + Pattern.DOTALL); - public static Pattern PGP_PUBLIC_KEY = - Pattern.compile(".*?(-----BEGIN PGP PUBLIC KEY BLOCK-----.*?-----END PGP PUBLIC KEY BLOCK-----).*", - Pattern.DOTALL); + public static Pattern PGP_PUBLIC_KEY = Pattern.compile( + ".*?(-----BEGIN PGP PUBLIC KEY BLOCK-----.*?-----END PGP PUBLIC KEY BLOCK-----).*", + Pattern.DOTALL); - private static HashMap mPassPhraseCache = - new HashMap(); + private static HashMap mPassPhraseCache = new HashMap(); private static String mEditPassPhrase = null; private static Database mDatabase = null; @@ -281,7 +274,7 @@ public class Apg { // check delay long nextCheck = realTtl - lived + 1000; if (nextCheck < delay) { - delay = (int)nextCheck; + delay = (int) nextCheck; } } } @@ -293,11 +286,10 @@ public class Apg { return delay; } - public static PGPSecretKey createKey(Context context, - int algorithmChoice, int keySize, String passPhrase, - PGPSecretKey masterKey) - throws NoSuchAlgorithmException, PGPException, NoSuchProviderException, - GeneralException, InvalidAlgorithmParameterException { + public static PGPSecretKey createKey(Context context, int algorithmChoice, int keySize, + String passPhrase, PGPSecretKey masterKey) throws NoSuchAlgorithmException, + PGPException, NoSuchProviderException, GeneralException, + InvalidAlgorithmParameterException { if (keySize < 512) { throw new GeneralException(context.getString(R.string.error_keySizeMinimum512bit)); @@ -313,39 +305,40 @@ public class Apg { KeyPairGenerator keyGen = null; switch (algorithmChoice) { - case Id.choice.algorithm.dsa: { - keyGen = KeyPairGenerator.getInstance("DSA", new BouncyCastleProvider()); - keyGen.initialize(keySize, new SecureRandom()); - algorithm = PGPPublicKey.DSA; - break; + case Id.choice.algorithm.dsa: { + keyGen = KeyPairGenerator.getInstance("DSA", new BouncyCastleProvider()); + keyGen.initialize(keySize, new SecureRandom()); + algorithm = PGPPublicKey.DSA; + break; + } + + case Id.choice.algorithm.elgamal: { + if (masterKey == null) { + throw new GeneralException( + context.getString(R.string.error_masterKeyMustNotBeElGamal)); } + keyGen = KeyPairGenerator.getInstance("ELGAMAL", new BouncyCastleProvider()); + BigInteger p = Primes.getBestPrime(keySize); + BigInteger g = new BigInteger("2"); - case Id.choice.algorithm.elgamal: { - if (masterKey == null) { - throw new GeneralException(context.getString(R.string.error_masterKeyMustNotBeElGamal)); - } - keyGen = KeyPairGenerator.getInstance("ELGAMAL", new BouncyCastleProvider()); - BigInteger p = Primes.getBestPrime(keySize); - BigInteger g = new BigInteger("2"); + ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); - ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); + keyGen.initialize(elParams); + algorithm = PGPPublicKey.ELGAMAL_ENCRYPT; + break; + } - keyGen.initialize(elParams); - algorithm = PGPPublicKey.ELGAMAL_ENCRYPT; - break; - } + case Id.choice.algorithm.rsa: { + keyGen = KeyPairGenerator.getInstance("RSA", new BouncyCastleProvider()); + keyGen.initialize(keySize, new SecureRandom()); - case Id.choice.algorithm.rsa: { - keyGen = KeyPairGenerator.getInstance("RSA", new BouncyCastleProvider()); - keyGen.initialize(keySize, new SecureRandom()); + algorithm = PGPPublicKey.RSA_GENERAL; + break; + } - algorithm = PGPPublicKey.RSA_GENERAL; - break; - } - - default: { - throw new GeneralException(context.getString(R.string.error_unknownAlgorithmChoice)); - } + default: { + throw new GeneralException(context.getString(R.string.error_unknownAlgorithmChoice)); + } } PGPKeyPair keyPair = new PGPKeyPair(algorithm, keyGen.generateKeyPair(), new Date()); @@ -354,27 +347,21 @@ public class Apg { if (masterKey == null) { // enough for now, as we assemble the key again later anyway secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, keyPair, "", - PGPEncryptedData.CAST5, passPhrase.toCharArray(), - null, null, - new SecureRandom(), new BouncyCastleProvider().getName()); + PGPEncryptedData.CAST5, passPhrase.toCharArray(), null, null, + new SecureRandom(), new BouncyCastleProvider().getName()); } else { PGPPublicKey tmpKey = masterKey.getPublicKey(); - PGPPublicKey masterPublicKey = - new PGPPublicKey(tmpKey.getAlgorithm(), - tmpKey.getKey(new BouncyCastleProvider()), - tmpKey.getCreationTime()); - PGPPrivateKey masterPrivateKey = - masterKey.extractPrivateKey(passPhrase.toCharArray(), - new BouncyCastleProvider()); + PGPPublicKey masterPublicKey = new PGPPublicKey(tmpKey.getAlgorithm(), + tmpKey.getKey(new BouncyCastleProvider()), tmpKey.getCreationTime()); + PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(passPhrase.toCharArray(), + new BouncyCastleProvider()); PGPKeyPair masterKeyPair = new PGPKeyPair(masterPublicKey, masterPrivateKey); - PGPKeyRingGenerator ringGen = - new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, - masterKeyPair, "", - PGPEncryptedData.CAST5, passPhrase.toCharArray(), - null, null, - new SecureRandom(), new BouncyCastleProvider().getName()); + PGPKeyRingGenerator ringGen = new PGPKeyRingGenerator( + PGPSignature.POSITIVE_CERTIFICATION, masterKeyPair, "", PGPEncryptedData.CAST5, + passPhrase.toCharArray(), null, null, new SecureRandom(), + new BouncyCastleProvider().getName()); ringGen.addSubKey(keyPair); PGPSecretKeyRing secKeyRing = ringGen.generateSecretKeyRing(); Iterator it = secKeyRing.getSecretKeys(); @@ -390,7 +377,7 @@ public class Apg { GregorianCalendar tmp = new GregorianCalendar(); tmp.setTime(first.getTime()); long numDays = (second.getTimeInMillis() - first.getTimeInMillis()) / 1000 / 86400; - tmp.add(Calendar.DAY_OF_MONTH, (int)numDays); + tmp.add(Calendar.DAY_OF_MONTH, (int) numDays); while (tmp.before(second)) { tmp.add(Calendar.DAY_OF_MONTH, 1); ++numDays; @@ -398,14 +385,13 @@ public class Apg { return numDays; } - public static void buildSecretKey(Activity context, - SectionView userIdsView, SectionView keysView, - String oldPassPhrase, String newPassPhrase, - ProgressDialogUpdater progress) - throws Apg.GeneralException, NoSuchProviderException, PGPException, - NoSuchAlgorithmException, SignatureException, IOException, Database.GeneralException { + public static void buildSecretKey(Activity context, SectionView userIdsView, + SectionView keysView, String oldPassPhrase, String newPassPhrase, + ProgressDialogUpdater progress) throws Apg.GeneralException, NoSuchProviderException, + PGPException, NoSuchAlgorithmException, SignatureException, IOException, + Database.GeneralException { - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_buildingKey, 0, 100); Security.addProvider(new BouncyCastleProvider()); @@ -426,14 +412,15 @@ public class Apg { boolean gotMainUserId = false; for (int i = 0; i < userIdEditors.getChildCount(); ++i) { - UserIdEditor editor = (UserIdEditor)userIdEditors.getChildAt(i); + UserIdEditor editor = (UserIdEditor) userIdEditors.getChildAt(i); String userId = null; try { userId = editor.getValue(); } catch (UserIdEditor.NoNameException e) { throw new Apg.GeneralException(context.getString(R.string.error_userIdNeedsAName)); } catch (UserIdEditor.NoEmailException e) { - throw new Apg.GeneralException(context.getString(R.string.error_userIdNeedsAnEmailAddress)); + throw new Apg.GeneralException( + context.getString(R.string.error_userIdNeedsAnEmailAddress)); } catch (UserIdEditor.InvalidEmailException e) { throw new Apg.GeneralException("" + e); } @@ -455,7 +442,8 @@ public class Apg { } if (!gotMainUserId) { - throw new Apg.GeneralException(context.getString(R.string.error_mainUserIdMustNotBeEmpty)); + throw new Apg.GeneralException( + context.getString(R.string.error_mainUserIdMustNotBeEmpty)); } if (keyEditors.getChildCount() == 0) { @@ -463,39 +451,33 @@ public class Apg { } for (int i = 0; i < keyEditors.getChildCount(); ++i) { - KeyEditor editor = (KeyEditor)keyEditors.getChildAt(i); + KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i); keys.add(editor.getValue()); } - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_preparingMasterKey, 10, 100); KeyEditor keyEditor = (KeyEditor) keyEditors.getChildAt(0); int usageId = keyEditor.getUsage(); - boolean canSign = (usageId == Id.choice.usage.sign_only || - usageId == Id.choice.usage.sign_and_encrypt); - boolean canEncrypt = (usageId == Id.choice.usage.encrypt_only || - usageId == Id.choice.usage.sign_and_encrypt); + boolean canSign = (usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt); + boolean canEncrypt = (usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt); String mainUserId = userIds.get(0); PGPSecretKey masterKey = keys.get(0); PGPPublicKey tmpKey = masterKey.getPublicKey(); - PGPPublicKey masterPublicKey = - new PGPPublicKey(tmpKey.getAlgorithm(), - tmpKey.getKey(new BouncyCastleProvider()), - tmpKey.getCreationTime()); - PGPPrivateKey masterPrivateKey = - masterKey.extractPrivateKey(oldPassPhrase.toCharArray(), - new BouncyCastleProvider()); + PGPPublicKey masterPublicKey = new PGPPublicKey(tmpKey.getAlgorithm(), + tmpKey.getKey(new BouncyCastleProvider()), tmpKey.getCreationTime()); + PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(oldPassPhrase.toCharArray(), + new BouncyCastleProvider()); - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_certifyingMasterKey, 20, 100); for (int i = 0; i < userIds.size(); ++i) { String userId = userIds.get(i); - PGPSignatureGenerator sGen = - new PGPSignatureGenerator(masterPublicKey.getAlgorithm(), - HashAlgorithmTags.SHA1, new BouncyCastleProvider()); + PGPSignatureGenerator sGen = new PGPSignatureGenerator(masterPublicKey.getAlgorithm(), + HashAlgorithmTags.SHA1, new BouncyCastleProvider()); sGen.initSign(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey); @@ -528,46 +510,40 @@ public class Apg { GregorianCalendar expiryDate = keyEditor.getExpiryDate(); long numDays = getNumDaysBetween(creationDate, expiryDate); if (numDays <= 0) { - throw new GeneralException(context.getString(R.string.error_expiryMustComeAfterCreation)); + throw new GeneralException( + context.getString(R.string.error_expiryMustComeAfterCreation)); } hashedPacketsGen.setKeyExpirationTime(true, numDays * 86400); } - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_buildingMasterKeyRing, 30, 100); - PGPKeyRingGenerator keyGen = - new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, - masterKeyPair, mainUserId, - PGPEncryptedData.CAST5, newPassPhrase.toCharArray(), - hashedPacketsGen.generate(), unhashedPacketsGen.generate(), - new SecureRandom(), new BouncyCastleProvider().getName()); + PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, + masterKeyPair, mainUserId, PGPEncryptedData.CAST5, newPassPhrase.toCharArray(), + hashedPacketsGen.generate(), unhashedPacketsGen.generate(), new SecureRandom(), + new BouncyCastleProvider().getName()); - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_addingSubKeys, 40, 100); for (int i = 1; i < keys.size(); ++i) { - if( progress != null ) - progress.setProgress(40 + 50 * (i - 1)/ (keys.size() - 1), 100); + if (progress != null) + progress.setProgress(40 + 50 * (i - 1) / (keys.size() - 1), 100); PGPSecretKey subKey = keys.get(i); keyEditor = (KeyEditor) keyEditors.getChildAt(i); PGPPublicKey subPublicKey = subKey.getPublicKey(); - PGPPrivateKey subPrivateKey = - subKey.extractPrivateKey(oldPassPhrase.toCharArray(), - new BouncyCastleProvider()); - PGPKeyPair subKeyPair = - new PGPKeyPair(subPublicKey.getAlgorithm(), - subPublicKey.getKey(new BouncyCastleProvider()), - subPrivateKey.getKey(), - subPublicKey.getCreationTime()); + PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(oldPassPhrase.toCharArray(), + new BouncyCastleProvider()); + PGPKeyPair subKeyPair = new PGPKeyPair(subPublicKey.getAlgorithm(), + subPublicKey.getKey(new BouncyCastleProvider()), subPrivateKey.getKey(), + subPublicKey.getCreationTime()); hashedPacketsGen = new PGPSignatureSubpacketGenerator(); unhashedPacketsGen = new PGPSignatureSubpacketGenerator(); keyFlags = 0; usageId = keyEditor.getUsage(); - canSign = (usageId == Id.choice.usage.sign_only || - usageId == Id.choice.usage.sign_and_encrypt); - canEncrypt = (usageId == Id.choice.usage.encrypt_only || - usageId == Id.choice.usage.sign_and_encrypt); + canSign = (usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt); + canEncrypt = (usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt); if (canSign) { keyFlags |= KeyFlags.SIGN_DATA; } @@ -583,39 +559,39 @@ public class Apg { GregorianCalendar expiryDate = keyEditor.getExpiryDate(); long numDays = getNumDaysBetween(creationDate, expiryDate); if (numDays <= 0) { - throw new GeneralException(context.getString(R.string.error_expiryMustComeAfterCreation)); + throw new GeneralException( + context.getString(R.string.error_expiryMustComeAfterCreation)); } hashedPacketsGen.setKeyExpirationTime(true, numDays * 86400); } - keyGen.addSubKey(subKeyPair, - hashedPacketsGen.generate(), unhashedPacketsGen.generate()); + keyGen.addSubKey(subKeyPair, hashedPacketsGen.generate(), unhashedPacketsGen.generate()); } PGPSecretKeyRing secretKeyRing = keyGen.generateSecretKeyRing(); PGPPublicKeyRing publicKeyRing = keyGen.generatePublicKeyRing(); - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_savingKeyRing, 90, 100); mDatabase.saveKeyRing(secretKeyRing); mDatabase.saveKeyRing(publicKeyRing); - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_done, 100, 100); } - + public static PGPKeyRing decodeKeyRing(InputStream is) throws IOException { InputStream in = PGPUtil.getDecoderStream(is); PGPObjectFactory objectFactory = new PGPObjectFactory(in); Object obj = objectFactory.nextObject(); - + if (obj instanceof PGPKeyRing) { return (PGPKeyRing) obj; } - + return null; } - + public static int storeKeyRingInCache(PGPKeyRing keyring) { int status = Integer.MIN_VALUE; // out of bounds value (Id.retrun_value.*) try { @@ -623,16 +599,18 @@ public class Apg { PGPSecretKeyRing secretKeyRing = (PGPSecretKeyRing) keyring; boolean save = true; try { - PGPPrivateKey testKey = secretKeyRing.getSecretKey().extractPrivateKey(new char[] {}, new BouncyCastleProvider()); + PGPPrivateKey testKey = secretKeyRing.getSecretKey().extractPrivateKey( + new char[] {}, new BouncyCastleProvider()); if (testKey == null) { - // this is bad, something is very wrong... likely a --export-secret-subkeys export + // this is bad, something is very wrong... likely a --export-secret-subkeys + // export save = false; status = Id.return_value.bad; } } catch (PGPException e) { // all good if this fails, we likely didn't use the right password } - + if (save) { status = mDatabase.saveKeyRing(secretKeyRing); } @@ -645,24 +623,24 @@ public class Apg { } catch (Database.GeneralException e) { status = Id.return_value.error; } - + return status; } - + public static boolean uploadKeyRingToServer(HkpKeyServer server, PGPPublicKeyRing keyring) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ArmoredOutputStream aos = new ArmoredOutputStream(bos); try { aos.write(keyring.getEncoded()); aos.close(); - + String armouredKey = bos.toString("UTF-8"); server.add(armouredKey); - + return true; } catch (IOException e) { return false; - } catch(AddKeyException e) { + } catch (AddKeyException e) { // TODO: tell the user? return false; } finally { @@ -673,17 +651,16 @@ public class Apg { } } - public static Bundle importKeyRings(Activity context, int type, - InputData data, - ProgressDialogUpdater progress) - throws GeneralException, FileNotFoundException, PGPException, IOException { + public static Bundle importKeyRings(Activity context, int type, InputData data, + ProgressDialogUpdater progress) throws GeneralException, FileNotFoundException, + PGPException, IOException { Bundle returnData = new Bundle(); if (type == Id.type.secret_key) { - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_importingSecretKeys, 0, 100); } else { - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_importingPublicKeys, 0, 100); } @@ -703,10 +680,10 @@ public class Apg { PGPKeyRing keyring = decodeKeyRing(bufferedInput); while (keyring != null) { int status = Integer.MIN_VALUE; // out of bounds value - + // if this key is what we expect it to be, save it - if ((type == Id.type.secret_key && keyring instanceof PGPSecretKeyRing) || - (type == Id.type.public_key && keyring instanceof PGPPublicKeyRing)) { + if ((type == Id.type.secret_key && keyring instanceof PGPSecretKeyRing) + || (type == Id.type.public_key && keyring instanceof PGPPublicKeyRing)) { status = storeKeyRingInCache(keyring); } @@ -722,12 +699,12 @@ public class Apg { } else if (status == Id.return_value.bad) { ++badKeys; } - + if (progress != null) { - progress.setProgress((int)(100 * progressIn.position() / data.getSize()), 100); + progress.setProgress((int) (100 * progressIn.position() / data.getSize()), 100); } - //TODO: needed? - //obj = objectFactory.nextObject(); + // TODO: needed? + // obj = objectFactory.nextObject(); keyring = decodeKeyRing(bufferedInput); } @@ -739,23 +716,22 @@ public class Apg { returnData.putInt("updated", oldKeys); returnData.putInt("bad", badKeys); - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_done, 100, 100); return returnData; } public static Bundle exportKeyRings(Activity context, Vector keyRingIds, - OutputStream outStream, - ProgressDialogUpdater progress) - throws GeneralException, FileNotFoundException, PGPException, IOException { + OutputStream outStream, ProgressDialogUpdater progress) throws GeneralException, + FileNotFoundException, PGPException, IOException { Bundle returnData = new Bundle(); if (keyRingIds.size() == 1) { - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_exportingKey, 0, 100); } else { - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_exportingKeys, 0, 100); } @@ -766,7 +742,7 @@ public class Apg { int numKeys = 0; for (int i = 0; i < keyRingIds.size(); ++i) { - if( progress != null ) + if (progress != null) progress.setProgress(i * 100 / keyRingIds.size(), 100); Object obj = mDatabase.getKeyRing(keyRingIds.get(i)); PGPPublicKeyRing publicKeyRing; @@ -786,7 +762,7 @@ public class Apg { out.close(); returnData.putInt("exported", numKeys); - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_done, 100, 100); return returnData; @@ -878,8 +854,8 @@ public class Apg { Date creationDate = getCreationDate(key); Date expiryDate = getExpiryDate(key); Date now = new Date(); - if (now.compareTo(creationDate) >= 0 && - (expiryDate == null || now.compareTo(expiryDate) <= 0)) { + if (now.compareTo(creationDate) >= 0 + && (expiryDate == null || now.compareTo(expiryDate) <= 0)) { return false; } return true; @@ -1007,15 +983,15 @@ public class Apg { } PGPSignatureSubpacketVector hashed = sig.getHashedSubPackets(); - if (hashed != null &&(hashed.getKeyFlags() & - (KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE)) != 0) { + 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) { + if (unhashed != null + && (unhashed.getKeyFlags() & (KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE)) != 0) { return true; } } @@ -1073,28 +1049,28 @@ public class Apg { String algorithmStr = null; switch (algorithm) { - case PGPPublicKey.RSA_ENCRYPT: - case PGPPublicKey.RSA_GENERAL: - case PGPPublicKey.RSA_SIGN: { - algorithmStr = "RSA"; - break; - } + case PGPPublicKey.RSA_ENCRYPT: + case PGPPublicKey.RSA_GENERAL: + case PGPPublicKey.RSA_SIGN: { + algorithmStr = "RSA"; + break; + } - case PGPPublicKey.DSA: { - algorithmStr = "DSA"; - break; - } + case PGPPublicKey.DSA: { + algorithmStr = "DSA"; + break; + } - case PGPPublicKey.ELGAMAL_ENCRYPT: - case PGPPublicKey.ELGAMAL_GENERAL: { - algorithmStr = "ElGamal"; - break; - } + case PGPPublicKey.ELGAMAL_ENCRYPT: + case PGPPublicKey.ELGAMAL_GENERAL: { + algorithmStr = "ElGamal"; + break; + } - default: { - algorithmStr = "???"; - break; - } + default: { + algorithmStr = "???"; + break; + } } return algorithmStr + ", " + keySize + "bit"; } @@ -1115,9 +1091,9 @@ public class Apg { } return fingerPrint; - + } - + public static String getFingerPrint(long keyId) { PGPPublicKey key = Apg.getPublicKey(keyId); if (key == null) { @@ -1174,7 +1150,7 @@ public class Apg { } return null; } - + public static PGPPublicKeyRing getPublicKeyRing(long keyId) { byte[] data = mDatabase.getKeyRingDataFromKeyId(Id.database.type_public, keyId); if (data == null) { @@ -1202,17 +1178,15 @@ public class Apg { if (keyRing == null) { return null; } - + return keyRing.getPublicKey(keyId); } public static Vector getKeyRingIds(int type) { SQLiteDatabase db = mDatabase.db(); Vector keyIds = new Vector(); - Cursor c = db.query(KeyRings.TABLE_NAME, - new String[] { KeyRings._ID }, - KeyRings.TYPE + " = ?", new String[] { "" + type }, - null, null, null); + Cursor c = db.query(KeyRings.TABLE_NAME, new String[] { KeyRings._ID }, KeyRings.TYPE + + " = ?", new String[] { "" + type }, null, null, null); if (c != null && c.moveToFirst()) { do { keyIds.add(c.getInt(0)); @@ -1228,25 +1202,16 @@ public class Apg { public static String getMainUserId(long keyId, int type) { SQLiteDatabase db = mDatabase.db(); - Cursor c = db.query(Keys.TABLE_NAME + " INNER JOIN " + KeyRings.TABLE_NAME + " ON (" + - KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + - Keys.TABLE_NAME + "." + Keys.KEY_RING_ID + ") " + - " INNER JOIN " + Keys.TABLE_NAME + " AS masterKey ON (" + - KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + - "masterKey." + Keys.KEY_RING_ID + " AND " + - "masterKey." + Keys.IS_MASTER_KEY + " = '1') " + - " INNER JOIN " + UserIds.TABLE_NAME + " ON (" + - UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " = " + - "masterKey." + Keys._ID + " AND " + - UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0')", - new String[] { UserIds.USER_ID }, - Keys.TABLE_NAME + "." + Keys.KEY_ID + " = ? AND " + - KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?", - new String[] { - "" + keyId, - "" + type, - }, - null, null, null); + Cursor c = db.query(Keys.TABLE_NAME + " INNER JOIN " + KeyRings.TABLE_NAME + " ON (" + + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME + "." + + Keys.KEY_RING_ID + ") " + " INNER JOIN " + Keys.TABLE_NAME + " AS masterKey ON (" + + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + "masterKey." + + Keys.KEY_RING_ID + " AND " + "masterKey." + Keys.IS_MASTER_KEY + " = '1') " + + " INNER JOIN " + UserIds.TABLE_NAME + " ON (" + UserIds.TABLE_NAME + "." + + UserIds.KEY_ID + " = " + "masterKey." + Keys._ID + " AND " + UserIds.TABLE_NAME + + "." + UserIds.RANK + " = '0')", new String[] { UserIds.USER_ID }, Keys.TABLE_NAME + + "." + Keys.KEY_ID + " = ? AND " + KeyRings.TABLE_NAME + "." + KeyRings.TYPE + + " = ?", new String[] { "" + keyId, "" + type, }, null, null, null); String userId = ""; if (c != null && c.moveToFirst()) { do { @@ -1261,15 +1226,10 @@ public class Apg { return userId; } - public static void encrypt(Context context, - InputData data, OutputStream outStream, - boolean armored, - long encryptionKeyIds[], long signatureKeyId, - String signaturePassPhrase, - ProgressDialogUpdater progress, - int symmetricAlgorithm, int hashAlgorithm, int compression, - boolean forceV3Signature, - String passPhrase) + public static void encrypt(Context context, InputData data, OutputStream outStream, + boolean armored, long encryptionKeyIds[], long signatureKeyId, + String signaturePassPhrase, ProgressDialogUpdater progress, int symmetricAlgorithm, + int hashAlgorithm, int compression, boolean forceV3Signature, String passPhrase) throws IOException, GeneralException, PGPException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException { Security.addProvider(new BouncyCastleProvider()); @@ -1293,7 +1253,8 @@ public class Apg { PGPPrivateKey signaturePrivateKey = null; if (encryptionKeyIds.length == 0 && passPhrase == null) { - throw new GeneralException(context.getString(R.string.error_noEncryptionKeysOrPassPhrase)); + throw new GeneralException( + context.getString(R.string.error_noEncryptionKeysOrPassPhrase)); } if (signatureKeyId != 0) { @@ -1306,21 +1267,21 @@ public class Apg { if (signaturePassPhrase == null) { throw new GeneralException(context.getString(R.string.error_noSignaturePassPhrase)); } - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_extractingSignatureKey, 0, 100); signaturePrivateKey = signingKey.extractPrivateKey(signaturePassPhrase.toCharArray(), - new BouncyCastleProvider()); + new BouncyCastleProvider()); if (signaturePrivateKey == null) { - throw new GeneralException(context.getString(R.string.error_couldNotExtractPrivateKey)); + throw new GeneralException( + context.getString(R.string.error_couldNotExtractPrivateKey)); } } - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_preparingStreams, 5, 100); // encrypt and compress input file content - PGPEncryptedDataGenerator cPk = - new PGPEncryptedDataGenerator(symmetricAlgorithm, true, new SecureRandom(), - new BouncyCastleProvider()); + PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(symmetricAlgorithm, true, + new SecureRandom(), new BouncyCastleProvider()); if (encryptionKeyIds.length == 0) { // symmetric encryption @@ -1338,19 +1299,15 @@ public class Apg { PGPV3SignatureGenerator signatureV3Generator = null; if (signatureKeyId != 0) { - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_preparingSignature, 10, 100); if (forceV3Signature) { - signatureV3Generator = - new PGPV3SignatureGenerator(signingKey.getPublicKey().getAlgorithm(), - hashAlgorithm, - new BouncyCastleProvider()); + signatureV3Generator = new PGPV3SignatureGenerator(signingKey.getPublicKey() + .getAlgorithm(), hashAlgorithm, new BouncyCastleProvider()); signatureV3Generator.initSign(PGPSignature.BINARY_DOCUMENT, signaturePrivateKey); } else { - signatureGenerator = - new PGPSignatureGenerator(signingKey.getPublicKey().getAlgorithm(), - hashAlgorithm, - new BouncyCastleProvider()); + signatureGenerator = new PGPSignatureGenerator(signingKey.getPublicKey() + .getAlgorithm(), hashAlgorithm, new BouncyCastleProvider()); signatureGenerator.initSign(PGPSignature.BINARY_DOCUMENT, signaturePrivateKey); String userId = getMainUserId(getMasterKey(signingKeyRing)); @@ -1378,9 +1335,9 @@ public class Apg { PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator(); // file name not needed, so empty string - OutputStream pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "", - new Date(), new byte[1 << 16]); - if( progress != null ) + OutputStream pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "", new Date(), + new byte[1 << 16]); + if (progress != null) progress.setProgress(R.string.progress_encrypting, 20, 100); long done = 0; @@ -1398,7 +1355,7 @@ public class Apg { } done += n; if (data.getSize() != 0) { - if( progress != null ) + if (progress != null) progress.setProgress((int) (20 + (95 - 20) * done / data.getSize()), 100); } } @@ -1406,7 +1363,7 @@ public class Apg { literalGen.close(); if (signatureKeyId != 0) { - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_generatingSignature, 95, 100); if (forceV3Signature) { signatureV3Generator.generate().encode(pOut); @@ -1422,18 +1379,14 @@ public class Apg { armorOut.close(); } - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_done, 100, 100); } - public static void signText(Context context, - InputData data, OutputStream outStream, - long signatureKeyId, String signaturePassPhrase, - int hashAlgorithm, - boolean forceV3Signature, - ProgressDialogUpdater progress) - throws GeneralException, PGPException, IOException, NoSuchAlgorithmException, - SignatureException { + public static void signText(Context context, InputData data, OutputStream outStream, + long signatureKeyId, String signaturePassPhrase, int hashAlgorithm, + boolean forceV3Signature, ProgressDialogUpdater progress) throws GeneralException, + PGPException, IOException, NoSuchAlgorithmException, SignatureException { Security.addProvider(new BouncyCastleProvider()); ArmoredOutputStream armorOut = new ArmoredOutputStream(outStream); @@ -1456,32 +1409,29 @@ public class Apg { if (signaturePassPhrase == null) { throw new GeneralException(context.getString(R.string.error_noSignaturePassPhrase)); } - signaturePrivateKey = - signingKey.extractPrivateKey(signaturePassPhrase.toCharArray(), - new BouncyCastleProvider()); + signaturePrivateKey = signingKey.extractPrivateKey(signaturePassPhrase.toCharArray(), + new BouncyCastleProvider()); if (signaturePrivateKey == null) { throw new GeneralException(context.getString(R.string.error_couldNotExtractPrivateKey)); } - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_preparingStreams, 0, 100); - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_preparingSignature, 30, 100); PGPSignatureGenerator signatureGenerator = null; PGPV3SignatureGenerator signatureV3Generator = null; if (forceV3Signature) { - signatureV3Generator = - new PGPV3SignatureGenerator(signingKey.getPublicKey().getAlgorithm(), - hashAlgorithm, - new BouncyCastleProvider()); - signatureV3Generator.initSign(PGPSignature.CANONICAL_TEXT_DOCUMENT, signaturePrivateKey); + signatureV3Generator = new PGPV3SignatureGenerator(signingKey.getPublicKey() + .getAlgorithm(), hashAlgorithm, new BouncyCastleProvider()); + signatureV3Generator + .initSign(PGPSignature.CANONICAL_TEXT_DOCUMENT, signaturePrivateKey); } else { - signatureGenerator = - new PGPSignatureGenerator(signingKey.getPublicKey().getAlgorithm(), - hashAlgorithm, - new BouncyCastleProvider()); + signatureGenerator = new PGPSignatureGenerator( + signingKey.getPublicKey().getAlgorithm(), hashAlgorithm, + new BouncyCastleProvider()); signatureGenerator.initSign(PGPSignature.CANONICAL_TEXT_DOCUMENT, signaturePrivateKey); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); @@ -1490,7 +1440,7 @@ public class Apg { signatureGenerator.setHashedSubpackets(spGen.generate()); } - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_signing, 40, 100); armorOut.beginClearText(hashAlgorithm); @@ -1534,17 +1484,13 @@ public class Apg { } armorOut.close(); - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_done, 100, 100); } - public static void generateSignature(Context context, - InputData data, OutputStream outStream, - boolean armored, boolean binary, - long signatureKeyId, String signaturePassPhrase, - int hashAlgorithm, - boolean forceV3Signature, - ProgressDialogUpdater progress) + public static void generateSignature(Context context, InputData data, OutputStream outStream, + boolean armored, boolean binary, long signatureKeyId, String signaturePassPhrase, + int hashAlgorithm, boolean forceV3Signature, ProgressDialogUpdater progress) throws GeneralException, PGPException, IOException, NoSuchAlgorithmException, SignatureException { Security.addProvider(new BouncyCastleProvider()); @@ -1576,16 +1522,15 @@ public class Apg { if (signaturePassPhrase == null) { throw new GeneralException(context.getString(R.string.error_noSignaturePassPhrase)); } - signaturePrivateKey = - signingKey.extractPrivateKey(signaturePassPhrase.toCharArray(), - new BouncyCastleProvider()); + signaturePrivateKey = signingKey.extractPrivateKey(signaturePassPhrase.toCharArray(), + new BouncyCastleProvider()); if (signaturePrivateKey == null) { throw new GeneralException(context.getString(R.string.error_couldNotExtractPrivateKey)); } - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_preparingStreams, 0, 100); - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_preparingSignature, 30, 100); PGPSignatureGenerator signatureGenerator = null; @@ -1597,16 +1542,13 @@ public class Apg { } if (forceV3Signature) { - signatureV3Generator = - new PGPV3SignatureGenerator(signingKey.getPublicKey().getAlgorithm(), - hashAlgorithm, - new BouncyCastleProvider()); + signatureV3Generator = new PGPV3SignatureGenerator(signingKey.getPublicKey() + .getAlgorithm(), hashAlgorithm, new BouncyCastleProvider()); signatureV3Generator.initSign(type, signaturePrivateKey); } else { - signatureGenerator = - new PGPSignatureGenerator(signingKey.getPublicKey().getAlgorithm(), - hashAlgorithm, - new BouncyCastleProvider()); + signatureGenerator = new PGPSignatureGenerator( + signingKey.getPublicKey().getAlgorithm(), hashAlgorithm, + new BouncyCastleProvider()); signatureGenerator.initSign(type, signaturePrivateKey); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); @@ -1615,7 +1557,7 @@ public class Apg { signatureGenerator.setHashedSubpackets(spGen.generate()); } - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_signing, 40, 100); InputStream inStream = data.getInputStream(); @@ -1659,12 +1601,12 @@ public class Apg { out.close(); outStream.close(); - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_done, 100, 100); } - public static long getDecryptionKeyId(Context context, InputData data) - throws GeneralException, NoAsymmetricEncryptionException, IOException { + public static long getDecryptionKeyId(Context context, InputData data) throws GeneralException, + NoAsymmetricEncryptionException, IOException { InputStream in = PGPUtil.getDecoderStream(data.getInputStream()); PGPObjectFactory pgpF = new PGPObjectFactory(in); PGPEncryptedDataList enc; @@ -1738,10 +1680,8 @@ public class Apg { return false; } - public static Bundle decrypt(Context context, - InputData data, OutputStream outStream, - String passPhrase, ProgressDialogUpdater progress, - boolean assumeSymmetric) + public static Bundle decrypt(Context context, InputData data, OutputStream outStream, + String passPhrase, ProgressDialogUpdater progress, boolean assumeSymmetric) throws IOException, GeneralException, PGPException, SignatureException { if (passPhrase == null) { passPhrase = ""; @@ -1754,7 +1694,7 @@ public class Apg { long signatureKeyId = 0; int currentProgress = 0; - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_readingData, currentProgress, 100); if (o instanceof PGPEncryptedDataList) { @@ -1787,16 +1727,17 @@ public class Apg { } if (pbe == null) { - throw new GeneralException(context.getString(R.string.error_noSymmetricEncryptionPacket)); + throw new GeneralException( + context.getString(R.string.error_noSymmetricEncryptionPacket)); } - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_preparingStreams, currentProgress, 100); clear = pbe.getDataStream(passPhrase.toCharArray(), new BouncyCastleProvider()); encryptedData = pbe; currentProgress += 5; } else { - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_findingKey, currentProgress, 100); PGPPublicKeyEncryptedData pbe = null; PGPSecretKey secretKey = null; @@ -1819,20 +1760,21 @@ public class Apg { } currentProgress += 5; - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_extractingKey, currentProgress, 100); PGPPrivateKey privateKey = null; try { privateKey = secretKey.extractPrivateKey(passPhrase.toCharArray(), - new BouncyCastleProvider()); + new BouncyCastleProvider()); } catch (PGPException e) { throw new PGPException(context.getString(R.string.error_wrongPassPhrase)); } if (privateKey == null) { - throw new GeneralException(context.getString(R.string.error_couldNotExtractPrivateKey)); + throw new GeneralException( + context.getString(R.string.error_couldNotExtractPrivateKey)); } currentProgress += 5; - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_preparingStreams, currentProgress, 100); clear = pbe.getDataStream(privateKey, new BouncyCastleProvider()); encryptedData = pbe; @@ -1846,17 +1788,17 @@ public class Apg { int signatureIndex = -1; if (dataChunk instanceof PGPCompressedData) { - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_decompressingData, currentProgress, 100); - PGPObjectFactory fact = - new PGPObjectFactory(((PGPCompressedData) dataChunk).getDataStream()); + PGPObjectFactory fact = new PGPObjectFactory( + ((PGPCompressedData) dataChunk).getDataStream()); dataChunk = fact.nextObject(); plainFact = fact; currentProgress += 10; } if (dataChunk instanceof PGPOnePassSignatureList) { - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_processingSignature, currentProgress, 100); returnData.putBoolean(EXTRA_SIGNATURE, true); PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk; @@ -1898,7 +1840,7 @@ public class Apg { } if (dataChunk instanceof PGPLiteralData) { - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_decrypting, currentProgress, 100); PGPLiteralData literalData = (PGPLiteralData) dataChunk; OutputStream out = outStream; @@ -1928,19 +1870,20 @@ public class Apg { } } // unknown size, but try to at least have a moving, slowing down progress bar - currentProgress = startProgress + (endProgress - startProgress) * done / (done + 100000); + currentProgress = startProgress + (endProgress - startProgress) * done + / (done + 100000); if (data.getSize() - startPos == 0) { currentProgress = endProgress; } else { - currentProgress = (int)(startProgress + (endProgress - startProgress) * - (data.getStreamPosition() - startPos) / (data.getSize() - startPos)); + currentProgress = (int) (startProgress + (endProgress - startProgress) + * (data.getStreamPosition() - startPos) / (data.getSize() - startPos)); } - if( progress != null ) + if (progress != null) progress.setProgress(currentProgress, 100); } if (signature != null) { - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_verifyingSignature, 90, 100); PGPSignatureList signatureList = (PGPSignatureList) plainFact.nextObject(); PGPSignature messageSignature = signatureList.get(signatureIndex); @@ -1954,7 +1897,7 @@ public class Apg { // TODO: add integrity somewhere if (encryptedData.isIntegrityProtected()) { - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_verifyingIntegrity, 95, 100); if (encryptedData.verify()) { // passed @@ -1965,21 +1908,20 @@ public class Apg { // no integrity check } - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_done, 100, 100); return returnData; } - public static Bundle verifyText(BaseActivity context, - InputData data, OutputStream outStream, - ProgressDialogUpdater progress) - throws IOException, GeneralException, PGPException, SignatureException { + public static Bundle verifyText(BaseActivity context, InputData data, OutputStream outStream, + ProgressDialogUpdater progress) throws IOException, GeneralException, PGPException, + SignatureException { Bundle returnData = new Bundle(); ByteArrayOutputStream out = new ByteArrayOutputStream(); ArmoredInputStream aIn = new ArmoredInputStream(data.getInputStream()); - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_done, 0, 100); // mostly taken from ClearSignedFileProcessor @@ -2005,7 +1947,7 @@ public class Apg { returnData.putBoolean(EXTRA_SIGNATURE, true); - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_processingSignature, 60, 100); PGPObjectFactory pgpFact = new PGPObjectFactory(aIn); @@ -2053,7 +1995,7 @@ public class Apg { if (signature == null) { returnData.putBoolean(EXTRA_SIGNATURE_UNKNOWN, true); - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_done, 100, 100); return returnData; } @@ -2070,29 +2012,26 @@ public class Apg { do { lookAhead = readInputLine(lineOut, lookAhead, sigIn); - signature.update((byte)'\r'); - signature.update((byte)'\n'); + signature.update((byte) '\r'); + signature.update((byte) '\n'); processLine(signature, lineOut.toByteArray()); - } - while (lookAhead != -1); + } while (lookAhead != -1); } returnData.putBoolean(EXTRA_SIGNATURE_SUCCESS, signature.verify()); - if( progress != null ) + if (progress != null) progress.setProgress(R.string.progress_done, 100, 100); return returnData; } - public static int getStreamContent(Context context, InputStream inStream) - throws IOException { + 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) { + if (object instanceof PGPPublicKeyRing || object instanceof PGPSecretKeyRing) { return Id.content.keys; } else if (object instanceof PGPEncryptedDataList) { return Id.content.encrypted_data; @@ -2103,10 +2042,8 @@ public class Apg { return Id.content.unknown; } - private static void processLine(final String pLine, - final ArmoredOutputStream pArmoredOutput, - final PGPSignatureGenerator pSignatureGenerator) - throws IOException, SignatureException { + private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput, + final PGPSignatureGenerator pSignatureGenerator) throws IOException, SignatureException { if (pLine == null) { return; @@ -2130,10 +2067,9 @@ public class Apg { pSignatureGenerator.update(data); } - private static void processLine(final String pLine, - final ArmoredOutputStream pArmoredOutput, - final PGPV3SignatureGenerator pSignatureGenerator) - throws IOException, SignatureException { + private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput, + final PGPV3SignatureGenerator pSignatureGenerator) throws IOException, + SignatureException { if (pLine == null) { return; @@ -2158,8 +2094,8 @@ public class Apg { } // taken from ClearSignedFileProcessor in BC - private static void processLine(PGPSignature sig, byte[] line) - throws SignatureException, IOException { + private static void processLine(PGPSignature sig, byte[] line) throws SignatureException, + IOException { int length = getLengthWithoutWhiteSpace(line); if (length > 0) { sig.update(line, 0, length); @@ -2167,7 +2103,7 @@ public class Apg { } private static int readInputLine(ByteArrayOutputStream bOut, InputStream fIn) - throws IOException { + throws IOException { bOut.reset(); int lookAhead = -1; @@ -2185,7 +2121,7 @@ public class Apg { } private static int readInputLine(ByteArrayOutputStream bOut, int lookAhead, InputStream fIn) - throws IOException { + throws IOException { bOut.reset(); int ch = lookAhead; @@ -2196,8 +2132,7 @@ public class Apg { lookAhead = readPassedEOL(bOut, ch, fIn); break; } - } - while ((ch = fIn.read()) >= 0); + } while ((ch = fIn.read()) >= 0); if (ch < 0) { lookAhead = -1; @@ -2207,7 +2142,7 @@ public class Apg { } private static int readPassedEOL(ByteArrayOutputStream bOut, int lastCh, InputStream fIn) - throws IOException { + throws IOException { int lookAhead = fIn.read(); if (lastCh == '\r' && lookAhead == '\n') { @@ -2251,7 +2186,7 @@ public class Apg { byte[] nlBytes = new byte[nl.length()]; for (int i = 0; i != nlBytes.length; i++) { - nlBytes[i] = (byte)nl.charAt(i); + nlBytes[i] = (byte) nl.charAt(i); } return nlBytes; @@ -2292,23 +2227,20 @@ public class Apg { public static String generateRandomString(int length) { SecureRandom random = new SecureRandom(); /* - try { - random = SecureRandom.getInstance("SHA1PRNG", new BouncyCastleProvider()); - } catch (NoSuchAlgorithmException e) { - // TODO: need to handle this case somehow - return null; - }*/ + * try { random = SecureRandom.getInstance("SHA1PRNG", new BouncyCastleProvider()); } catch + * (NoSuchAlgorithmException e) { // TODO: need to handle this case somehow return null; } + */ 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); + result += (char) ('0' + v); } else if (v < 36) { - result += (char)('A' + v - 10); + result += (char) ('A' + v - 10); } else if (v < 62) { - result += (char)('a' + v - 36); + result += (char) ('a' + v - 36); } else if (v == 62) { result += '_'; } else if (v == 63) { @@ -2328,7 +2260,7 @@ public class Apg { return size; } - static void deleteFileSecurely(Context context, File file, ProgressDialogUpdater progress) + public static void deleteFileSecurely(Context context, File file, ProgressDialogUpdater progress) throws FileNotFoundException, IOException { long length = file.length(); SecureRandom random = new SecureRandom(); @@ -2339,8 +2271,8 @@ public class Apg { int pos = 0; String msg = context.getString(R.string.progress_deletingSecurely, file.getName()); while (pos < length) { - if( progress != null ) - progress.setProgress(msg, (int)(100 * pos / length), 100); + if (progress != null) + progress.setProgress(msg, (int) (100 * pos / length), 100); random.nextBytes(data); raf.write(data); pos += data.length; diff --git a/src/org/thialfihar/android/apg/ApgService.java b/src/org/apg/ApgService.java similarity index 75% rename from src/org/thialfihar/android/apg/ApgService.java rename to src/org/apg/ApgService.java index 46d8b4765..82e85371d 100644 --- a/src/org/thialfihar/android/apg/ApgService.java +++ b/src/org/apg/ApgService.java @@ -1,4 +1,4 @@ -package org.thialfihar.android.apg; +package org.apg; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -11,9 +11,10 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import org.thialfihar.android.apg.provider.KeyRings; -import org.thialfihar.android.apg.provider.Keys; -import org.thialfihar.android.apg.provider.UserIds; +import org.apg.provider.KeyRings; +import org.apg.provider.Keys; +import org.apg.provider.UserIds; +import org.apg.IApgService; import android.content.ContentResolver; import android.content.Intent; @@ -31,28 +32,22 @@ public class ApgService extends Service { @Override public IBinder onBind(Intent intent) { - if( LOCAL_LOGD ) Log.d(TAG, "bound"); + if (LOCAL_LOGD) + Log.d(TAG, "bound"); return mBinder; } /** error status */ private static enum error { - ARGUMENTS_MISSING, - APG_FAILURE, - NO_MATCHING_SECRET_KEY, - PRIVATE_KEY_PASSPHRASE_WRONG, - PRIVATE_KEY_PASSPHRASE_MISSING; + ARGUMENTS_MISSING, APG_FAILURE, NO_MATCHING_SECRET_KEY, PRIVATE_KEY_PASSPHRASE_WRONG, PRIVATE_KEY_PASSPHRASE_MISSING; public int shiftedOrdinal() { return ordinal() + 100; } } - + private static enum call { - encrypt_with_passphrase, - encrypt_with_public_key, - decrypt, - get_keys + encrypt_with_passphrase, encrypt_with_public_key, decrypt, get_keys } /** all arguments that can be passed by calling application */ @@ -139,42 +134,49 @@ public class ApgService extends Service { private static final HashMap FUNCTIONS_DEFAULTS_METHODS = new HashMap(); static { try { - FUNCTIONS_DEFAULTS_METHODS.put("getDefaultEncryptionAlgorithm", Preferences.class.getMethod("getDefaultEncryptionAlgorithm")); - FUNCTIONS_DEFAULTS_METHODS.put("getDefaultHashAlgorithm", Preferences.class.getMethod("getDefaultHashAlgorithm")); - FUNCTIONS_DEFAULTS_METHODS.put("getDefaultAsciiArmour", Preferences.class.getMethod("getDefaultAsciiArmour")); - FUNCTIONS_DEFAULTS_METHODS.put("getForceV3Signatures", Preferences.class.getMethod("getForceV3Signatures")); - FUNCTIONS_DEFAULTS_METHODS.put("getDefaultMessageCompression", Preferences.class.getMethod("getDefaultMessageCompression")); + FUNCTIONS_DEFAULTS_METHODS.put("getDefaultEncryptionAlgorithm", + Preferences.class.getMethod("getDefaultEncryptionAlgorithm")); + FUNCTIONS_DEFAULTS_METHODS.put("getDefaultHashAlgorithm", + Preferences.class.getMethod("getDefaultHashAlgorithm")); + FUNCTIONS_DEFAULTS_METHODS.put("getDefaultAsciiArmour", + Preferences.class.getMethod("getDefaultAsciiArmour")); + FUNCTIONS_DEFAULTS_METHODS.put("getForceV3Signatures", + Preferences.class.getMethod("getForceV3Signatures")); + FUNCTIONS_DEFAULTS_METHODS.put("getDefaultMessageCompression", + Preferences.class.getMethod("getDefaultMessageCompression")); } catch (Exception e) { Log.e(TAG, "Function method exception: " + e.getMessage()); } } - + private static void writeToOutputStream(InputStream is, OutputStream os) throws IOException { byte[] buffer = new byte[8]; int len = 0; - while( (len = is.read(buffer)) != -1) { + while ((len = is.read(buffer)) != -1) { os.write(buffer, 0, len); } } private static Cursor getKeyEntries(HashMap pParams) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); - qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME - + "." + Keys.KEY_RING_ID + " AND " + Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " + UserIds.TABLE_NAME - + " ON " + "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " + UserIds.TABLE_NAME + "." - + UserIds.RANK + " = '0') "); + qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "(" + + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME + "." + + Keys.KEY_RING_ID + " AND " + Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + + " = '1'" + ") " + " INNER JOIN " + UserIds.TABLE_NAME + " ON " + "(" + + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." + + UserIds.KEY_ID + " AND " + UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') "); - String orderBy = pParams.containsKey("order_by") ? (String) pParams.get("order_by") : UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC"; + String orderBy = pParams.containsKey("order_by") ? (String) pParams.get("order_by") + : UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC"; String typeVal[] = null; String typeWhere = null; if (pParams.containsKey("key_type")) { typeWhere = KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?"; - typeVal = new String[] { - "" + pParams.get("key_type") - }; + typeVal = new String[] { "" + pParams.get("key_type") }; } - return qb.query(Apg.getDatabase().db(), (String[]) pParams.get("columns"), typeWhere, typeVal, null, null, orderBy); + return qb.query(Apg.getDatabase().db(), (String[]) pParams.get("columns"), typeWhere, + typeVal, null, null, orderBy); } /** @@ -197,40 +199,43 @@ public class ApgService extends Service { return 0; } } - + /** * maps fingerprints or user ids of keys to master keys in database * * @param search_keys - * a list of keys (fingerprints or user ids) to look for in - * database + * a list of keys (fingerprints or user ids) to look for in database * @return an array of master keys */ private static long[] getMasterKey(ArrayList pSearchKeys, Bundle pReturn) { HashMap qParams = new HashMap(); - qParams.put("columns", new String[] { - KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 0 + qParams.put("columns", new String[] { KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 0 UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 1 }); qParams.put("key_type", Id.database.type_public); Cursor mCursor = getKeyEntries(qParams); - if( LOCAL_LOGV ) Log.v(TAG, "going through installed user keys"); + if (LOCAL_LOGV) + Log.v(TAG, "going through installed user keys"); ArrayList masterKeys = new ArrayList(); while (mCursor.moveToNext()) { long curMkey = mCursor.getLong(0); String curUser = mCursor.getString(1); String curFprint = Apg.getSmallFingerPrint(curMkey); - if( LOCAL_LOGV ) Log.v(TAG, "current user: " + curUser + " (" + curFprint + ")"); + if (LOCAL_LOGV) + Log.v(TAG, "current user: " + curUser + " (" + curFprint + ")"); if (pSearchKeys.contains(curFprint) || pSearchKeys.contains(curUser)) { - if( LOCAL_LOGV ) Log.v(TAG, "master key found for: " + curFprint); + if (LOCAL_LOGV) + Log.v(TAG, "master key found for: " + curFprint); masterKeys.add(curMkey); pSearchKeys.remove(curFprint); } else { - if( LOCAL_LOGV ) Log.v(TAG, "Installed key " + curFprint + " is not in the list of public keys to encrypt with"); + if (LOCAL_LOGV) + Log.v(TAG, "Installed key " + curFprint + + " is not in the list of public keys to encrypt with"); } } mCursor.close(); @@ -243,12 +248,14 @@ public class ApgService extends Service { if (i == 0) { Log.w(TAG, "Found not one public key"); - pReturn.getStringArrayList(ret.WARNINGS.name()).add("Searched for public key(s) but found not one"); + pReturn.getStringArrayList(ret.WARNINGS.name()).add( + "Searched for public key(s) but found not one"); } for (String key : pSearchKeys) { Log.w(TAG, "Searched for key " + key + " but cannot find it in APG"); - pReturn.getStringArrayList(ret.WARNINGS.name()).add("Searched for key " + key + " but cannot find it in APG"); + pReturn.getStringArrayList(ret.WARNINGS.name()).add( + "Searched for key " + key + " but cannot find it in APG"); } return masterKeyLongs; @@ -269,18 +276,27 @@ public class ApgService extends Service { while (iter.hasNext()) { arg currentArg = iter.next(); String currentKey = currentArg.name(); - if (!pArgs.containsKey(currentKey) && FUNCTIONS_OPTIONAL_ARGS.get(pCall).contains(currentArg)) { + if (!pArgs.containsKey(currentKey) + && FUNCTIONS_OPTIONAL_ARGS.get(pCall).contains(currentArg)) { String currentFunctionName = FUNCTIONS_DEFAULTS.get(currentArg); try { - Class returnType = FUNCTIONS_DEFAULTS_METHODS.get(currentFunctionName).getReturnType(); + Class returnType = FUNCTIONS_DEFAULTS_METHODS.get(currentFunctionName) + .getReturnType(); if (returnType == String.class) { - pArgs.putString(currentKey, (String) FUNCTIONS_DEFAULTS_METHODS.get(currentFunctionName).invoke(preferences)); + pArgs.putString(currentKey, + (String) FUNCTIONS_DEFAULTS_METHODS.get(currentFunctionName) + .invoke(preferences)); } else if (returnType == boolean.class) { - pArgs.putBoolean(currentKey, (Boolean) FUNCTIONS_DEFAULTS_METHODS.get(currentFunctionName).invoke(preferences)); + pArgs.putBoolean(currentKey, + (Boolean) FUNCTIONS_DEFAULTS_METHODS.get(currentFunctionName) + .invoke(preferences)); } else if (returnType == int.class) { - pArgs.putInt(currentKey, (Integer) FUNCTIONS_DEFAULTS_METHODS.get(currentFunctionName).invoke(preferences)); + pArgs.putInt(currentKey, + (Integer) FUNCTIONS_DEFAULTS_METHODS.get(currentFunctionName) + .invoke(preferences)); } else { - Log.e(TAG, "Unknown return type " + returnType.toString() + " for default option"); + Log.e(TAG, "Unknown return type " + returnType.toString() + + " for default option"); } } catch (Exception e) { Log.e(TAG, "Exception in add_default_arguments " + e.getMessage()); @@ -320,19 +336,21 @@ public class ApgService extends Service { while (iter.hasNext()) { String curArg = iter.next().name(); if (!pArgs.containsKey(curArg)) { - pReturn.getStringArrayList(ret.ERRORS.name()).add("Argument missing: " + curArg); + pReturn.getStringArrayList(ret.ERRORS.name()) + .add("Argument missing: " + curArg); } } } - - if(pFunction.equals(call.encrypt_with_passphrase.name()) || - pFunction.equals(call.encrypt_with_public_key.name()) || - pFunction.equals(call.decrypt.name())) { + + if (pFunction.equals(call.encrypt_with_passphrase.name()) + || pFunction.equals(call.encrypt_with_public_key.name()) + || pFunction.equals(call.decrypt.name())) { // check that either MESSAGE or BLOB are there - if( !pArgs.containsKey(arg.MESSAGE.name()) && !pArgs.containsKey(arg.BLOB.name())) { - pReturn.getStringArrayList(ret.ERRORS.name()).add("Arguments missing: Neither MESSAGE nor BLOG found"); + if (!pArgs.containsKey(arg.MESSAGE.name()) && !pArgs.containsKey(arg.BLOB.name())) { + pReturn.getStringArrayList(ret.ERRORS.name()).add( + "Arguments missing: Neither MESSAGE nor BLOG found"); } - + } } @@ -363,7 +381,8 @@ public class ApgService extends Service { try { arg curArg = arg.valueOf(curKey); if (!allArgs.contains(curArg)) { - pReturn.getStringArrayList(ret.WARNINGS.name()).add("Unknown argument: " + curKey); + pReturn.getStringArrayList(ret.WARNINGS.name()).add( + "Unknown argument: " + curKey); unknownArgs.add(curKey); } } catch (Exception e) { @@ -386,23 +405,28 @@ public class ApgService extends Service { /* add default arguments if missing */ addDefaultArguments(pCall, pArgs); - if( LOCAL_LOGV ) Log.v(TAG, "add_default_arguments"); + if (LOCAL_LOGV) + Log.v(TAG, "add_default_arguments"); /* check for required arguments */ checkForRequiredArgs(pCall, pArgs, pReturn); - if( LOCAL_LOGV ) Log.v(TAG, "check_required_args"); + if (LOCAL_LOGV) + Log.v(TAG, "check_required_args"); /* check for unknown arguments and add to warning if found */ checkForUnknownArgs(pCall, pArgs, pReturn); - if( LOCAL_LOGV ) Log.v(TAG, "check_unknown_args"); + if (LOCAL_LOGV) + Log.v(TAG, "check_unknown_args"); /* return if errors happened */ if (pReturn.getStringArrayList(ret.ERRORS.name()).size() != 0) { - if( LOCAL_LOGV ) Log.v(TAG, "Errors after preparing, not executing "+pCall); + if (LOCAL_LOGV) + Log.v(TAG, "Errors after preparing, not executing " + pCall); pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.shiftedOrdinal()); return false; } - if( LOCAL_LOGV ) Log.v(TAG, "error return"); + if (LOCAL_LOGV) + Log.v(TAG, "error return"); return true; } @@ -414,7 +438,8 @@ public class ApgService extends Service { if (pArgs.containsKey(arg.PUBLIC_KEYS.name())) { ArrayList list = pArgs.getStringArrayList(arg.PUBLIC_KEYS.name()); ArrayList pubKeys = new ArrayList(); - if( LOCAL_LOGV ) Log.v(TAG, "Long size: " + list.size()); + if (LOCAL_LOGV) + Log.v(TAG, "Long size: " + list.size()); Iterator iter = list.iterator(); while (iter.hasNext()) { pubKeys.add(iter.next()); @@ -423,7 +448,7 @@ public class ApgService extends Service { } InputStream inStream = null; - if(isBlob) { + if (isBlob) { ContentResolver cr = getContentResolver(); try { inStream = cr.openInputStream(Uri.parse(pArgs.getString(arg.BLOB.name()))); @@ -436,14 +461,16 @@ public class ApgService extends Service { InputData in = new InputData(inStream, 0); // XXX Size second param? OutputStream out = new ByteArrayOutputStream(); - if( LOCAL_LOGV ) Log.v(TAG, "About to encrypt"); + if (LOCAL_LOGV) + Log.v(TAG, "About to encrypt"); try { Apg.encrypt(getBaseContext(), // context in, // input stream out, // output stream pArgs.getBoolean(arg.ARMORED_OUTPUT.name()), // ARMORED_OUTPUT pubMasterKeys, // encryption keys - getMasterKey(pArgs.getString(arg.SIGNATURE_KEY.name()), pReturn), // signature key + getMasterKey(pArgs.getString(arg.SIGNATURE_KEY.name()), pReturn), // signature + // key pArgs.getString(arg.PRIVATE_KEY_PASSPHRASE.name()), // signature passphrase null, // progress pArgs.getInt(arg.ENCRYPTION_ALGORYTHM.name()), // encryption @@ -451,27 +478,38 @@ public class ApgService extends Service { pArgs.getInt(arg.COMPRESSION.name()), // compression pArgs.getBoolean(arg.FORCE_V3_SIGNATURE.name()), // mPreferences.getForceV3Signatures(), pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) // passPhrase - ); + ); } catch (Exception e) { Log.e(TAG, "Exception in encrypt"); String msg = e.getMessage(); if (msg.equals(getBaseContext().getString(R.string.error_noSignaturePassPhrase))) { - pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " missing): " + msg); - pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_MISSING.shiftedOrdinal()); - } else if (msg.equals(getBaseContext().getString(R.string.error_couldNotExtractPrivateKey))) { - pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " probably wrong): " + msg); - pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.shiftedOrdinal()); + pReturn.getStringArrayList(ret.ERRORS.name()).add( + "Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " missing): " + + msg); + pReturn.putInt(ret.ERROR.name(), + error.PRIVATE_KEY_PASSPHRASE_MISSING.shiftedOrdinal()); + } else if (msg.equals(getBaseContext().getString( + R.string.error_couldNotExtractPrivateKey))) { + pReturn.getStringArrayList(ret.ERRORS.name()).add( + "Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + + " probably wrong): " + msg); + pReturn.putInt(ret.ERROR.name(), + error.PRIVATE_KEY_PASSPHRASE_WRONG.shiftedOrdinal()); } else { - pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when encrypting: " + e.getMessage()); + pReturn.getStringArrayList(ret.ERRORS.name()).add( + "Internal failure (" + e.getClass() + ") in APG when encrypting: " + + e.getMessage()); pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.shiftedOrdinal()); } return false; } - if( LOCAL_LOGV ) Log.v(TAG, "Encrypted"); - if(isBlob) { + if (LOCAL_LOGV) + Log.v(TAG, "Encrypted"); + if (isBlob) { ContentResolver cr = getContentResolver(); try { - OutputStream outStream = cr.openOutputStream(Uri.parse(pArgs.getString(arg.BLOB.name()))); + OutputStream outStream = cr.openOutputStream(Uri.parse(pArgs.getString(arg.BLOB + .name()))); writeToOutputStream(new ByteArrayInputStream(out.toString().getBytes()), outStream); outStream.close(); } catch (Exception e) { @@ -501,7 +539,8 @@ public class ApgService extends Service { ArrayList fPrints = new ArrayList(); ArrayList ids = new ArrayList(); while (cursor.moveToNext()) { - if( LOCAL_LOGV ) Log.v(TAG, "adding key "+Apg.getSmallFingerPrint(cursor.getLong(0))); + if (LOCAL_LOGV) + Log.v(TAG, "adding key " + Apg.getSmallFingerPrint(cursor.getLong(0))); fPrints.add(Apg.getSmallFingerPrint(cursor.getLong(0))); ids.add(cursor.getString(1)); } @@ -533,14 +572,15 @@ public class ApgService extends Service { if (!prepareArgs("decrypt", pArgs, pReturn)) { return false; } - + boolean isBlob = pArgs.containsKey(arg.BLOB.name()); - String passphrase = pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null ? pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) : pArgs + String passphrase = pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null ? pArgs + .getString(arg.SYMMETRIC_PASSPHRASE.name()) : pArgs .getString(arg.PRIVATE_KEY_PASSPHRASE.name()); InputStream inStream = null; - if(isBlob) { + if (isBlob) { ContentResolver cr = getContentResolver(); try { inStream = cr.openInputStream(Uri.parse(pArgs.getString(arg.BLOB.name()))); @@ -550,14 +590,15 @@ public class ApgService extends Service { } else { inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes()); } - + InputData in = new InputData(inStream, 0); // XXX what size in second parameter? OutputStream out = new ByteArrayOutputStream(); - if( LOCAL_LOGV ) Log.v(TAG, "About to decrypt"); + if (LOCAL_LOGV) + Log.v(TAG, "About to decrypt"); try { Apg.decrypt(getBaseContext(), in, out, passphrase, null, // progress pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null // symmetric - ); + ); } catch (Exception e) { Log.e(TAG, "Exception in decrypt"); String msg = e.getMessage(); @@ -565,25 +606,33 @@ public class ApgService extends Service { pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt: " + msg); pReturn.putInt(ret.ERROR.name(), error.NO_MATCHING_SECRET_KEY.shiftedOrdinal()); } else if (msg.equals(getBaseContext().getString(R.string.error_wrongPassPhrase))) { - pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " wrong/missing): " + msg); - pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.shiftedOrdinal()); + pReturn.getStringArrayList(ret.ERRORS.name()).add( + "Cannot decrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + + " wrong/missing): " + msg); + pReturn.putInt(ret.ERROR.name(), + error.PRIVATE_KEY_PASSPHRASE_WRONG.shiftedOrdinal()); } else { - pReturn.getStringArrayList(ret.ERRORS.name()).add("Internal failure (" + e.getClass() + ") in APG when decrypting: " + msg); + pReturn.getStringArrayList(ret.ERRORS.name()).add( + "Internal failure (" + e.getClass() + ") in APG when decrypting: " + + msg); pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.shiftedOrdinal()); } return false; } - if( LOCAL_LOGV ) Log.v(TAG, "... decrypted"); + if (LOCAL_LOGV) + Log.v(TAG, "... decrypted"); - if(isBlob) { + if (isBlob) { ContentResolver cr = getContentResolver(); try { - OutputStream outStream = cr.openOutputStream(Uri.parse(pArgs.getString(arg.BLOB.name()))); - writeToOutputStream(new ByteArrayInputStream(out.toString().getBytes()), outStream); + OutputStream outStream = cr.openOutputStream(Uri.parse(pArgs.getString(arg.BLOB + .name()))); + writeToOutputStream(new ByteArrayInputStream(out.toString().getBytes()), + outStream); outStream.close(); } catch (Exception e) { Log.e(TAG, "... exception on writing blob", e); - } + } } else { pReturn.putString(ret.RESULT.name(), out.toString()); } diff --git a/src/org/thialfihar/android/apg/AskForSecretKeyPassPhrase.java b/src/org/apg/AskForSecretKeyPassPhrase.java similarity index 58% rename from src/org/thialfihar/android/apg/AskForSecretKeyPassPhrase.java rename to src/org/apg/AskForSecretKeyPassPhrase.java index f473b157b..ebed75667 100644 --- a/src/org/thialfihar/android/apg/AskForSecretKeyPassPhrase.java +++ b/src/org/apg/AskForSecretKeyPassPhrase.java @@ -14,12 +14,13 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg; import org.spongycastle.jce.provider.BouncyCastleProvider; import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPPrivateKey; import org.spongycastle.openpgp.PGPSecretKey; +import org.apg.R; import android.app.Activity; import android.app.AlertDialog; @@ -38,7 +39,7 @@ public class AskForSecretKeyPassPhrase { } public static Dialog createDialog(Activity context, long secretKeyId, - PassPhraseCallbackInterface callback) { + PassPhraseCallbackInterface callback) { AlertDialog.Builder alert = new AlertDialog.Builder(context); alert.setTitle(R.string.title_authentication); @@ -66,8 +67,8 @@ public class AskForSecretKeyPassPhrase { alert.setMessage(context.getString(R.string.passPhraseFor, userId)); } - LayoutInflater inflater = - (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + LayoutInflater inflater = (LayoutInflater) context + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.pass_phrase, null); final EditText input = (EditText) view.findViewById(R.id.passPhrase); final EditText inputNotUsed = (EditText) view.findViewById(R.id.passPhraseAgain); @@ -76,42 +77,38 @@ public class AskForSecretKeyPassPhrase { alert.setView(view); final PassPhraseCallbackInterface cb = callback; - alert.setPositiveButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - activity.removeDialog(Id.dialog.pass_phrase); - String passPhrase = "" + input.getText(); - long keyId; - if (secretKey != null) { - try { - PGPPrivateKey testKey = secretKey.extractPrivateKey(passPhrase.toCharArray(), - new BouncyCastleProvider()); - if (testKey == null) { - Toast.makeText(activity, - R.string.error_couldNotExtractPrivateKey, - Toast.LENGTH_SHORT).show(); - return; - } - } catch (PGPException e) { - Toast.makeText(activity, - R.string.wrongPassPhrase, - Toast.LENGTH_SHORT).show(); - return; - } - keyId = secretKey.getKeyID(); - } else { - keyId = Id.key.symmetric; + alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + activity.removeDialog(Id.dialog.pass_phrase); + String passPhrase = "" + input.getText(); + long keyId; + if (secretKey != null) { + try { + PGPPrivateKey testKey = secretKey.extractPrivateKey( + passPhrase.toCharArray(), new BouncyCastleProvider()); + if (testKey == null) { + Toast.makeText(activity, R.string.error_couldNotExtractPrivateKey, + Toast.LENGTH_SHORT).show(); + return; } - cb.passPhraseCallback(keyId, passPhrase); + } catch (PGPException e) { + Toast.makeText(activity, R.string.wrongPassPhrase, Toast.LENGTH_SHORT) + .show(); + return; } - }); + keyId = secretKey.getKeyID(); + } else { + keyId = Id.key.symmetric; + } + cb.passPhraseCallback(keyId, passPhrase); + } + }); - alert.setNegativeButton(android.R.string.cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - activity.removeDialog(Id.dialog.pass_phrase); - } - }); + alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + activity.removeDialog(Id.dialog.pass_phrase); + } + }); return alert.create(); } diff --git a/src/org/thialfihar/android/apg/CachedPassPhrase.java b/src/org/apg/CachedPassPhrase.java similarity index 84% rename from src/org/thialfihar/android/apg/CachedPassPhrase.java rename to src/org/apg/CachedPassPhrase.java index 4a3b86500..2d67a300d 100644 --- a/src/org/thialfihar/android/apg/CachedPassPhrase.java +++ b/src/org/apg/CachedPassPhrase.java @@ -1,4 +1,4 @@ -package org.thialfihar.android.apg; +package org.apg; public class CachedPassPhrase { public final long timestamp; @@ -11,14 +11,14 @@ public class CachedPassPhrase { } @Override - public int hashCode() { - int hc1 = (int)(this.timestamp & 0xffffffff); + public int hashCode() { + int hc1 = (int) (this.timestamp & 0xffffffff); int hc2 = (this.passPhrase == null ? 0 : this.passPhrase.hashCode()); return (hc1 + hc2) * hc2 + hc1; } @Override - public boolean equals(Object other) { + public boolean equals(Object other) { if (!(other instanceof CachedPassPhrase)) { return false; } @@ -42,7 +42,7 @@ public class CachedPassPhrase { } @Override - public String toString() { + public String toString() { return "(" + timestamp + ", *******)"; } } diff --git a/src/org/thialfihar/android/apg/Constants.java b/src/org/apg/Constants.java similarity index 98% rename from src/org/thialfihar/android/apg/Constants.java rename to src/org/apg/Constants.java index bd0746085..90822189a 100644 --- a/src/org/thialfihar/android/apg/Constants.java +++ b/src/org/apg/Constants.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg; import android.os.Environment; public final class Constants { - + public static final String tag = "APG"; - + public static final class path { public static final String app_dir = Environment.getExternalStorageDirectory() + "/APG"; } diff --git a/src/org/apg/DataDestination.java b/src/org/apg/DataDestination.java new file mode 100644 index 000000000..509670e69 --- /dev/null +++ b/src/org/apg/DataDestination.java @@ -0,0 +1,81 @@ +package org.apg; + +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import org.apg.Apg.GeneralException; +import org.apg.R; + +import android.content.Context; +import android.os.Environment; + +public class DataDestination { + private String mStreamFilename; + private String mFilename; + private int mMode = Id.mode.undefined; + + public DataDestination() { + + } + + public void setMode(int mode) { + mMode = mode; + } + + public void setFilename(String filename) { + mFilename = filename; + } + + public String getStreamFilename() { + return mStreamFilename; + } + + public OutputStream getOutputStream(Context context) throws Apg.GeneralException, + FileNotFoundException, IOException { + OutputStream out = null; + mStreamFilename = null; + + switch (mMode) { + case Id.mode.stream: { + try { + while (true) { + mStreamFilename = Apg.generateRandomString(32); + if (mStreamFilename == null) { + throw new Apg.GeneralException("couldn't generate random file name"); + } + context.openFileInput(mStreamFilename).close(); + } + } catch (FileNotFoundException e) { + // found a name that isn't used yet + } + out = context.openFileOutput(mStreamFilename, Context.MODE_PRIVATE); + break; + } + + case Id.mode.byte_array: { + out = new ByteArrayOutputStream(); + break; + } + + case Id.mode.file: { + if (mFilename.startsWith(Environment.getExternalStorageDirectory().getAbsolutePath())) { + if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + throw new GeneralException( + context.getString(R.string.error_externalStorageNotReady)); + } + } + out = new FileOutputStream(mFilename); + break; + } + + default: { + break; + } + } + + return out; + } +} diff --git a/src/org/thialfihar/android/apg/DataSource.java b/src/org/apg/DataSource.java similarity index 90% rename from src/org/thialfihar/android/apg/DataSource.java rename to src/org/apg/DataSource.java index e01da4590..340afa9f8 100644 --- a/src/org/thialfihar/android/apg/DataSource.java +++ b/src/org/apg/DataSource.java @@ -1,4 +1,4 @@ -package org.thialfihar.android.apg; +package org.apg; import java.io.ByteArrayInputStream; import java.io.File; @@ -7,7 +7,8 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import org.thialfihar.android.apg.Apg.GeneralException; +import org.apg.Apg.GeneralException; +import org.apg.R; import android.content.Context; import android.net.Uri; @@ -56,8 +57,8 @@ public class DataSource { return mData != null || mContentUri != null; } - public InputData getInputData(Context context, boolean withSize) - throws GeneralException, FileNotFoundException, IOException { + public InputData getInputData(Context context, boolean withSize) throws GeneralException, + FileNotFoundException, IOException { InputStream in = null; long size = 0; @@ -67,7 +68,8 @@ public class DataSource { String path = Uri.decode(mContentUri.toString().substring(7)); if (path.startsWith(Environment.getExternalStorageDirectory().getAbsolutePath())) { if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - throw new GeneralException(context.getString(R.string.error_externalStorageNotReady)); + throw new GeneralException( + context.getString(R.string.error_externalStorageNotReady)); } } in = new FileInputStream(path); diff --git a/src/org/thialfihar/android/apg/FileDialog.java b/src/org/apg/FileDialog.java similarity index 73% rename from src/org/thialfihar/android/apg/FileDialog.java rename to src/org/apg/FileDialog.java index a054b8518..6ad498b90 100644 --- a/src/org/thialfihar/android/apg/FileDialog.java +++ b/src/org/apg/FileDialog.java @@ -14,7 +14,9 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg; + +import org.apg.R; import android.app.Activity; import android.app.AlertDialog; @@ -41,18 +43,17 @@ public class FileDialog { public static interface OnClickListener { public void onCancelClick(); + public void onOkClick(String filename, boolean checkbox); } public static AlertDialog build(Activity activity, String title, String message, - String defaultFile, OnClickListener onClickListener, - String fileManagerTitle, String fileManagerButton, - String checkboxText, - int requestCode) { + String defaultFile, OnClickListener onClickListener, String fileManagerTitle, + String fileManagerButton, String checkboxText, int requestCode) { // TODO: fileManagerTitle and fileManagerButton are deprecated, no use for them right now, // but maybe the Intent now used will someday support them again, so leaving them in - LayoutInflater inflater = - (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + LayoutInflater inflater = (LayoutInflater) activity + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); AlertDialog.Builder alert = new AlertDialog.Builder(activity); alert.setTitle(title); @@ -87,22 +88,20 @@ public class FileDialog { final OnClickListener clickListener = onClickListener; alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - boolean checked = false; - if (mCheckBox.isEnabled()) { - checked = mCheckBox.isChecked(); - } - clickListener.onOkClick(mFilename.getText().toString(), - checked); - } - }); + public void onClick(DialogInterface dialog, int id) { + boolean checked = false; + if (mCheckBox.isEnabled()) { + checked = mCheckBox.isChecked(); + } + clickListener.onOkClick(mFilename.getText().toString(), checked); + } + }); - alert.setNegativeButton(android.R.string.cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - clickListener.onCancelClick(); - } - }); + alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + clickListener.onCancelClick(); + } + }); return alert.create(); } diff --git a/src/org/thialfihar/android/apg/HkpKeyServer.java b/src/org/apg/HkpKeyServer.java similarity index 89% rename from src/org/thialfihar/android/apg/HkpKeyServer.java rename to src/org/apg/HkpKeyServer.java index ea0bfddfd..294a60cb2 100644 --- a/src/org/thialfihar/android/apg/HkpKeyServer.java +++ b/src/org/apg/HkpKeyServer.java @@ -1,4 +1,4 @@ -package org.thialfihar.android.apg; +package org.apg; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -56,9 +56,15 @@ public class HkpKeyServer extends KeyServer { private short mPort = 11371; // example: - // pub 2048R/9F5C9090 2009-08-17 Jörg Runge <joerg@joergrunge.de> - public static Pattern PUB_KEY_LINE = Pattern.compile("pub +([0-9]+)([a-z]+)/.*?0x([0-9a-z]+).*? +([0-9-]+) +(.+)[\n\r]+((?: +.+[\n\r]+)*)", Pattern.CASE_INSENSITIVE); - public static Pattern USER_ID_LINE = Pattern.compile("^ +(.+)$", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE); + // pub 2048R/9F5C9090 2009-08-17 Jörg Runge + // <joerg@joergrunge.de> + public static Pattern PUB_KEY_LINE = Pattern + .compile( + "pub +([0-9]+)([a-z]+)/.*?0x([0-9a-z]+).*? +([0-9-]+) +(.+)[\n\r]+((?: +.+[\n\r]+)*)", + Pattern.CASE_INSENSITIVE); + public static Pattern USER_ID_LINE = Pattern.compile("^ +(.+)$", Pattern.MULTILINE + | Pattern.CASE_INSENSITIVE); public HkpKeyServer(String host) { mHost = host; @@ -119,7 +125,8 @@ public class HkpKeyServer extends KeyServer { // TODO: replace this with httpclient @Override - List search(String query) throws QueryException, TooManyResponses, InsufficientQuery { + public List search(String query) throws QueryException, TooManyResponses, + InsufficientQuery { Vector results = new Vector(); if (query.length() < 3) { @@ -160,7 +167,8 @@ public class HkpKeyServer extends KeyServer { info.keyId = Apg.keyFromHex(matcher.group(3)); info.fingerPrint = Apg.getSmallFingerPrint(info.keyId); String chunks[] = matcher.group(4).split("-"); - info.date = new GregorianCalendar(Integer.parseInt(chunks[0]), Integer.parseInt(chunks[1]), Integer.parseInt(chunks[2])).getTime(); + info.date = new GregorianCalendar(Integer.parseInt(chunks[0]), + Integer.parseInt(chunks[1]), Integer.parseInt(chunks[2])).getTime(); info.userIds = new Vector(); if (matcher.group(5).startsWith("*** KEY")) { info.revoked = matcher.group(5); @@ -184,16 +192,17 @@ public class HkpKeyServer extends KeyServer { } @Override - String get(long keyId) throws QueryException { + public String get(long keyId) throws QueryException { HttpClient client = new DefaultHttpClient(); try { - HttpGet get = new HttpGet("http://" + mHost + ":" + mPort + "/pks/lookup?op=get&search=0x" + Apg.keyToHex(keyId)); - + HttpGet get = new HttpGet("http://" + mHost + ":" + mPort + + "/pks/lookup?op=get&search=0x" + Apg.keyToHex(keyId)); + 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)); @@ -206,7 +215,7 @@ public class HkpKeyServer extends KeyServer { } finally { client.getConnectionManager().shutdown(); } - + return null; } @@ -215,11 +224,11 @@ public class HkpKeyServer extends KeyServer { HttpClient client = new DefaultHttpClient(); try { HttpPost post = new HttpPost("http://" + mHost + ":" + mPort + "/pks/add"); - + List nameValuePairs = new ArrayList(2); nameValuePairs.add(new BasicNameValuePair("keytext", armouredText)); post.setEntity(new UrlEncodedFormEntity(nameValuePairs)); - + HttpResponse response = client.execute(post); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { throw new AddKeyException(); diff --git a/src/org/thialfihar/android/apg/IApgService.aidl b/src/org/apg/IApgService.aidl similarity index 99% rename from src/org/thialfihar/android/apg/IApgService.aidl rename to src/org/apg/IApgService.aidl index 25780f366..8101bd2a4 100644 --- a/src/org/thialfihar/android/apg/IApgService.aidl +++ b/src/org/apg/IApgService.aidl @@ -1,4 +1,4 @@ -package org.thialfihar.android.apg; +package org.apg; interface IApgService { diff --git a/src/org/thialfihar/android/apg/Id.java b/src/org/apg/Id.java similarity index 99% rename from src/org/thialfihar/android/apg/Id.java rename to src/org/apg/Id.java index d874c48e4..e0ffa95cd 100644 --- a/src/org/thialfihar/android/apg/Id.java +++ b/src/org/apg/Id.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg; import org.spongycastle.bcpg.CompressionAlgorithmTags; public final class Id { - + public static final String TAG = "APG"; - + public static final class menu { public static final int export = 0x21070001; public static final int delete = 0x21070002; diff --git a/src/org/thialfihar/android/apg/InputData.java b/src/org/apg/InputData.java similarity index 83% rename from src/org/thialfihar/android/apg/InputData.java rename to src/org/apg/InputData.java index 49f66d5b6..ae5b51fe4 100644 --- a/src/org/thialfihar/android/apg/InputData.java +++ b/src/org/apg/InputData.java @@ -1,4 +1,4 @@ -package org.thialfihar.android.apg; +package org.apg; import java.io.InputStream; @@ -6,7 +6,7 @@ public class InputData { private PositionAwareInputStream mInputStream; private long mSize; - InputData(InputStream inputStream, long size) { + public InputData(InputStream inputStream, long size) { mInputStream = new PositionAwareInputStream(inputStream); mSize = size; } diff --git a/src/org/thialfihar/android/apg/KeyServer.java b/src/org/apg/KeyServer.java similarity index 79% rename from src/org/thialfihar/android/apg/KeyServer.java rename to src/org/apg/KeyServer.java index c6782632e..32158454f 100644 --- a/src/org/thialfihar/android/apg/KeyServer.java +++ b/src/org/apg/KeyServer.java @@ -1,4 +1,4 @@ -package org.thialfihar.android.apg; +package org.apg; import java.io.Serializable; import java.util.Date; @@ -8,35 +8,39 @@ import java.util.Vector; public abstract class KeyServer { static public class QueryException extends Exception { private static final long serialVersionUID = 2703768928624654512L; + public QueryException(String message) { super(message); } } - + static public class TooManyResponses extends Exception { private static final long serialVersionUID = 2703768928624654513L; } - + static public class InsufficientQuery extends Exception { private static final long serialVersionUID = 2703768928624654514L; } - + static public class AddKeyException extends Exception { private static final long serialVersionUID = -507574859137295530L; } - + static public class KeyInfo implements Serializable { private static final long serialVersionUID = -7797972113284992662L; - Vector userIds; - String revoked; - Date date; - String fingerPrint; - long keyId; - int size; - String algorithm; + public Vector userIds; + public String revoked; + public Date date; + public String fingerPrint; + public long keyId; + public int size; + public String algorithm; } - - abstract List search(String query) throws QueryException, TooManyResponses, InsufficientQuery; + + abstract List search(String query) throws QueryException, TooManyResponses, + InsufficientQuery; + abstract String get(long keyId) throws QueryException; + abstract void add(String armouredText) throws AddKeyException; } diff --git a/src/org/thialfihar/android/apg/PausableThread.java b/src/org/apg/PausableThread.java similarity index 88% rename from src/org/thialfihar/android/apg/PausableThread.java rename to src/org/apg/PausableThread.java index 8a68c8a28..87258d36c 100644 --- a/src/org/thialfihar/android/apg/PausableThread.java +++ b/src/org/apg/PausableThread.java @@ -1,4 +1,4 @@ -package org.thialfihar.android.apg; +package org.apg; public class PausableThread extends Thread { private boolean mPaused = false; @@ -22,8 +22,8 @@ public class PausableThread extends Thread { public void unpause() { synchronized (this) { - mPaused = false; - notify(); + mPaused = false; + notify(); } } diff --git a/src/org/thialfihar/android/apg/PositionAwareInputStream.java b/src/org/apg/PositionAwareInputStream.java similarity index 97% rename from src/org/thialfihar/android/apg/PositionAwareInputStream.java rename to src/org/apg/PositionAwareInputStream.java index 3b0fdc1f9..c59459670 100644 --- a/src/org/thialfihar/android/apg/PositionAwareInputStream.java +++ b/src/org/apg/PositionAwareInputStream.java @@ -1,4 +1,4 @@ -package org.thialfihar.android.apg; +package org.apg; import java.io.IOException; import java.io.InputStream; diff --git a/src/org/thialfihar/android/apg/Preferences.java b/src/org/apg/Preferences.java similarity index 90% rename from src/org/thialfihar/android/apg/Preferences.java rename to src/org/apg/Preferences.java index 198294377..0bd79290f 100644 --- a/src/org/thialfihar/android/apg/Preferences.java +++ b/src/org/apg/Preferences.java @@ -1,4 +1,4 @@ -package org.thialfihar.android.apg; +package org.apg; import org.spongycastle.bcpg.HashAlgorithmTags; import org.spongycastle.openpgp.PGPEncryptedData; @@ -15,17 +15,15 @@ public class Preferences { public static synchronized Preferences getPreferences(Context context) { return getPreferences(context, false); } - - public static synchronized Preferences getPreferences(Context context, boolean force_new) - { + + public static synchronized Preferences getPreferences(Context context, boolean force_new) { if (mPreferences == null || force_new) { mPreferences = new Preferences(context); } return mPreferences; } - private Preferences(Context context) - { + private Preferences(Context context) { mSharedPreferences = context.getSharedPreferences("APG.main", Context.MODE_PRIVATE); } @@ -57,7 +55,7 @@ public class Preferences { public int getDefaultEncryptionAlgorithm() { return mSharedPreferences.getInt(Constants.pref.default_encryption_algorithm, - PGPEncryptedData.AES_256); + PGPEncryptedData.AES_256); } public void setDefaultEncryptionAlgorithm(int value) { @@ -68,7 +66,7 @@ public class Preferences { public int getDefaultHashAlgorithm() { return mSharedPreferences.getInt(Constants.pref.default_hash_algorithm, - HashAlgorithmTags.SHA256); + HashAlgorithmTags.SHA256); } public void setDefaultHashAlgorithm(int value) { @@ -79,7 +77,7 @@ public class Preferences { public int getDefaultMessageCompression() { return mSharedPreferences.getInt(Constants.pref.default_message_compression, - Id.choice.compression.zlib); + Id.choice.compression.zlib); } public void setDefaultMessageCompression(int value) { @@ -90,7 +88,7 @@ public class Preferences { public int getDefaultFileCompression() { return mSharedPreferences.getInt(Constants.pref.default_file_compression, - Id.choice.compression.none); + Id.choice.compression.none); } public void setDefaultFileCompression(int value) { @@ -120,8 +118,7 @@ public class Preferences { } public boolean hasSeenChangeLog(String version) { - return mSharedPreferences.getBoolean(Constants.pref.has_seen_change_log + version, - false); + return mSharedPreferences.getBoolean(Constants.pref.has_seen_change_log + version, false); } public void setHasSeenChangeLog(String version, boolean value) { @@ -142,7 +139,7 @@ public class Preferences { public String[] getKeyServers() { String rawData = mSharedPreferences.getString(Constants.pref.key_servers, - Constants.defaults.key_servers); + Constants.defaults.key_servers); Vector servers = new Vector(); String chunks[] = rawData.split(","); for (int i = 0; i < chunks.length; ++i) { diff --git a/src/org/thialfihar/android/apg/Primes.java b/src/org/apg/Primes.java similarity index 99% rename from src/org/thialfihar/android/apg/Primes.java rename to src/org/apg/Primes.java index f0f391291..1fd6482b2 100644 --- a/src/org/thialfihar/android/apg/Primes.java +++ b/src/org/apg/Primes.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg; import java.math.BigInteger; diff --git a/src/org/thialfihar/android/apg/ProgressDialogUpdater.java b/src/org/apg/ProgressDialogUpdater.java similarity index 95% rename from src/org/thialfihar/android/apg/ProgressDialogUpdater.java rename to src/org/apg/ProgressDialogUpdater.java index 691a90353..043cca906 100644 --- a/src/org/thialfihar/android/apg/ProgressDialogUpdater.java +++ b/src/org/apg/ProgressDialogUpdater.java @@ -14,10 +14,12 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg; 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/src/org/thialfihar/android/apg/Service.java b/src/org/apg/Service.java similarity index 98% rename from src/org/thialfihar/android/apg/Service.java rename to src/org/apg/Service.java index 70bc80a16..24c4daa11 100644 --- a/src/org/thialfihar/android/apg/Service.java +++ b/src/org/apg/Service.java @@ -1,4 +1,4 @@ -package org.thialfihar.android.apg; +package org.apg; import android.content.Intent; import android.os.Binder; diff --git a/src/org/thialfihar/android/apg/provider/Accounts.java b/src/org/apg/provider/Accounts.java similarity index 95% rename from src/org/thialfihar/android/apg/provider/Accounts.java rename to src/org/apg/provider/Accounts.java index e1829ef4b..b95f079df 100644 --- a/src/org/thialfihar/android/apg/provider/Accounts.java +++ b/src/org/apg/provider/Accounts.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.thialfihar.android.apg.provider; +package org.apg.provider; import android.provider.BaseColumns; diff --git a/src/org/thialfihar/android/apg/provider/ApgServiceBlobDatabase.java b/src/org/apg/provider/ApgServiceBlobDatabase.java similarity index 95% rename from src/org/thialfihar/android/apg/provider/ApgServiceBlobDatabase.java rename to src/org/apg/provider/ApgServiceBlobDatabase.java index 9a891ddfa..70b9cd64f 100644 --- a/src/org/thialfihar/android/apg/provider/ApgServiceBlobDatabase.java +++ b/src/org/apg/provider/ApgServiceBlobDatabase.java @@ -1,6 +1,6 @@ -package org.thialfihar.android.apg.provider; +package org.apg.provider; -import org.thialfihar.android.apg.ApgService; +import org.apg.ApgService; import android.content.ContentUris; import android.content.ContentValues; diff --git a/src/org/thialfihar/android/apg/provider/ApgServiceBlobProvider.java b/src/org/apg/provider/ApgServiceBlobProvider.java similarity index 97% rename from src/org/thialfihar/android/apg/provider/ApgServiceBlobProvider.java rename to src/org/apg/provider/ApgServiceBlobProvider.java index fd4145f4c..18aa76d5e 100644 --- a/src/org/thialfihar/android/apg/provider/ApgServiceBlobProvider.java +++ b/src/org/apg/provider/ApgServiceBlobProvider.java @@ -1,7 +1,7 @@ -package org.thialfihar.android.apg.provider; +package org.apg.provider; -import org.thialfihar.android.apg.ApgService; -import org.thialfihar.android.apg.Constants; +import org.apg.ApgService; +import org.apg.Constants; import android.content.ContentProvider; import android.content.ContentValues; diff --git a/src/org/thialfihar/android/apg/provider/DataProvider.java b/src/org/apg/provider/DataProvider.java similarity index 99% rename from src/org/thialfihar/android/apg/provider/DataProvider.java rename to src/org/apg/provider/DataProvider.java index 9cf083528..a97851e58 100644 --- a/src/org/thialfihar/android/apg/provider/DataProvider.java +++ b/src/org/apg/provider/DataProvider.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.thialfihar.android.apg.provider; +package org.apg.provider; import java.io.File; import java.io.FileNotFoundException; import java.util.HashMap; -import org.thialfihar.android.apg.Id; +import org.apg.Id; import android.content.ContentProvider; import android.content.ContentValues; diff --git a/src/org/thialfihar/android/apg/provider/Database.java b/src/org/apg/provider/Database.java similarity index 99% rename from src/org/thialfihar/android/apg/provider/Database.java rename to src/org/apg/provider/Database.java index 92d8ae9fb..8b1aaa9e7 100644 --- a/src/org/thialfihar/android/apg/provider/Database.java +++ b/src/org/apg/provider/Database.java @@ -1,13 +1,13 @@ -package org.thialfihar.android.apg.provider; +package org.apg.provider; +import org.apg.Apg; +import org.apg.Id; +import org.apg.util.IterableIterator; import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPPublicKeyRing; import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKeyRing; -import org.thialfihar.android.apg.Apg; -import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.utils.IterableIterator; import android.content.ContentValues; import android.content.Context; diff --git a/src/org/thialfihar/android/apg/provider/KeyRings.java b/src/org/apg/provider/KeyRings.java similarity index 96% rename from src/org/thialfihar/android/apg/provider/KeyRings.java rename to src/org/apg/provider/KeyRings.java index 58e95eba6..304afd24f 100644 --- a/src/org/thialfihar/android/apg/provider/KeyRings.java +++ b/src/org/apg/provider/KeyRings.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.thialfihar.android.apg.provider; +package org.apg.provider; import android.provider.BaseColumns; diff --git a/src/org/thialfihar/android/apg/provider/Keys.java b/src/org/apg/provider/Keys.java similarity index 98% rename from src/org/thialfihar/android/apg/provider/Keys.java rename to src/org/apg/provider/Keys.java index 618c5e920..63eaee54f 100644 --- a/src/org/thialfihar/android/apg/provider/Keys.java +++ b/src/org/apg/provider/Keys.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.thialfihar.android.apg.provider; +package org.apg.provider; import android.provider.BaseColumns; diff --git a/src/org/thialfihar/android/apg/provider/UserIds.java b/src/org/apg/provider/UserIds.java similarity index 96% rename from src/org/thialfihar/android/apg/provider/UserIds.java rename to src/org/apg/provider/UserIds.java index 2050ccf9c..e8ddc677d 100644 --- a/src/org/thialfihar/android/apg/provider/UserIds.java +++ b/src/org/apg/provider/UserIds.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.thialfihar.android.apg.provider; +package org.apg.provider; import android.provider.BaseColumns; diff --git a/src/org/apg/ui/BaseActivity.java b/src/org/apg/ui/BaseActivity.java new file mode 100644 index 000000000..6e61b1412 --- /dev/null +++ b/src/org/apg/ui/BaseActivity.java @@ -0,0 +1,461 @@ +/* + * Copyright (C) 2010 Thialfihar + * + * 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.apg.ui; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Locale; + +import org.apg.Apg; +import org.apg.AskForSecretKeyPassPhrase; +import org.apg.Constants; +import org.apg.Id; +import org.apg.PausableThread; +import org.apg.Preferences; +import org.apg.ProgressDialogUpdater; +import org.apg.Service; +import org.apg.R; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.res.Configuration; +import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import android.os.Message; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +public class BaseActivity extends Activity implements Runnable, ProgressDialogUpdater, + AskForSecretKeyPassPhrase.PassPhraseCallbackInterface { + + private ProgressDialog mProgressDialog = null; + private PausableThread mRunningThread = null; + private Thread mDeletingThread = null; + + private long mSecretKeyId = 0; + private String mDeleteFile = null; + + protected Preferences mPreferences; + + private Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + handlerCallback(msg); + } + }; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mPreferences = Preferences.getPreferences(this); + setLanguage(this, mPreferences.getLanguage()); + + Apg.initialize(this); + + 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 + } + } + + startCacheService(this, mPreferences); + } + + public static void startCacheService(Activity activity, Preferences preferences) { + Intent intent = new Intent(activity, Service.class); + intent.putExtra(Service.EXTRA_TTL, preferences.getPassPhraseCacheTtl()); + activity.startService(intent); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + menu.add(0, Id.menu.option.preferences, 0, R.string.menu_preferences).setIcon( + android.R.drawable.ic_menu_preferences); + menu.add(0, Id.menu.option.about, 1, R.string.menu_about).setIcon( + android.R.drawable.ic_menu_info_details); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case Id.menu.option.about: { + showDialog(Id.dialog.about); + return true; + } + + case Id.menu.option.preferences: { + startActivity(new Intent(this, PreferencesActivity.class)); + return true; + } + + case Id.menu.option.search: { + startSearch("", false, null, false); + return true; + } + + default: { + break; + } + } + return false; + } + + @Override + protected Dialog onCreateDialog(int id) { + // in case it is a progress dialog + mProgressDialog = new ProgressDialog(this); + mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + mProgressDialog.setCancelable(false); + switch (id) { + case Id.dialog.encrypting: { + mProgressDialog.setMessage(this.getString(R.string.progress_initializing)); + return mProgressDialog; + } + + case Id.dialog.decrypting: { + mProgressDialog.setMessage(this.getString(R.string.progress_initializing)); + return mProgressDialog; + } + + case Id.dialog.saving: { + mProgressDialog.setMessage(this.getString(R.string.progress_saving)); + return mProgressDialog; + } + + case Id.dialog.importing: { + mProgressDialog.setMessage(this.getString(R.string.progress_importing)); + return mProgressDialog; + } + + case Id.dialog.exporting: { + mProgressDialog.setMessage(this.getString(R.string.progress_exporting)); + return mProgressDialog; + } + + case Id.dialog.deleting: { + mProgressDialog.setMessage(this.getString(R.string.progress_initializing)); + return mProgressDialog; + } + + case Id.dialog.querying: { + mProgressDialog.setMessage(this.getString(R.string.progress_querying)); + mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); + mProgressDialog.setCancelable(false); + return mProgressDialog; + } + + case Id.dialog.signing: { + mProgressDialog.setMessage(this.getString(R.string.progress_signing)); + mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); + mProgressDialog.setCancelable(false); + return mProgressDialog; + } + + default: { + break; + } + } + mProgressDialog = null; + + switch (id) { + case Id.dialog.about: { + AlertDialog.Builder alert = new AlertDialog.Builder(this); + + alert.setTitle("About " + Apg.getFullVersion(this)); + + LayoutInflater inflater = (LayoutInflater) this + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View layout = inflater.inflate(R.layout.info, null); + TextView message = (TextView) layout.findViewById(R.id.message); + message.setText("This is an attempt to bring OpenPGP to Android. " + + "It is far from complete, but more features are planned (see website).\n\n" + + "Feel free to send bug reports, suggestions, feature requests, feedback, " + + "photographs.\n\n" + "mail: thi@thialfihar.org\n" + + "site: http://apg.thialfihar.org\n\n" + + "This software is provided \"as is\", without warranty of any kind."); + alert.setView(layout); + + alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + BaseActivity.this.removeDialog(Id.dialog.about); + } + }); + + return alert.create(); + } + + case Id.dialog.pass_phrase: { + return AskForSecretKeyPassPhrase.createDialog(this, getSecretKeyId(), this); + } + + case Id.dialog.pass_phrases_do_not_match: { + AlertDialog.Builder alert = new AlertDialog.Builder(this); + + alert.setIcon(android.R.drawable.ic_dialog_alert); + alert.setTitle(R.string.error); + alert.setMessage(R.string.passPhrasesDoNotMatch); + + alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + removeDialog(Id.dialog.pass_phrases_do_not_match); + } + }); + alert.setCancelable(false); + + return alert.create(); + } + + case Id.dialog.no_pass_phrase: { + AlertDialog.Builder alert = new AlertDialog.Builder(this); + + alert.setIcon(android.R.drawable.ic_dialog_alert); + alert.setTitle(R.string.error); + alert.setMessage(R.string.passPhraseMustNotBeEmpty); + + alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + removeDialog(Id.dialog.no_pass_phrase); + } + }); + alert.setCancelable(false); + + return alert.create(); + } + + case Id.dialog.delete_file: { + AlertDialog.Builder alert = new AlertDialog.Builder(this); + + alert.setIcon(android.R.drawable.ic_dialog_alert); + alert.setTitle(R.string.warning); + alert.setMessage(this.getString(R.string.fileDeleteConfirmation, getDeleteFile())); + + alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + removeDialog(Id.dialog.delete_file); + final File file = new File(getDeleteFile()); + showDialog(Id.dialog.deleting); + mDeletingThread = new Thread(new Runnable() { + public void run() { + Bundle data = new Bundle(); + data.putInt(Constants.extras.status, Id.message.delete_done); + try { + Apg.deleteFileSecurely(BaseActivity.this, file, BaseActivity.this); + } catch (FileNotFoundException e) { + data.putString(Apg.EXTRA_ERROR, BaseActivity.this.getString( + R.string.error_fileNotFound, file)); + } catch (IOException e) { + data.putString(Apg.EXTRA_ERROR, BaseActivity.this.getString( + R.string.error_fileDeleteFailed, file)); + } + Message msg = new Message(); + msg.setData(data); + sendMessage(msg); + } + }); + mDeletingThread.start(); + } + }); + alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + removeDialog(Id.dialog.delete_file); + } + }); + alert.setCancelable(true); + + return alert.create(); + } + + default: { + break; + } + } + + return super.onCreateDialog(id); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case Id.request.secret_keys: { + if (resultCode == RESULT_OK) { + Bundle bundle = data.getExtras(); + setSecretKeyId(bundle.getLong(Apg.EXTRA_KEY_ID)); + } else { + setSecretKeyId(Id.key.none); + } + break; + } + + default: { + break; + } + } + + super.onActivityResult(requestCode, resultCode, data); + } + + public void setProgress(int resourceId, int progress, int max) { + setProgress(getString(resourceId), progress, max); + } + + public void setProgress(int progress, int max) { + Message msg = new Message(); + Bundle data = new Bundle(); + data.putInt(Constants.extras.status, Id.message.progress_update); + data.putInt(Constants.extras.progress, progress); + data.putInt(Constants.extras.progress_max, max); + msg.setData(data); + mHandler.sendMessage(msg); + } + + public void setProgress(String message, int progress, int max) { + Message msg = new Message(); + Bundle data = new Bundle(); + data.putInt(Constants.extras.status, Id.message.progress_update); + data.putString(Constants.extras.message, message); + data.putInt(Constants.extras.progress, progress); + data.putInt(Constants.extras.progress_max, max); + msg.setData(data); + mHandler.sendMessage(msg); + } + + public void handlerCallback(Message msg) { + Bundle data = msg.getData(); + if (data == null) { + return; + } + + int type = data.getInt(Constants.extras.status); + switch (type) { + case Id.message.progress_update: { + String message = data.getString(Constants.extras.message); + if (mProgressDialog != null) { + if (message != null) { + mProgressDialog.setMessage(message); + } + mProgressDialog.setMax(data.getInt(Constants.extras.progress_max)); + mProgressDialog.setProgress(data.getInt(Constants.extras.progress)); + } + break; + } + + case Id.message.delete_done: { + mProgressDialog = null; + deleteDoneCallback(msg); + break; + } + + case Id.message.import_done: // intentionally no break + case Id.message.export_done: // intentionally no break + case Id.message.query_done: // intentionally no break + case Id.message.done: { + mProgressDialog = null; + doneCallback(msg); + break; + } + + default: { + break; + } + } + } + + public void doneCallback(Message msg) { + + } + + public void deleteDoneCallback(Message msg) { + removeDialog(Id.dialog.deleting); + mDeletingThread = null; + + Bundle data = msg.getData(); + String error = data.getString(Apg.EXTRA_ERROR); + String message; + if (error != null) { + message = getString(R.string.errorMessage, error); + } else { + message = getString(R.string.fileDeleteSuccessful); + } + + Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); + } + + public void passPhraseCallback(long keyId, String passPhrase) { + Apg.setCachedPassPhrase(keyId, passPhrase); + } + + public void sendMessage(Message msg) { + mHandler.sendMessage(msg); + } + + public PausableThread getRunningThread() { + return mRunningThread; + } + + public void startThread() { + mRunningThread = new PausableThread(this); + mRunningThread.start(); + } + + public void run() { + + } + + public void setSecretKeyId(long id) { + mSecretKeyId = id; + } + + public long getSecretKeyId() { + return mSecretKeyId; + } + + protected void setDeleteFile(String deleteFile) { + mDeleteFile = deleteFile; + } + + protected String getDeleteFile() { + return mDeleteFile; + } + + public static void setLanguage(Context context, String language) { + Locale locale; + if (language == null || language.equals("")) { + locale = Locale.getDefault(); + } else { + locale = new Locale(language); + } + Configuration config = new Configuration(); + config.locale = locale; + context.getResources().updateConfiguration(config, + context.getResources().getDisplayMetrics()); + } +} diff --git a/src/org/thialfihar/android/apg/DecryptActivity.java b/src/org/apg/ui/DecryptActivity.java similarity index 98% rename from src/org/thialfihar/android/apg/DecryptActivity.java rename to src/org/apg/ui/DecryptActivity.java index cd4ef00f6..48884cbfc 100644 --- a/src/org/thialfihar/android/apg/DecryptActivity.java +++ b/src/org/apg/ui/DecryptActivity.java @@ -14,13 +14,22 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg.ui; +import org.apg.Apg; +import org.apg.Constants; +import org.apg.DataDestination; +import org.apg.DataSource; +import org.apg.FileDialog; +import org.apg.Id; +import org.apg.InputData; +import org.apg.PausableThread; +import org.apg.provider.DataProvider; +import org.apg.util.Compatibility; import org.spongycastle.jce.provider.BouncyCastleProvider; import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPPublicKeyRing; -import org.thialfihar.android.apg.provider.DataProvider; -import org.thialfihar.android.apg.utils.Compatibility; +import org.apg.R; import android.app.AlertDialog; import android.app.Dialog; diff --git a/src/org/thialfihar/android/apg/EditKeyActivity.java b/src/org/apg/ui/EditKeyActivity.java similarity index 64% rename from src/org/thialfihar/android/apg/EditKeyActivity.java rename to src/org/apg/ui/EditKeyActivity.java index 17049b2dc..6e1eab63e 100644 --- a/src/org/thialfihar/android/apg/EditKeyActivity.java +++ b/src/org/apg/ui/EditKeyActivity.java @@ -14,15 +14,19 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg.ui; +import org.apg.Apg; +import org.apg.Constants; +import org.apg.Id; +import org.apg.provider.Database; +import org.apg.ui.widget.KeyEditor; +import org.apg.ui.widget.SectionView; +import org.apg.util.IterableIterator; import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKeyRing; -import org.thialfihar.android.apg.provider.Database; -import org.thialfihar.android.apg.ui.widget.KeyEditor; -import org.thialfihar.android.apg.ui.widget.SectionView; -import org.thialfihar.android.apg.utils.IterableIterator; +import org.apg.R; import android.app.AlertDialog; import android.app.Dialog; @@ -104,8 +108,7 @@ public class EditKeyActivity extends BaseActivity implements OnClickListener { mSaveButton.setOnClickListener(this); mDiscardButton.setOnClickListener(this); - LayoutInflater inflater = - (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); + LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); LinearLayout container = (LinearLayout) findViewById(R.id.container); mUserIds = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false); @@ -124,8 +127,9 @@ public class EditKeyActivity extends BaseActivity implements OnClickListener { updatePassPhraseButtonText(); - Toast.makeText(this, getString(R.string.warningMessage, getString(R.string.keyEditingIsBeta)), - Toast.LENGTH_LONG).show(); + Toast.makeText(this, + getString(R.string.warningMessage, getString(R.string.keyEditingIsBeta)), + Toast.LENGTH_LONG).show(); } private long getMasterKeyId() { @@ -136,75 +140,72 @@ public class EditKeyActivity extends BaseActivity implements OnClickListener { } public boolean havePassPhrase() { - return (!mCurrentPassPhrase.equals("")) || - (mNewPassPhrase != null && !mNewPassPhrase.equals("")); + return (!mCurrentPassPhrase.equals("")) + || (mNewPassPhrase != null && !mNewPassPhrase.equals("")); } @Override public boolean onCreateOptionsMenu(Menu menu) { - menu.add(0, Id.menu.option.preferences, 0, R.string.menu_preferences) - .setIcon(android.R.drawable.ic_menu_preferences); - menu.add(0, Id.menu.option.about, 1, R.string.menu_about) - .setIcon(android.R.drawable.ic_menu_info_details); + menu.add(0, Id.menu.option.preferences, 0, R.string.menu_preferences).setIcon( + android.R.drawable.ic_menu_preferences); + menu.add(0, Id.menu.option.about, 1, R.string.menu_about).setIcon( + android.R.drawable.ic_menu_info_details); return true; } @Override protected Dialog onCreateDialog(int id) { switch (id) { - case Id.dialog.new_pass_phrase: { - AlertDialog.Builder alert = new AlertDialog.Builder(this); + case Id.dialog.new_pass_phrase: { + AlertDialog.Builder alert = new AlertDialog.Builder(this); - if (havePassPhrase()) { - alert.setTitle(R.string.title_changePassPhrase); - } else { - alert.setTitle(R.string.title_setPassPhrase); + if (havePassPhrase()) { + alert.setTitle(R.string.title_changePassPhrase); + } else { + alert.setTitle(R.string.title_setPassPhrase); + } + alert.setMessage(R.string.enterPassPhraseTwice); + + LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View view = inflater.inflate(R.layout.pass_phrase, null); + final EditText input1 = (EditText) view.findViewById(R.id.passPhrase); + final EditText input2 = (EditText) view.findViewById(R.id.passPhraseAgain); + + alert.setView(view); + + alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + removeDialog(Id.dialog.new_pass_phrase); + + String passPhrase1 = "" + input1.getText(); + String passPhrase2 = "" + input2.getText(); + if (!passPhrase1.equals(passPhrase2)) { + showDialog(Id.dialog.pass_phrases_do_not_match); + return; + } + + if (passPhrase1.equals("")) { + showDialog(Id.dialog.no_pass_phrase); + return; + } + + mNewPassPhrase = passPhrase1; + updatePassPhraseButtonText(); } - alert.setMessage(R.string.enterPassPhraseTwice); + }); - LayoutInflater inflater = - (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); - View view = inflater.inflate(R.layout.pass_phrase, null); - final EditText input1 = (EditText) view.findViewById(R.id.passPhrase); - final EditText input2 = (EditText) view.findViewById(R.id.passPhraseAgain); + alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + removeDialog(Id.dialog.new_pass_phrase); + } + }); - alert.setView(view); + return alert.create(); + } - alert.setPositiveButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - removeDialog(Id.dialog.new_pass_phrase); - - String passPhrase1 = "" + input1.getText(); - String passPhrase2 = "" + input2.getText(); - if (!passPhrase1.equals(passPhrase2)) { - showDialog(Id.dialog.pass_phrases_do_not_match); - return; - } - - if (passPhrase1.equals("")) { - showDialog(Id.dialog.no_pass_phrase); - return; - } - - mNewPassPhrase = passPhrase1; - updatePassPhraseButtonText(); - } - }); - - alert.setNegativeButton(android.R.string.cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - removeDialog(Id.dialog.new_pass_phrase); - } - }); - - return alert.create(); - } - - default: { - return super.onCreateDialog(id); - } + default: { + return super.onCreateDialog(id); + } } } @@ -275,8 +276,8 @@ public class EditKeyActivity extends BaseActivity implements OnClickListener { String error = data.getString(Apg.EXTRA_ERROR); if (error != null) { - Toast.makeText(EditKeyActivity.this, - getString(R.string.errorMessage, error), Toast.LENGTH_SHORT).show(); + Toast.makeText(EditKeyActivity.this, getString(R.string.errorMessage, error), + Toast.LENGTH_SHORT).show(); } else { Toast.makeText(EditKeyActivity.this, R.string.keySaved, Toast.LENGTH_SHORT).show(); setResult(RESULT_OK); @@ -285,7 +286,7 @@ public class EditKeyActivity extends BaseActivity implements OnClickListener { } private void updatePassPhraseButtonText() { - mChangePassPhrase.setText( - havePassPhrase() ? R.string.btn_changePassPhrase : R.string.btn_setPassPhrase); + mChangePassPhrase.setText(havePassPhrase() ? R.string.btn_changePassPhrase + : R.string.btn_setPassPhrase); } } diff --git a/src/org/thialfihar/android/apg/EncryptActivity.java b/src/org/apg/ui/EncryptActivity.java similarity index 69% rename from src/org/thialfihar/android/apg/EncryptActivity.java rename to src/org/apg/ui/EncryptActivity.java index 1ac98dfd3..603d1a04d 100644 --- a/src/org/thialfihar/android/apg/EncryptActivity.java +++ b/src/org/apg/ui/EncryptActivity.java @@ -14,16 +14,24 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg.ui; +import org.apg.Apg; +import org.apg.Constants; +import org.apg.DataDestination; +import org.apg.DataSource; +import org.apg.FileDialog; +import org.apg.Id; +import org.apg.InputData; +import org.apg.provider.DataProvider; +import org.apg.util.Choice; +import org.apg.util.Compatibility; import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPPublicKeyRing; import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKeyRing; -import org.thialfihar.android.apg.provider.DataProvider; -import org.thialfihar.android.apg.utils.Choice; -import org.thialfihar.android.apg.utils.Compatibility; +import org.apg.R; import android.app.Dialog; import android.content.ActivityNotFoundException; @@ -121,9 +129,9 @@ public class EncryptActivity extends BaseActivity { mSourcePrevious.setOnClickListener(new OnClickListener() { public void onClick(View v) { mSource.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_right_in)); + R.anim.push_right_in)); mSource.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_right_out)); + R.anim.push_right_out)); mSource.showPrevious(); updateSource(); } @@ -133,9 +141,9 @@ public class EncryptActivity extends BaseActivity { OnClickListener nextSourceClickListener = new OnClickListener() { public void onClick(View v) { mSource.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_left_in)); + R.anim.push_left_in)); mSource.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_left_out)); + R.anim.push_left_out)); mSource.showNext(); updateSource(); } @@ -154,9 +162,9 @@ public class EncryptActivity extends BaseActivity { mModePrevious.setOnClickListener(new OnClickListener() { public void onClick(View v) { mMode.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_right_in)); + R.anim.push_right_in)); mMode.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_right_out)); + R.anim.push_right_out)); mMode.showPrevious(); updateMode(); } @@ -165,9 +173,9 @@ public class EncryptActivity extends BaseActivity { OnClickListener nextModeClickListener = new OnClickListener() { public void onClick(View v) { mMode.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_left_in)); + R.anim.push_left_in)); mMode.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_left_out)); + R.anim.push_left_out)); mMode.showNext(); updateMode(); } @@ -205,14 +213,14 @@ public class EncryptActivity extends BaseActivity { mFileCompression = (Spinner) findViewById(R.id.fileCompression); Choice[] choices = new Choice[] { - new Choice(Id.choice.compression.none, getString(R.string.choice_none) + - " (" + getString(R.string.fast) + ")"), + new Choice(Id.choice.compression.none, getString(R.string.choice_none) + " (" + + getString(R.string.fast) + ")"), new Choice(Id.choice.compression.zip, "ZIP (" + getString(R.string.fast) + ")"), new Choice(Id.choice.compression.zlib, "ZLIB (" + getString(R.string.fast) + ")"), - new Choice(Id.choice.compression.bzip2, "BZIP2 (" + getString(R.string.very_slow) + ")"), - }; - ArrayAdapter adapter = - new ArrayAdapter(this, android.R.layout.simple_spinner_item, choices); + new Choice(Id.choice.compression.bzip2, "BZIP2 (" + getString(R.string.very_slow) + + ")"), }; + ArrayAdapter adapter = new ArrayAdapter(this, + android.R.layout.simple_spinner_item, choices); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mFileCompression.setAdapter(adapter); @@ -265,18 +273,18 @@ public class EncryptActivity extends BaseActivity { }); mIntent = getIntent(); - if (Apg.Intent.ENCRYPT.equals(mIntent.getAction()) || - Apg.Intent.ENCRYPT_FILE.equals(mIntent.getAction()) || - Apg.Intent.ENCRYPT_AND_RETURN.equals(mIntent.getAction()) || - Apg.Intent.GENERATE_SIGNATURE.equals(mIntent.getAction())) { + if (Apg.Intent.ENCRYPT.equals(mIntent.getAction()) + || Apg.Intent.ENCRYPT_FILE.equals(mIntent.getAction()) + || Apg.Intent.ENCRYPT_AND_RETURN.equals(mIntent.getAction()) + || Apg.Intent.GENERATE_SIGNATURE.equals(mIntent.getAction())) { mContentUri = mIntent.getData(); Bundle extras = mIntent.getExtras(); if (extras == null) { extras = new Bundle(); } - if (Apg.Intent.ENCRYPT_AND_RETURN.equals(mIntent.getAction()) || - Apg.Intent.GENERATE_SIGNATURE.equals(mIntent.getAction())) { + if (Apg.Intent.ENCRYPT_AND_RETURN.equals(mIntent.getAction()) + || Apg.Intent.GENERATE_SIGNATURE.equals(mIntent.getAction())) { mReturnResult = true; } @@ -341,9 +349,9 @@ public class EncryptActivity extends BaseActivity { } } - if (Apg.Intent.ENCRYPT.equals(mIntent.getAction()) || - Apg.Intent.ENCRYPT_AND_RETURN.equals(mIntent.getAction()) || - Apg.Intent.GENERATE_SIGNATURE.equals(mIntent.getAction())) { + if (Apg.Intent.ENCRYPT.equals(mIntent.getAction()) + || Apg.Intent.ENCRYPT_AND_RETURN.equals(mIntent.getAction()) + || Apg.Intent.GENERATE_SIGNATURE.equals(mIntent.getAction())) { if (textData != null) { mMessage.setText(textData); } @@ -385,11 +393,9 @@ public class EncryptActivity extends BaseActivity { updateButtons(); - if (mReturnResult && - (mMessage.getText().length() > 0 || mData != null || mContentUri != null) && - ((mEncryptionKeyIds != null && - mEncryptionKeyIds.length > 0) || - getSecretKeyId() != 0)) { + if (mReturnResult + && (mMessage.getText().length() > 0 || mData != null || mContentUri != null) + && ((mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0) || getSecretKeyId() != 0)) { encryptClicked(); } } @@ -420,39 +426,69 @@ public class EncryptActivity extends BaseActivity { private void updateSource() { switch (mSource.getCurrentView().getId()) { - case R.id.sourceFile: { - mSourceLabel.setText(R.string.label_file); - break; - } + case R.id.sourceFile: { + mSourceLabel.setText(R.string.label_file); + break; + } - case R.id.sourceMessage: { - mSourceLabel.setText(R.string.label_message); - break; - } + case R.id.sourceMessage: { + mSourceLabel.setText(R.string.label_message); + break; + } - default: { - break; - } + default: { + break; + } } updateButtons(); } private void updateButtons() { switch (mSource.getCurrentView().getId()) { - case R.id.sourceFile: { - mEncryptToClipboardButton.setVisibility(View.INVISIBLE); - mEncryptButton.setText(R.string.btn_encrypt); - break; - } + case R.id.sourceFile: { + mEncryptToClipboardButton.setVisibility(View.INVISIBLE); + mEncryptButton.setText(R.string.btn_encrypt); + break; + } - case R.id.sourceMessage: { - mSourceLabel.setText(R.string.label_message); + case R.id.sourceMessage: { + mSourceLabel.setText(R.string.label_message); + if (mReturnResult) { + mEncryptToClipboardButton.setVisibility(View.INVISIBLE); + } else { + mEncryptToClipboardButton.setVisibility(View.VISIBLE); + } + if (mMode.getCurrentView().getId() == R.id.modeSymmetric) { if (mReturnResult) { - mEncryptToClipboardButton.setVisibility(View.INVISIBLE); + mEncryptButton.setText(R.string.btn_encrypt); } else { - mEncryptToClipboardButton.setVisibility(View.VISIBLE); + mEncryptButton.setText(R.string.btn_encryptAndEmail); } - if (mMode.getCurrentView().getId() == R.id.modeSymmetric) { + mEncryptButton.setEnabled(true); + mEncryptToClipboardButton.setText(R.string.btn_encryptToClipboard); + mEncryptToClipboardButton.setEnabled(true); + } else { + if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) { + if (getSecretKeyId() == 0) { + if (mReturnResult) { + mEncryptButton.setText(R.string.btn_encrypt); + } else { + mEncryptButton.setText(R.string.btn_encryptAndEmail); + } + mEncryptButton.setEnabled(false); + mEncryptToClipboardButton.setText(R.string.btn_encryptToClipboard); + mEncryptToClipboardButton.setEnabled(false); + } else { + if (mReturnResult) { + mEncryptButton.setText(R.string.btn_sign); + } else { + mEncryptButton.setText(R.string.btn_signAndEmail); + } + mEncryptButton.setEnabled(true); + mEncryptToClipboardButton.setText(R.string.btn_signToClipboard); + mEncryptToClipboardButton.setEnabled(true); + } + } else { if (mReturnResult) { mEncryptButton.setText(R.string.btn_encrypt); } else { @@ -461,62 +497,32 @@ public class EncryptActivity extends BaseActivity { mEncryptButton.setEnabled(true); mEncryptToClipboardButton.setText(R.string.btn_encryptToClipboard); mEncryptToClipboardButton.setEnabled(true); - } else { - if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) { - if (getSecretKeyId() == 0) { - if (mReturnResult) { - mEncryptButton.setText(R.string.btn_encrypt); - } else { - mEncryptButton.setText(R.string.btn_encryptAndEmail); - } - mEncryptButton.setEnabled(false); - mEncryptToClipboardButton.setText(R.string.btn_encryptToClipboard); - mEncryptToClipboardButton.setEnabled(false); - } else { - if (mReturnResult) { - mEncryptButton.setText(R.string.btn_sign); - } else { - mEncryptButton.setText(R.string.btn_signAndEmail); - } - mEncryptButton.setEnabled(true); - mEncryptToClipboardButton.setText(R.string.btn_signToClipboard); - mEncryptToClipboardButton.setEnabled(true); - } - } else { - if (mReturnResult) { - mEncryptButton.setText(R.string.btn_encrypt); - } else { - mEncryptButton.setText(R.string.btn_encryptAndEmail); - } - mEncryptButton.setEnabled(true); - mEncryptToClipboardButton.setText(R.string.btn_encryptToClipboard); - mEncryptToClipboardButton.setEnabled(true); - } } - break; } + break; + } - default: { - break; - } + default: { + break; + } } } private void updateMode() { switch (mMode.getCurrentView().getId()) { - case R.id.modeAsymmetric: { - mModeLabel.setText(R.string.label_asymmetric); - break; - } + case R.id.modeAsymmetric: { + mModeLabel.setText(R.string.label_asymmetric); + break; + } - case R.id.modeSymmetric: { - mModeLabel.setText(R.string.label_symmetric); - break; - } + case R.id.modeSymmetric: { + mModeLabel.setText(R.string.label_symmetric); + break; + } - default: { - break; - } + default: { + break; + } } updateButtons(); } @@ -550,9 +556,10 @@ public class EncryptActivity extends BaseActivity { if (!mInputFilename.startsWith("content")) { File file = new File(mInputFilename); if (!file.exists() || !file.isFile()) { - Toast.makeText(this, getString(R.string.errorMessage, - getString(R.string.error_fileNotFound)), - Toast.LENGTH_SHORT).show(); + Toast.makeText( + this, + getString(R.string.errorMessage, getString(R.string.error_fileNotFound)), + Toast.LENGTH_SHORT).show(); return; } } @@ -582,8 +589,8 @@ public class EncryptActivity extends BaseActivity { } if (!encryptIt && getSecretKeyId() == 0) { - Toast.makeText(this, R.string.selectEncryptionOrSignatureKey, - Toast.LENGTH_SHORT).show(); + Toast.makeText(this, R.string.selectEncryptionOrSignatureKey, Toast.LENGTH_SHORT) + .show(); return; } @@ -666,55 +673,49 @@ public class EncryptActivity extends BaseActivity { } if (mGenerateSignature) { - Apg.generateSignature(this, in, out, useAsciiArmour, mDataSource.isBinary(), - getSecretKeyId(), - Apg.getCachedPassPhrase(getSecretKeyId()), - mPreferences.getDefaultHashAlgorithm(), - mPreferences.getForceV3Signatures(), - this); + Apg.generateSignature(this, in, out, useAsciiArmour, mDataSource.isBinary(), + getSecretKeyId(), Apg.getCachedPassPhrase(getSecretKeyId()), + mPreferences.getDefaultHashAlgorithm(), + mPreferences.getForceV3Signatures(), this); } else if (signOnly) { Apg.signText(this, in, out, getSecretKeyId(), - Apg.getCachedPassPhrase(getSecretKeyId()), - mPreferences.getDefaultHashAlgorithm(), - mPreferences.getForceV3Signatures(), - this); + Apg.getCachedPassPhrase(getSecretKeyId()), + mPreferences.getDefaultHashAlgorithm(), + mPreferences.getForceV3Signatures(), this); } else { - Apg.encrypt(this, in, out, useAsciiArmour, - encryptionKeyIds, signatureKeyId, - Apg.getCachedPassPhrase(signatureKeyId), this, - mPreferences.getDefaultEncryptionAlgorithm(), - mPreferences.getDefaultHashAlgorithm(), - compressionId, - mPreferences.getForceV3Signatures(), - passPhrase); + Apg.encrypt(this, in, out, useAsciiArmour, encryptionKeyIds, signatureKeyId, + Apg.getCachedPassPhrase(signatureKeyId), this, + mPreferences.getDefaultEncryptionAlgorithm(), + mPreferences.getDefaultHashAlgorithm(), compressionId, + mPreferences.getForceV3Signatures(), passPhrase); } out.close(); if (mEncryptTarget != Id.target.file) { - - if(out instanceof ByteArrayOutputStream) { - if (useAsciiArmour) { - String extraData = new String(((ByteArrayOutputStream)out).toByteArray()); - if (mGenerateSignature) { - data.putString(Apg.EXTRA_SIGNATURE_TEXT, extraData); - } else { - data.putString(Apg.EXTRA_ENCRYPTED_MESSAGE, extraData); - } - } else { - byte extraData[] = ((ByteArrayOutputStream)out).toByteArray(); - if (mGenerateSignature) { - data.putByteArray(Apg.EXTRA_SIGNATURE_DATA, extraData); - } else { - data.putByteArray(Apg.EXTRA_ENCRYPTED_DATA, extraData); - } - } - } else if(out instanceof FileOutputStream) { - String fileName = mDataDestination.getStreamFilename(); - String uri = "content://" + DataProvider.AUTHORITY + "/data/" + fileName; - data.putString(Apg.EXTRA_RESULT_URI, uri); - } else { - throw new Apg.GeneralException("No output-data found."); - } + + if (out instanceof ByteArrayOutputStream) { + if (useAsciiArmour) { + String extraData = new String(((ByteArrayOutputStream) out).toByteArray()); + if (mGenerateSignature) { + data.putString(Apg.EXTRA_SIGNATURE_TEXT, extraData); + } else { + data.putString(Apg.EXTRA_ENCRYPTED_MESSAGE, extraData); + } + } else { + byte extraData[] = ((ByteArrayOutputStream) out).toByteArray(); + if (mGenerateSignature) { + data.putByteArray(Apg.EXTRA_SIGNATURE_DATA, extraData); + } else { + data.putByteArray(Apg.EXTRA_ENCRYPTED_DATA, extraData); + } + } + } else if (out instanceof FileOutputStream) { + String fileName = mDataDestination.getStreamFilename(); + String uri = "content://" + DataProvider.AUTHORITY + "/data/" + fileName; + data.putString(Apg.EXTRA_RESULT_URI, uri); + } else { + throw new Apg.GeneralException("No output-data found."); + } } } catch (IOException e) { error = "" + e; @@ -746,8 +747,8 @@ public class EncryptActivity extends BaseActivity { } else if (mEncryptionKeyIds.length == 1) { mSelectKeysButton.setText(R.string.oneKeySelected); } else { - mSelectKeysButton.setText("" + mEncryptionKeyIds.length + " " + - getResources().getString(R.string.nKeysSelected)); + mSelectKeysButton.setText("" + mEncryptionKeyIds.length + " " + + getResources().getString(R.string.nKeysSelected)); } if (getSecretKeyId() == 0) { @@ -788,7 +789,7 @@ public class EncryptActivity extends BaseActivity { keyIds.add(mEncryptionKeyIds[i]); } } - long [] initialKeyIds = null; + long[] initialKeyIds = null; if (keyIds.size() > 0) { initialKeyIds = new long[keyIds.size()]; for (int i = 0; i < keyIds.size(); ++i) { @@ -807,60 +808,60 @@ public class EncryptActivity extends BaseActivity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { - case Id.request.filename: { - if (resultCode == RESULT_OK && data != null) { - String filename = data.getDataString(); - if (filename != null) { - // Get rid of URI prefix: - if (filename.startsWith("file://")) { - filename = filename.substring(7); - } - // replace %20 and so on - filename = Uri.decode(filename); - - mFilename.setText(filename); + case Id.request.filename: { + if (resultCode == RESULT_OK && data != null) { + String filename = data.getDataString(); + if (filename != null) { + // Get rid of URI prefix: + if (filename.startsWith("file://")) { + filename = filename.substring(7); } + // replace %20 and so on + filename = Uri.decode(filename); + + mFilename.setText(filename); } - return; } + return; + } - case Id.request.output_filename: { - if (resultCode == RESULT_OK && data != null) { - String filename = data.getDataString(); - if (filename != null) { - // Get rid of URI prefix: - if (filename.startsWith("file://")) { - filename = filename.substring(7); - } - // replace %20 and so on - filename = Uri.decode(filename); - - FileDialog.setFilename(filename); + case Id.request.output_filename: { + if (resultCode == RESULT_OK && data != null) { + String filename = data.getDataString(); + if (filename != null) { + // Get rid of URI prefix: + if (filename.startsWith("file://")) { + filename = filename.substring(7); } - } - return; - } + // replace %20 and so on + filename = Uri.decode(filename); - case Id.request.secret_keys: { - if (resultCode == RESULT_OK) { - super.onActivityResult(requestCode, resultCode, data); + FileDialog.setFilename(filename); } - updateView(); - break; } + return; + } - case Id.request.public_keys: { - if (resultCode == RESULT_OK) { - Bundle bundle = data.getExtras(); - mEncryptionKeyIds = bundle.getLongArray(Apg.EXTRA_SELECTION); - } - updateView(); - break; + case Id.request.secret_keys: { + if (resultCode == RESULT_OK) { + super.onActivityResult(requestCode, resultCode, data); } + updateView(); + break; + } - default: { - break; + case Id.request.public_keys: { + if (resultCode == RESULT_OK) { + Bundle bundle = data.getExtras(); + mEncryptionKeyIds = bundle.getLongArray(Apg.EXTRA_SELECTION); } + updateView(); + break; + } + + default: { + break; + } } super.onActivityResult(requestCode, resultCode, data); @@ -875,88 +876,82 @@ public class EncryptActivity extends BaseActivity { Bundle data = msg.getData(); String error = data.getString(Apg.EXTRA_ERROR); if (error != null) { - Toast.makeText(this, getString(R.string.errorMessage, error), Toast.LENGTH_SHORT).show(); + Toast.makeText(this, getString(R.string.errorMessage, error), Toast.LENGTH_SHORT) + .show(); return; } switch (mEncryptTarget) { - case Id.target.clipboard: { - String message = data.getString(Apg.EXTRA_ENCRYPTED_MESSAGE); - Compatibility.copyToClipboard(this, message); - Toast.makeText(this, R.string.encryptionToClipboardSuccessful, - Toast.LENGTH_SHORT).show(); - break; + case Id.target.clipboard: { + String message = data.getString(Apg.EXTRA_ENCRYPTED_MESSAGE); + Compatibility.copyToClipboard(this, message); + Toast.makeText(this, R.string.encryptionToClipboardSuccessful, Toast.LENGTH_SHORT) + .show(); + break; + } + + case Id.target.email: { + if (mReturnResult) { + Intent intent = new Intent(); + intent.putExtras(data); + setResult(RESULT_OK, intent); + finish(); + return; } - case Id.target.email: { - if (mReturnResult) { - Intent intent = new Intent(); - intent.putExtras(data); - setResult(RESULT_OK, intent); - finish(); - return; - } - - String message = data.getString(Apg.EXTRA_ENCRYPTED_MESSAGE); - Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); - emailIntent.setType("text/plain; charset=utf-8"); - emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, message); - if (mSubject != null) { - emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, - mSubject); - } - if (mSendTo != null) { - emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, - new String[] { mSendTo }); - } - EncryptActivity.this. - startActivity(Intent.createChooser(emailIntent, - getString(R.string.title_sendEmail))); - break; + String message = data.getString(Apg.EXTRA_ENCRYPTED_MESSAGE); + Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); + emailIntent.setType("text/plain; charset=utf-8"); + emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, message); + if (mSubject != null) { + emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, mSubject); } - - case Id.target.file: { - Toast.makeText(this, R.string.encryptionSuccessful, Toast.LENGTH_SHORT).show(); - if (mDeleteAfter.isChecked()) { - setDeleteFile(mInputFilename); - showDialog(Id.dialog.delete_file); - } - break; + if (mSendTo != null) { + emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] { mSendTo }); } + EncryptActivity.this.startActivity(Intent.createChooser(emailIntent, + getString(R.string.title_sendEmail))); + break; + } - default: { - // shouldn't happen - break; + case Id.target.file: { + Toast.makeText(this, R.string.encryptionSuccessful, Toast.LENGTH_SHORT).show(); + if (mDeleteAfter.isChecked()) { + setDeleteFile(mInputFilename); + showDialog(Id.dialog.delete_file); } + break; + } + + default: { + // shouldn't happen + break; + } } } @Override protected Dialog onCreateDialog(int id) { switch (id) { - case Id.dialog.output_filename: { - return FileDialog.build(this, getString(R.string.title_encryptToFile), - getString(R.string.specifyFileToEncryptTo), - mOutputFilename, - new FileDialog.OnClickListener() { - public void onOkClick(String filename, boolean checked) { - removeDialog(Id.dialog.output_filename); - mOutputFilename = filename; - encryptStart(); - } + case Id.dialog.output_filename: { + return FileDialog.build(this, getString(R.string.title_encryptToFile), + getString(R.string.specifyFileToEncryptTo), mOutputFilename, + new FileDialog.OnClickListener() { + public void onOkClick(String filename, boolean checked) { + removeDialog(Id.dialog.output_filename); + mOutputFilename = filename; + encryptStart(); + } - public void onCancelClick() { - removeDialog(Id.dialog.output_filename); - } - }, - getString(R.string.filemanager_titleSave), - getString(R.string.filemanager_btnSave), - null, - Id.request.output_filename); - } + public void onCancelClick() { + removeDialog(Id.dialog.output_filename); + } + }, getString(R.string.filemanager_titleSave), + getString(R.string.filemanager_btnSave), null, Id.request.output_filename); + } - default: { - break; - } + default: { + break; + } } return super.onCreateDialog(id); diff --git a/src/org/thialfihar/android/apg/GeneralActivity.java b/src/org/apg/ui/GeneralActivity.java similarity index 98% rename from src/org/thialfihar/android/apg/GeneralActivity.java rename to src/org/apg/ui/GeneralActivity.java index 8f2a77e26..d70694630 100644 --- a/src/org/thialfihar/android/apg/GeneralActivity.java +++ b/src/org/apg/ui/GeneralActivity.java @@ -1,4 +1,4 @@ -package org.thialfihar.android.apg; +package org.apg.ui; import java.io.ByteArrayInputStream; import java.io.FileNotFoundException; @@ -6,7 +6,10 @@ import java.io.IOException; import java.io.InputStream; import java.util.Vector; -import org.thialfihar.android.apg.utils.Choice; +import org.apg.Apg; +import org.apg.Id; +import org.apg.util.Choice; +import org.apg.R; import android.content.Intent; import android.net.Uri; diff --git a/src/org/thialfihar/android/apg/ImportFromQRCodeActivity.java b/src/org/apg/ui/ImportFromQRCodeActivity.java similarity index 97% rename from src/org/thialfihar/android/apg/ImportFromQRCodeActivity.java rename to src/org/apg/ui/ImportFromQRCodeActivity.java index 773a5b727..0d9209991 100644 --- a/src/org/thialfihar/android/apg/ImportFromQRCodeActivity.java +++ b/src/org/apg/ui/ImportFromQRCodeActivity.java @@ -1,11 +1,16 @@ -package org.thialfihar.android.apg; +package org.apg.ui; import java.io.ByteArrayInputStream; import java.io.IOException; +import org.apg.Apg; +import org.apg.Constants; +import org.apg.HkpKeyServer; +import org.apg.Id; +import org.apg.KeyServer.QueryException; import org.spongycastle.openpgp.PGPKeyRing; import org.spongycastle.openpgp.PGPPublicKeyRing; -import org.thialfihar.android.apg.KeyServer.QueryException; +import org.apg.R; import android.content.Intent; import android.os.Bundle; diff --git a/src/org/thialfihar/android/apg/KeyListActivity.java b/src/org/apg/ui/KeyListActivity.java similarity index 99% rename from src/org/thialfihar/android/apg/KeyListActivity.java rename to src/org/apg/ui/KeyListActivity.java index cbf2f93c0..00be0321a 100644 --- a/src/org/thialfihar/android/apg/KeyListActivity.java +++ b/src/org/apg/ui/KeyListActivity.java @@ -14,14 +14,20 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg.ui; +import org.apg.Apg; +import org.apg.Constants; +import org.apg.FileDialog; +import org.apg.Id; +import org.apg.InputData; +import org.apg.provider.KeyRings; +import org.apg.provider.Keys; +import org.apg.provider.UserIds; import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPPublicKeyRing; import org.spongycastle.openpgp.PGPSecretKeyRing; -import org.thialfihar.android.apg.provider.KeyRings; -import org.thialfihar.android.apg.provider.Keys; -import org.thialfihar.android.apg.provider.UserIds; +import org.apg.R; import android.app.AlertDialog; import android.app.Dialog; diff --git a/src/org/thialfihar/android/apg/KeyServerPreferenceActivity.java b/src/org/apg/ui/KeyServerPreferenceActivity.java similarity index 94% rename from src/org/thialfihar/android/apg/KeyServerPreferenceActivity.java rename to src/org/apg/ui/KeyServerPreferenceActivity.java index 4f5a026a1..85d31779a 100644 --- a/src/org/thialfihar/android/apg/KeyServerPreferenceActivity.java +++ b/src/org/apg/ui/KeyServerPreferenceActivity.java @@ -14,13 +14,15 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg.ui; import java.util.Vector; -import org.thialfihar.android.apg.ui.widget.Editor; -import org.thialfihar.android.apg.ui.widget.Editor.EditorListener; -import org.thialfihar.android.apg.ui.widget.KeyServerEditor; +import org.apg.Apg; +import org.apg.ui.widget.Editor; +import org.apg.ui.widget.KeyServerEditor; +import org.apg.ui.widget.Editor.EditorListener; +import org.apg.R; import android.content.Context; import android.content.Intent; diff --git a/src/org/thialfihar/android/apg/KeyServerQueryActivity.java b/src/org/apg/ui/KeyServerQueryActivity.java similarity index 97% rename from src/org/thialfihar/android/apg/KeyServerQueryActivity.java rename to src/org/apg/ui/KeyServerQueryActivity.java index ccf4e33d8..f1f6466e3 100644 --- a/src/org/thialfihar/android/apg/KeyServerQueryActivity.java +++ b/src/org/apg/ui/KeyServerQueryActivity.java @@ -1,12 +1,17 @@ -package org.thialfihar.android.apg; +package org.apg.ui; import java.util.List; import java.util.Vector; -import org.thialfihar.android.apg.KeyServer.InsufficientQuery; -import org.thialfihar.android.apg.KeyServer.KeyInfo; -import org.thialfihar.android.apg.KeyServer.QueryException; -import org.thialfihar.android.apg.KeyServer.TooManyResponses; +import org.apg.Apg; +import org.apg.Constants; +import org.apg.HkpKeyServer; +import org.apg.Id; +import org.apg.KeyServer.InsufficientQuery; +import org.apg.KeyServer.KeyInfo; +import org.apg.KeyServer.QueryException; +import org.apg.KeyServer.TooManyResponses; +import org.apg.R; import android.app.Activity; import android.app.Dialog; diff --git a/src/org/thialfihar/android/apg/MailListActivity.java b/src/org/apg/ui/MailListActivity.java similarity index 98% rename from src/org/thialfihar/android/apg/MailListActivity.java rename to src/org/apg/ui/MailListActivity.java index 2f3108644..ad1d08068 100644 --- a/src/org/thialfihar/android/apg/MailListActivity.java +++ b/src/org/apg/ui/MailListActivity.java @@ -14,11 +14,15 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg.ui; import java.util.Vector; import java.util.regex.Matcher; +import org.apg.Apg; +import org.apg.Preferences; +import org.apg.R; + import android.app.ListActivity; import android.content.Context; import android.content.Intent; diff --git a/src/org/thialfihar/android/apg/MainActivity.java b/src/org/apg/ui/MainActivity.java similarity index 98% rename from src/org/thialfihar/android/apg/MainActivity.java rename to src/org/apg/ui/MainActivity.java index 1d4ca37ff..8c985c2ac 100644 --- a/src/org/thialfihar/android/apg/MainActivity.java +++ b/src/org/apg/ui/MainActivity.java @@ -14,14 +14,20 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg.ui; import java.security.Security; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apg.Apg; +import org.apg.Id; +import org.apg.Id.dialog; +import org.apg.Id.menu; +import org.apg.Id.menu.option; +import org.apg.provider.Accounts; import org.spongycastle.jce.provider.BouncyCastleProvider; -import org.thialfihar.android.apg.provider.Accounts; +import org.apg.R; import android.app.AlertDialog; import android.app.Dialog; diff --git a/src/org/thialfihar/android/apg/PreferencesActivity.java b/src/org/apg/ui/PreferencesActivity.java similarity index 97% rename from src/org/thialfihar/android/apg/PreferencesActivity.java rename to src/org/apg/ui/PreferencesActivity.java index 49ea1a983..749f70657 100644 --- a/src/org/thialfihar/android/apg/PreferencesActivity.java +++ b/src/org/apg/ui/PreferencesActivity.java @@ -14,11 +14,20 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg.ui; +import org.apg.Apg; +import org.apg.Constants; +import org.apg.Id; +import org.apg.Preferences; +import org.apg.Constants.pref; +import org.apg.Id.choice; +import org.apg.Id.request; +import org.apg.Id.choice.compression; +import org.apg.ui.widget.IntegerListPreference; import org.spongycastle.bcpg.HashAlgorithmTags; import org.spongycastle.openpgp.PGPEncryptedData; -import org.thialfihar.android.apg.ui.widget.IntegerListPreference; +import org.apg.R; import android.content.Intent; import android.os.Bundle; diff --git a/src/org/thialfihar/android/apg/PublicKeyListActivity.java b/src/org/apg/ui/PublicKeyListActivity.java similarity index 96% rename from src/org/thialfihar/android/apg/PublicKeyListActivity.java rename to src/org/apg/ui/PublicKeyListActivity.java index 5bcc97db5..a9c5dbc15 100644 --- a/src/org/thialfihar/android/apg/PublicKeyListActivity.java +++ b/src/org/apg/ui/PublicKeyListActivity.java @@ -14,9 +14,18 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg.ui; +import org.apg.Apg; +import org.apg.Constants; +import org.apg.Id; +import org.apg.Constants.path; +import org.apg.Id.menu; +import org.apg.Id.request; +import org.apg.Id.type; +import org.apg.Id.menu.option; import org.spongycastle.openpgp.PGPPublicKeyRing; +import org.apg.R; import android.content.Intent; import android.os.Bundle; diff --git a/src/org/thialfihar/android/apg/SecretKeyListActivity.java b/src/org/apg/ui/SecretKeyListActivity.java similarity index 95% rename from src/org/thialfihar/android/apg/SecretKeyListActivity.java rename to src/org/apg/ui/SecretKeyListActivity.java index d160042fc..c8a5c9866 100644 --- a/src/org/thialfihar/android/apg/SecretKeyListActivity.java +++ b/src/org/apg/ui/SecretKeyListActivity.java @@ -14,7 +14,19 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg.ui; + +import org.apg.Apg; +import org.apg.AskForSecretKeyPassPhrase; +import org.apg.Constants; +import org.apg.Id; +import org.apg.Constants.path; +import org.apg.Id.dialog; +import org.apg.Id.menu; +import org.apg.Id.message; +import org.apg.Id.type; +import org.apg.Id.menu.option; +import org.apg.R; import android.app.Dialog; import android.content.Intent; diff --git a/src/org/thialfihar/android/apg/SelectPublicKeyListActivity.java b/src/org/apg/ui/SelectPublicKeyListActivity.java similarity index 97% rename from src/org/thialfihar/android/apg/SelectPublicKeyListActivity.java rename to src/org/apg/ui/SelectPublicKeyListActivity.java index 40b261d1b..5216e7a3d 100644 --- a/src/org/thialfihar/android/apg/SelectPublicKeyListActivity.java +++ b/src/org/apg/ui/SelectPublicKeyListActivity.java @@ -14,10 +14,16 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg.ui; import java.util.Vector; +import org.apg.Apg; +import org.apg.Id; +import org.apg.Id.menu; +import org.apg.Id.menu.option; +import org.apg.R; + import android.app.SearchManager; import android.content.Intent; import android.os.Bundle; diff --git a/src/org/thialfihar/android/apg/SelectPublicKeyListAdapter.java b/src/org/apg/ui/SelectPublicKeyListAdapter.java similarity index 97% rename from src/org/thialfihar/android/apg/SelectPublicKeyListAdapter.java rename to src/org/apg/ui/SelectPublicKeyListAdapter.java index 5933aad64..b2f49f74a 100644 --- a/src/org/thialfihar/android/apg/SelectPublicKeyListAdapter.java +++ b/src/org/apg/ui/SelectPublicKeyListAdapter.java @@ -14,13 +14,17 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg.ui; import java.util.Date; -import org.thialfihar.android.apg.provider.KeyRings; -import org.thialfihar.android.apg.provider.Keys; -import org.thialfihar.android.apg.provider.UserIds; +import org.apg.Apg; +import org.apg.Id; +import org.apg.Id.database; +import org.apg.provider.KeyRings; +import org.apg.provider.Keys; +import org.apg.provider.UserIds; +import org.apg.R; import android.app.Activity; import android.content.Context; diff --git a/src/org/thialfihar/android/apg/SelectSecretKeyListActivity.java b/src/org/apg/ui/SelectSecretKeyListActivity.java similarity index 96% rename from src/org/thialfihar/android/apg/SelectSecretKeyListActivity.java rename to src/org/apg/ui/SelectSecretKeyListActivity.java index 45aac9d08..191a0ecc7 100644 --- a/src/org/thialfihar/android/apg/SelectSecretKeyListActivity.java +++ b/src/org/apg/ui/SelectSecretKeyListActivity.java @@ -14,7 +14,13 @@ * limitations under the License. */ -package org.thialfihar.android.apg; +package org.apg.ui; + +import org.apg.Apg; +import org.apg.Id; +import org.apg.Id.menu; +import org.apg.Id.menu.option; +import org.apg.R; import android.app.SearchManager; import android.content.Intent; diff --git a/src/org/thialfihar/android/apg/SelectSecretKeyListAdapter.java b/src/org/apg/ui/SelectSecretKeyListAdapter.java similarity index 97% rename from src/org/thialfihar/android/apg/SelectSecretKeyListAdapter.java rename to src/org/apg/ui/SelectSecretKeyListAdapter.java index 405498d7c..1a7734245 100644 --- a/src/org/thialfihar/android/apg/SelectSecretKeyListAdapter.java +++ b/src/org/apg/ui/SelectSecretKeyListAdapter.java @@ -1,10 +1,14 @@ -package org.thialfihar.android.apg; +package org.apg.ui; import java.util.Date; -import org.thialfihar.android.apg.provider.KeyRings; -import org.thialfihar.android.apg.provider.Keys; -import org.thialfihar.android.apg.provider.UserIds; +import org.apg.Apg; +import org.apg.Id; +import org.apg.Id.database; +import org.apg.provider.KeyRings; +import org.apg.provider.Keys; +import org.apg.provider.UserIds; +import org.apg.R; import android.app.Activity; import android.content.Context; diff --git a/src/org/thialfihar/android/apg/SendKeyActivity.java b/src/org/apg/ui/SendKeyActivity.java similarity index 93% rename from src/org/thialfihar/android/apg/SendKeyActivity.java rename to src/org/apg/ui/SendKeyActivity.java index 9fe201a7a..2dcb08d3d 100644 --- a/src/org/thialfihar/android/apg/SendKeyActivity.java +++ b/src/org/apg/ui/SendKeyActivity.java @@ -1,7 +1,14 @@ -package org.thialfihar.android.apg; +package org.apg.ui; +import org.apg.Apg; +import org.apg.Constants; +import org.apg.HkpKeyServer; +import org.apg.Id; +import org.apg.Constants.extras; +import org.apg.Id.message; import org.spongycastle.openpgp.PGPKeyRing; import org.spongycastle.openpgp.PGPPublicKeyRing; +import org.apg.R; import android.os.Bundle; import android.os.Message; diff --git a/src/org/thialfihar/android/apg/SignKeyActivity.java b/src/org/apg/ui/SignKeyActivity.java similarity index 97% rename from src/org/thialfihar/android/apg/SignKeyActivity.java rename to src/org/apg/ui/SignKeyActivity.java index 0d8a473bd..6fad76dff 100644 --- a/src/org/thialfihar/android/apg/SignKeyActivity.java +++ b/src/org/apg/ui/SignKeyActivity.java @@ -1,10 +1,19 @@ -package org.thialfihar.android.apg; +package org.apg.ui; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SignatureException; import java.util.Iterator; +import org.apg.Apg; +import org.apg.Constants; +import org.apg.HkpKeyServer; +import org.apg.Id; +import org.apg.Constants.extras; +import org.apg.Id.dialog; +import org.apg.Id.message; +import org.apg.Id.request; +import org.apg.Id.return_value; import org.spongycastle.jce.provider.BouncyCastleProvider; import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPPrivateKey; @@ -16,6 +25,7 @@ import org.spongycastle.openpgp.PGPSignatureGenerator; import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator; import org.spongycastle.openpgp.PGPSignatureSubpacketVector; import org.spongycastle.openpgp.PGPUtil; +import org.apg.R; import android.content.Intent; import android.os.Bundle; diff --git a/src/org/thialfihar/android/apg/ui/widget/Editor.java b/src/org/apg/ui/widget/Editor.java similarity index 94% rename from src/org/thialfihar/android/apg/ui/widget/Editor.java rename to src/org/apg/ui/widget/Editor.java index a7200fad0..be95ad656 100644 --- a/src/org/thialfihar/android/apg/ui/widget/Editor.java +++ b/src/org/apg/ui/widget/Editor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.thialfihar.android.apg.ui.widget; +package org.apg.ui.widget; public interface Editor { public interface EditorListener { diff --git a/src/org/thialfihar/android/apg/ui/widget/IntegerListPreference.java b/src/org/apg/ui/widget/IntegerListPreference.java similarity index 98% rename from src/org/thialfihar/android/apg/ui/widget/IntegerListPreference.java rename to src/org/apg/ui/widget/IntegerListPreference.java index 1d5f9e3d7..fa411a786 100644 --- a/src/org/thialfihar/android/apg/ui/widget/IntegerListPreference.java +++ b/src/org/apg/ui/widget/IntegerListPreference.java @@ -14,7 +14,7 @@ * the License. */ -package org.thialfihar.android.apg.ui.widget; +package org.apg.ui.widget; import android.content.Context; import android.preference.ListPreference; diff --git a/src/org/thialfihar/android/apg/ui/widget/KeyEditor.java b/src/org/apg/ui/widget/KeyEditor.java similarity index 97% rename from src/org/thialfihar/android/apg/ui/widget/KeyEditor.java rename to src/org/apg/ui/widget/KeyEditor.java index 6bed42b88..ef98f794a 100644 --- a/src/org/thialfihar/android/apg/ui/widget/KeyEditor.java +++ b/src/org/apg/ui/widget/KeyEditor.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.thialfihar.android.apg.ui.widget; +package org.apg.ui.widget; +import org.apg.Apg; +import org.apg.Id; +import org.apg.util.Choice; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPSecretKey; -import org.thialfihar.android.apg.Apg; -import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.R; -import org.thialfihar.android.apg.utils.Choice; +import org.apg.R; import android.app.DatePickerDialog; import android.app.Dialog; diff --git a/src/org/thialfihar/android/apg/ui/widget/KeyServerEditor.java b/src/org/apg/ui/widget/KeyServerEditor.java similarity index 96% rename from src/org/thialfihar/android/apg/ui/widget/KeyServerEditor.java rename to src/org/apg/ui/widget/KeyServerEditor.java index cbea7f031..3d8634c76 100644 --- a/src/org/thialfihar/android/apg/ui/widget/KeyServerEditor.java +++ b/src/org/apg/ui/widget/KeyServerEditor.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package org.thialfihar.android.apg.ui.widget; +package org.apg.ui.widget; -import org.thialfihar.android.apg.R; +import org.apg.R; import android.content.Context; import android.util.AttributeSet; diff --git a/src/org/thialfihar/android/apg/ui/widget/SectionView.java b/src/org/apg/ui/widget/SectionView.java similarity index 97% rename from src/org/thialfihar/android/apg/ui/widget/SectionView.java rename to src/org/apg/ui/widget/SectionView.java index 13b8e01ac..220699124 100644 --- a/src/org/thialfihar/android/apg/ui/widget/SectionView.java +++ b/src/org/apg/ui/widget/SectionView.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.thialfihar.android.apg.ui.widget; +package org.apg.ui.widget; +import org.apg.Apg; +import org.apg.Id; +import org.apg.ui.widget.Editor.EditorListener; +import org.apg.util.Choice; import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPSecretKey; -import org.thialfihar.android.apg.Apg; -import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.R; -import org.thialfihar.android.apg.ui.widget.Editor.EditorListener; -import org.thialfihar.android.apg.utils.Choice; +import org.apg.R; import android.app.AlertDialog; import android.app.ProgressDialog; diff --git a/src/org/thialfihar/android/apg/ui/widget/UserIdEditor.java b/src/org/apg/ui/widget/UserIdEditor.java similarity index 98% rename from src/org/thialfihar/android/apg/ui/widget/UserIdEditor.java rename to src/org/apg/ui/widget/UserIdEditor.java index 0ff6fde4f..b154803cf 100644 --- a/src/org/thialfihar/android/apg/ui/widget/UserIdEditor.java +++ b/src/org/apg/ui/widget/UserIdEditor.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.thialfihar.android.apg.ui.widget; +package org.apg.ui.widget; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.thialfihar.android.apg.R; +import org.apg.R; import android.content.Context; import android.util.AttributeSet; diff --git a/src/org/thialfihar/android/apg/utils/ApgCon.java b/src/org/apg/util/ApgCon.java similarity index 99% rename from src/org/thialfihar/android/apg/utils/ApgCon.java rename to src/org/apg/util/ApgCon.java index c46ccf6b1..73ee66ad9 100644 --- a/src/org/thialfihar/android/apg/utils/ApgCon.java +++ b/src/org/apg/util/ApgCon.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.thialfihar.android.apg.utils; +package org.apg.util; -import org.thialfihar.android.apg.IApgService; -import org.thialfihar.android.apg.utils.ApgConInterface.OnCallFinishListener; +import org.apg.util.ApgConInterface.OnCallFinishListener; +import org.apg.IApgService; import android.content.ComponentName; import android.content.ContentResolver; diff --git a/src/org/thialfihar/android/apg/utils/ApgConInterface.java b/src/org/apg/util/ApgConInterface.java similarity index 79% rename from src/org/thialfihar/android/apg/utils/ApgConInterface.java rename to src/org/apg/util/ApgConInterface.java index 27254fe95..2b66164f1 100644 --- a/src/org/thialfihar/android/apg/utils/ApgConInterface.java +++ b/src/org/apg/util/ApgConInterface.java @@ -1,4 +1,4 @@ -package org.thialfihar.android.apg.utils; +package org.apg.util; public interface ApgConInterface { public static interface OnCallFinishListener { diff --git a/src/org/thialfihar/android/apg/utils/Choice.java b/src/org/apg/util/Choice.java similarity index 96% rename from src/org/thialfihar/android/apg/utils/Choice.java rename to src/org/apg/util/Choice.java index 0cd35e048..1dbd9b215 100644 --- a/src/org/thialfihar/android/apg/utils/Choice.java +++ b/src/org/apg/util/Choice.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.thialfihar.android.apg.utils; +package org.apg.util; public class Choice { private String mName; diff --git a/src/org/thialfihar/android/apg/utils/Compatibility.java b/src/org/apg/util/Compatibility.java similarity index 98% rename from src/org/thialfihar/android/apg/utils/Compatibility.java rename to src/org/apg/util/Compatibility.java index 1a1a44020..10b3c7f6b 100644 --- a/src/org/thialfihar/android/apg/utils/Compatibility.java +++ b/src/org/apg/util/Compatibility.java @@ -1,4 +1,4 @@ -package org.thialfihar.android.apg.utils; +package org.apg.util; import java.lang.reflect.Method; diff --git a/src/org/thialfihar/android/apg/utils/IterableIterator.java b/src/org/apg/util/IterableIterator.java similarity index 95% rename from src/org/thialfihar/android/apg/utils/IterableIterator.java rename to src/org/apg/util/IterableIterator.java index 1d9664e38..be6632ac0 100644 --- a/src/org/thialfihar/android/apg/utils/IterableIterator.java +++ b/src/org/apg/util/IterableIterator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.thialfihar.android.apg.utils; +package org.apg.util; import java.util.Iterator; diff --git a/src/org/thialfihar/android/apg/BaseActivity.java b/src/org/thialfihar/android/apg/BaseActivity.java deleted file mode 100644 index 36c7225bc..000000000 --- a/src/org/thialfihar/android/apg/BaseActivity.java +++ /dev/null @@ -1,464 +0,0 @@ -/* - * Copyright (C) 2010 Thialfihar - * - * 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.thialfihar.android.apg; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Locale; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.ProgressDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.res.Configuration; -import android.os.Bundle; -import android.os.Environment; -import android.os.Handler; -import android.os.Message; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.TextView; -import android.widget.Toast; - -public class BaseActivity extends Activity - implements Runnable, ProgressDialogUpdater, - AskForSecretKeyPassPhrase.PassPhraseCallbackInterface { - - private ProgressDialog mProgressDialog = null; - private PausableThread mRunningThread = null; - private Thread mDeletingThread = null; - - private long mSecretKeyId = 0; - private String mDeleteFile = null; - - protected Preferences mPreferences; - - private Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - handlerCallback(msg); - } - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - mPreferences = Preferences.getPreferences(this); - setLanguage(this, mPreferences.getLanguage()); - - Apg.initialize(this); - - 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 - } - } - - startCacheService(this, mPreferences); - } - - public static void startCacheService(Activity activity, Preferences preferences) { - Intent intent = new Intent(activity, Service.class); - intent.putExtra(Service.EXTRA_TTL, preferences.getPassPhraseCacheTtl()); - activity.startService(intent); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(0, Id.menu.option.preferences, 0, R.string.menu_preferences) - .setIcon(android.R.drawable.ic_menu_preferences); - menu.add(0, Id.menu.option.about, 1, R.string.menu_about) - .setIcon(android.R.drawable.ic_menu_info_details); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case Id.menu.option.about: { - showDialog(Id.dialog.about); - return true; - } - - case Id.menu.option.preferences: { - startActivity(new Intent(this, PreferencesActivity.class)); - return true; - } - - case Id.menu.option.search: { - startSearch("", false, null, false); - return true; - } - - default: { - break; - } - } - return false; - } - - @Override - protected Dialog onCreateDialog(int id) { - // in case it is a progress dialog - mProgressDialog = new ProgressDialog(this); - mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); - mProgressDialog.setCancelable(false); - switch (id) { - case Id.dialog.encrypting: { - mProgressDialog.setMessage(this.getString(R.string.progress_initializing)); - return mProgressDialog; - } - - case Id.dialog.decrypting: { - mProgressDialog.setMessage(this.getString(R.string.progress_initializing)); - return mProgressDialog; - } - - case Id.dialog.saving: { - mProgressDialog.setMessage(this.getString(R.string.progress_saving)); - return mProgressDialog; - } - - case Id.dialog.importing: { - mProgressDialog.setMessage(this.getString(R.string.progress_importing)); - return mProgressDialog; - } - - case Id.dialog.exporting: { - mProgressDialog.setMessage(this.getString(R.string.progress_exporting)); - return mProgressDialog; - } - - case Id.dialog.deleting: { - mProgressDialog.setMessage(this.getString(R.string.progress_initializing)); - return mProgressDialog; - } - - case Id.dialog.querying: { - mProgressDialog.setMessage(this.getString(R.string.progress_querying)); - mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); - mProgressDialog.setCancelable(false); - return mProgressDialog; - } - - case Id.dialog.signing: { - mProgressDialog.setMessage(this.getString(R.string.progress_signing)); - mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); - mProgressDialog.setCancelable(false); - return mProgressDialog; - } - - default: { - break; - } - } - mProgressDialog = null; - - switch (id) { - case Id.dialog.about: { - AlertDialog.Builder alert = new AlertDialog.Builder(this); - - alert.setTitle("About " + Apg.getFullVersion(this)); - - LayoutInflater inflater = - (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - View layout = inflater.inflate(R.layout.info, null); - TextView message = (TextView) layout.findViewById(R.id.message); - message.setText("This is an attempt to bring OpenPGP to Android. " + - "It is far from complete, but more features are planned (see website).\n\n" + - "Feel free to send bug reports, suggestions, feature requests, feedback, " + - "photographs.\n\n" + - "mail: thi@thialfihar.org\n" + - "site: http://apg.thialfihar.org\n\n" + - "This software is provided \"as is\", without warranty of any kind."); - alert.setView(layout); - - alert.setPositiveButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - BaseActivity.this.removeDialog(Id.dialog.about); - } - }); - - return alert.create(); - } - - case Id.dialog.pass_phrase: { - return AskForSecretKeyPassPhrase.createDialog(this, getSecretKeyId(), this); - } - - case Id.dialog.pass_phrases_do_not_match: { - AlertDialog.Builder alert = new AlertDialog.Builder(this); - - alert.setIcon(android.R.drawable.ic_dialog_alert); - alert.setTitle(R.string.error); - alert.setMessage(R.string.passPhrasesDoNotMatch); - - alert.setPositiveButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - removeDialog(Id.dialog.pass_phrases_do_not_match); - } - }); - alert.setCancelable(false); - - return alert.create(); - } - - case Id.dialog.no_pass_phrase: { - AlertDialog.Builder alert = new AlertDialog.Builder(this); - - alert.setIcon(android.R.drawable.ic_dialog_alert); - alert.setTitle(R.string.error); - alert.setMessage(R.string.passPhraseMustNotBeEmpty); - - alert.setPositiveButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - removeDialog(Id.dialog.no_pass_phrase); - } - }); - alert.setCancelable(false); - - return alert.create(); - } - - case Id.dialog.delete_file: { - AlertDialog.Builder alert = new AlertDialog.Builder(this); - - alert.setIcon(android.R.drawable.ic_dialog_alert); - alert.setTitle(R.string.warning); - alert.setMessage(this.getString(R.string.fileDeleteConfirmation, getDeleteFile())); - - alert.setPositiveButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - removeDialog(Id.dialog.delete_file); - final File file = new File(getDeleteFile()); - showDialog(Id.dialog.deleting); - mDeletingThread = new Thread(new Runnable() { - public void run() { - Bundle data = new Bundle(); - data.putInt(Constants.extras.status, Id.message.delete_done); - try { - Apg.deleteFileSecurely(BaseActivity.this, file, BaseActivity.this); - } catch (FileNotFoundException e) { - data.putString(Apg.EXTRA_ERROR, - BaseActivity.this.getString( - R.string.error_fileNotFound, file)); - } catch (IOException e) { - data.putString(Apg.EXTRA_ERROR, - BaseActivity.this.getString( - R.string.error_fileDeleteFailed, file)); - } - Message msg = new Message(); - msg.setData(data); - sendMessage(msg); - } - }); - mDeletingThread.start(); - } - }); - alert.setNegativeButton(android.R.string.cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - removeDialog(Id.dialog.delete_file); - } - }); - alert.setCancelable(true); - - return alert.create(); - } - - default: { - break; - } - } - - return super.onCreateDialog(id); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - switch (requestCode) { - case Id.request.secret_keys: { - if (resultCode == RESULT_OK) { - Bundle bundle = data.getExtras(); - setSecretKeyId(bundle.getLong(Apg.EXTRA_KEY_ID)); - } else { - setSecretKeyId(Id.key.none); - } - break; - } - - default: { - break; - } - } - - super.onActivityResult(requestCode, resultCode, data); - } - - public void setProgress(int resourceId, int progress, int max) { - setProgress(getString(resourceId), progress, max); - } - - public void setProgress(int progress, int max) { - Message msg = new Message(); - Bundle data = new Bundle(); - data.putInt(Constants.extras.status, Id.message.progress_update); - data.putInt(Constants.extras.progress, progress); - data.putInt(Constants.extras.progress_max, max); - msg.setData(data); - mHandler.sendMessage(msg); - } - - public void setProgress(String message, int progress, int max) { - Message msg = new Message(); - Bundle data = new Bundle(); - data.putInt(Constants.extras.status, Id.message.progress_update); - data.putString(Constants.extras.message, message); - data.putInt(Constants.extras.progress, progress); - data.putInt(Constants.extras.progress_max, max); - msg.setData(data); - mHandler.sendMessage(msg); - } - - public void handlerCallback(Message msg) { - Bundle data = msg.getData(); - if (data == null) { - return; - } - - int type = data.getInt(Constants.extras.status); - switch (type) { - case Id.message.progress_update: { - String message = data.getString(Constants.extras.message); - if (mProgressDialog != null) { - if (message != null) { - mProgressDialog.setMessage(message); - } - mProgressDialog.setMax(data.getInt(Constants.extras.progress_max)); - mProgressDialog.setProgress(data.getInt(Constants.extras.progress)); - } - break; - } - - case Id.message.delete_done: { - mProgressDialog = null; - deleteDoneCallback(msg); - break; - } - - case Id.message.import_done: // intentionally no break - case Id.message.export_done: // intentionally no break - case Id.message.query_done: // intentionally no break - case Id.message.done: { - mProgressDialog = null; - doneCallback(msg); - break; - } - - default: { - break; - } - } - } - - public void doneCallback(Message msg) { - - } - - public void deleteDoneCallback(Message msg) { - removeDialog(Id.dialog.deleting); - mDeletingThread = null; - - Bundle data = msg.getData(); - String error = data.getString(Apg.EXTRA_ERROR); - String message; - if (error != null) { - message = getString(R.string.errorMessage, error); - } else { - message = getString(R.string.fileDeleteSuccessful); - } - - Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); - } - - public void passPhraseCallback(long keyId, String passPhrase) { - Apg.setCachedPassPhrase(keyId, passPhrase); - } - - public void sendMessage(Message msg) { - mHandler.sendMessage(msg); - } - - public PausableThread getRunningThread() { - return mRunningThread; - } - - public void startThread() { - mRunningThread = new PausableThread(this); - mRunningThread.start(); - } - - public void run() { - - } - - public void setSecretKeyId(long id) { - mSecretKeyId = id; - } - - public long getSecretKeyId() { - return mSecretKeyId; - } - - protected void setDeleteFile(String deleteFile) { - mDeleteFile = deleteFile; - } - - protected String getDeleteFile() { - return mDeleteFile; - } - - public static void setLanguage(Context context, String language) - { - Locale locale; - if (language == null || language.equals("")) - { - locale = Locale.getDefault(); - } - else - { - locale = new Locale(language); - } - Configuration config = new Configuration(); - config.locale = locale; - context.getResources().updateConfiguration(config, - context.getResources().getDisplayMetrics()); - } -} diff --git a/src/org/thialfihar/android/apg/DataDestination.java b/src/org/thialfihar/android/apg/DataDestination.java deleted file mode 100644 index a09154c2d..000000000 --- a/src/org/thialfihar/android/apg/DataDestination.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.thialfihar.android.apg; - -import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -import org.thialfihar.android.apg.Apg.GeneralException; - -import android.content.Context; -import android.os.Environment; - -public class DataDestination { - private String mStreamFilename; - private String mFilename; - private int mMode = Id.mode.undefined; - - public DataDestination() { - - } - - public void setMode(int mode) { - mMode = mode; - } - - public void setFilename(String filename) { - mFilename = filename; - } - - public String getStreamFilename() { - return mStreamFilename; - } - - protected OutputStream getOutputStream(Context context) - throws Apg.GeneralException, FileNotFoundException, IOException { - OutputStream out = null; - mStreamFilename = null; - - switch (mMode) { - case Id.mode.stream: { - try { - while (true) { - mStreamFilename = Apg.generateRandomString(32); - if (mStreamFilename == null) { - throw new Apg.GeneralException("couldn't generate random file name"); - } - context.openFileInput(mStreamFilename).close(); - } - } catch (FileNotFoundException e) { - // found a name that isn't used yet - } - out = context.openFileOutput(mStreamFilename, Context.MODE_PRIVATE); - break; - } - - case Id.mode.byte_array: { - out = new ByteArrayOutputStream(); - break; - } - - case Id.mode.file: { - if (mFilename.startsWith(Environment.getExternalStorageDirectory().getAbsolutePath())) { - if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - throw new GeneralException(context.getString(R.string.error_externalStorageNotReady)); - } - } - out = new FileOutputStream(mFilename); - break; - } - - default: { - break; - } - } - - return out; - } -}