mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-27 03:02:15 -05:00
renaming whole package to org.apg to simplifiy name
This commit is contained in:
parent
df6933bfb8
commit
8452fb62b7
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:installLocation="auto"
|
android:installLocation="auto"
|
||||||
package="org.thialfihar.android.apg"
|
package="org.apg"
|
||||||
android:versionCode="11000"
|
android:versionCode="11000"
|
||||||
android:versionName="1.1" >
|
android:versionName="1.1" >
|
||||||
|
|
||||||
@ -33,7 +33,7 @@
|
|||||||
android:icon="@drawable/icon"
|
android:icon="@drawable/icon"
|
||||||
android:label="@string/app_name" >
|
android:label="@string/app_name" >
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".ui.MainActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|keyboard"
|
android:configChanges="keyboardHidden|orientation|keyboard"
|
||||||
android:label="@string/app_name" >
|
android:label="@string/app_name" >
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@ -43,7 +43,7 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".PublicKeyListActivity"
|
android:name=".ui.PublicKeyListActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|keyboard"
|
android:configChanges="keyboardHidden|orientation|keyboard"
|
||||||
android:label="@string/title_managePublicKeys"
|
android:label="@string/title_managePublicKeys"
|
||||||
android:launchMode="singleTop" >
|
android:launchMode="singleTop" >
|
||||||
@ -56,7 +56,7 @@
|
|||||||
android:resource="@xml/searchable_public_keys" />
|
android:resource="@xml/searchable_public_keys" />
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".SecretKeyListActivity"
|
android:name=".ui.SecretKeyListActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|keyboard"
|
android:configChanges="keyboardHidden|orientation|keyboard"
|
||||||
android:label="@string/title_manageSecretKeys"
|
android:label="@string/title_manageSecretKeys"
|
||||||
android:launchMode="singleTop" >
|
android:launchMode="singleTop" >
|
||||||
@ -69,11 +69,11 @@
|
|||||||
android:resource="@xml/searchable_secret_keys" />
|
android:resource="@xml/searchable_secret_keys" />
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".EditKeyActivity"
|
android:name=".ui.EditKeyActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|keyboard"
|
android:configChanges="keyboardHidden|orientation|keyboard"
|
||||||
android:label="@string/title_editKey" />
|
android:label="@string/title_editKey" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".SelectPublicKeyListActivity"
|
android:name=".ui.SelectPublicKeyListActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|keyboard"
|
android:configChanges="keyboardHidden|orientation|keyboard"
|
||||||
android:label="@string/title_selectRecipients"
|
android:label="@string/title_selectRecipients"
|
||||||
android:launchMode="singleTop" >
|
android:launchMode="singleTop" >
|
||||||
@ -91,7 +91,7 @@
|
|||||||
android:resource="@xml/searchable_public_keys" />
|
android:resource="@xml/searchable_public_keys" />
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".SelectSecretKeyListActivity"
|
android:name=".ui.SelectSecretKeyListActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|keyboard"
|
android:configChanges="keyboardHidden|orientation|keyboard"
|
||||||
android:label="@string/title_selectSignature"
|
android:label="@string/title_selectSignature"
|
||||||
android:launchMode="singleTop" >
|
android:launchMode="singleTop" >
|
||||||
@ -109,7 +109,7 @@
|
|||||||
android:resource="@xml/searchable_secret_keys" />
|
android:resource="@xml/searchable_secret_keys" />
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".EncryptActivity"
|
android:name=".ui.EncryptActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|keyboard"
|
android:configChanges="keyboardHidden|orientation|keyboard"
|
||||||
android:label="@string/title_encrypt" >
|
android:label="@string/title_encrypt" >
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@ -124,7 +124,7 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".DecryptActivity"
|
android:name=".ui.DecryptActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|keyboard"
|
android:configChanges="keyboardHidden|orientation|keyboard"
|
||||||
android:label="@string/title_decrypt" >
|
android:label="@string/title_decrypt" >
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@ -138,7 +138,7 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".GeneralActivity"
|
android:name=".ui.GeneralActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|keyboard"
|
android:configChanges="keyboardHidden|orientation|keyboard"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@android:style/Theme.Dialog" >
|
android:theme="@android:style/Theme.Dialog" >
|
||||||
@ -170,31 +170,31 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".MailListActivity"
|
android:name=".ui.MailListActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|keyboard"
|
android:configChanges="keyboardHidden|orientation|keyboard"
|
||||||
android:label="@string/title_mailInbox" />
|
android:label="@string/title_mailInbox" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".KeyServerQueryActivity"
|
android:name=".ui.KeyServerQueryActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|keyboard"
|
android:configChanges="keyboardHidden|orientation|keyboard"
|
||||||
android:label="@string/title_keyServerQuery" />
|
android:label="@string/title_keyServerQuery" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".SendKeyActivity"
|
android:name=".ui.SendKeyActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|keyboard"
|
android:configChanges="keyboardHidden|orientation|keyboard"
|
||||||
android:label="@string/title_sendKey" />
|
android:label="@string/title_sendKey" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".PreferencesActivity"
|
android:name=".ui.PreferencesActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|keyboard"
|
android:configChanges="keyboardHidden|orientation|keyboard"
|
||||||
android:label="@string/title_preferences" />
|
android:label="@string/title_preferences" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".KeyServerPreferenceActivity"
|
android:name=".ui.KeyServerPreferenceActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|keyboard"
|
android:configChanges="keyboardHidden|orientation|keyboard"
|
||||||
android:label="@string/title_keyServerPreference" />
|
android:label="@string/title_keyServerPreference" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".SignKeyActivity"
|
android:name=".ui.SignKeyActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|keyboard"
|
android:configChanges="keyboardHidden|orientation|keyboard"
|
||||||
android:label="@string/title_signKey" />
|
android:label="@string/title_signKey" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ImportFromQRCodeActivity"
|
android:name=".ui.ImportFromQRCodeActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|keyboard"
|
android:configChanges="keyboardHidden|orientation|keyboard"
|
||||||
android:label="@string/title_importFromQRCode" />
|
android:label="@string/title_importFromQRCode" />
|
||||||
|
|
||||||
@ -215,11 +215,11 @@
|
|||||||
</service>
|
</service>
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name="org.thialfihar.android.apg.provider.DataProvider"
|
android:name=".provider.DataProvider"
|
||||||
android:authorities="org.thialfihar.android.apg.provider"
|
android:authorities="org.thialfihar.android.apg.provider"
|
||||||
android:readPermission="org.thialfihar.android.apg.permission.READ_KEY_DETAILS" />
|
android:readPermission="org.thialfihar.android.apg.permission.READ_KEY_DETAILS" />
|
||||||
<provider
|
<provider
|
||||||
android:name="org.thialfihar.android.apg.provider.ApgServiceBlobProvider"
|
android:name=".provider.ApgServiceBlobProvider"
|
||||||
android:authorities="org.thialfihar.android.apg.provider.apgserviceblobprovider"
|
android:authorities="org.thialfihar.android.apg.provider.apgserviceblobprovider"
|
||||||
android:permission="org.thialfihar.android.apg.permission.STORE_BLOBS" />
|
android:permission="org.thialfihar.android.apg.permission.STORE_BLOBS" />
|
||||||
</application>
|
</application>
|
||||||
|
202
COPYING
Normal file
202
COPYING
Normal file
@ -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.
|
@ -14,7 +14,7 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<org.thialfihar.android.apg.ui.widget.SectionView
|
<org.apg.ui.widget.SectionView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -63,4 +63,4 @@
|
|||||||
android:paddingBottom="6dip"
|
android:paddingBottom="6dip"
|
||||||
android:orientation="vertical"/>
|
android:orientation="vertical"/>
|
||||||
|
|
||||||
</org.thialfihar.android.apg.ui.widget.SectionView>
|
</org.apg.ui.widget.SectionView>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<org.thialfihar.android.apg.ui.widget.UserIdEditor
|
<org.apg.ui.widget.UserIdEditor
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -112,4 +112,4 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</org.thialfihar.android.apg.ui.widget.UserIdEditor>
|
</org.apg.ui.widget.UserIdEditor>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<org.thialfihar.android.apg.ui.widget.KeyServerEditor
|
<org.apg.ui.widget.KeyServerEditor
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -49,4 +49,4 @@
|
|||||||
android:layout_height="1dip"
|
android:layout_height="1dip"
|
||||||
android:background="?android:attr/listDivider"/>
|
android:background="?android:attr/listDivider"/>
|
||||||
|
|
||||||
</org.thialfihar.android.apg.ui.widget.KeyServerEditor>
|
</org.apg.ui.widget.KeyServerEditor>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
|
<!--
|
||||||
|
Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@ -15,6 +16,7 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<style name="MinusButton">
|
<style name="MinusButton">
|
||||||
<item name="android:background">@drawable/btn_circle</item>
|
<item name="android:background">@drawable/btn_circle</item>
|
||||||
<item name="android:src">@drawable/ic_btn_round_minus</item>
|
<item name="android:src">@drawable/ic_btn_round_minus</item>
|
||||||
@ -24,4 +26,5 @@
|
|||||||
<item name="android:background">@drawable/btn_circle</item>
|
<item name="android:background">@drawable/btn_circle</item>
|
||||||
<item name="android:src">@drawable/ic_btn_round_plus</item>
|
<item name="android:src">@drawable/ic_btn_round_plus</item>
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
|
||||||
|
</resources>
|
@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
|
<!--
|
||||||
|
Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@ -14,71 +15,56 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<PreferenceScreen
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
|
|
||||||
<PreferenceCategory
|
|
||||||
android:title="@string/section_general">
|
|
||||||
|
|
||||||
|
<PreferenceCategory android:title="@string/section_general" >
|
||||||
<ListPreference
|
<ListPreference
|
||||||
android:key="language"
|
android:dialogTitle="@string/label_language"
|
||||||
android:title="@string/label_language"
|
|
||||||
android:entries="@array/language_entries"
|
android:entries="@array/language_entries"
|
||||||
android:entryValues="@array/language_values"
|
android:entryValues="@array/language_values"
|
||||||
android:dialogTitle="@string/label_language" />
|
android:key="language"
|
||||||
|
android:title="@string/label_language" />
|
||||||
|
|
||||||
<org.thialfihar.android.apg.ui.widget.IntegerListPreference
|
<org.apg.ui.widget.IntegerListPreference
|
||||||
android:persistent="false"
|
|
||||||
android:key="passPhraseCacheTtl"
|
|
||||||
android:entries="@array/pass_phrase_cache_ttl_entries"
|
android:entries="@array/pass_phrase_cache_ttl_entries"
|
||||||
android:entryValues="@array/pass_phrase_cache_ttl_values"
|
android:entryValues="@array/pass_phrase_cache_ttl_values"
|
||||||
|
android:key="passPhraseCacheTtl"
|
||||||
|
android:persistent="false"
|
||||||
android:title="@string/label_passPhraseCacheTtl" />
|
android:title="@string/label_passPhraseCacheTtl" />
|
||||||
|
|
||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
android:persistent="false"
|
|
||||||
android:key="keyServers"
|
android:key="keyServers"
|
||||||
|
android:persistent="false"
|
||||||
android:title="@string/label_keyServers" />
|
android:title="@string/label_keyServers" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
<PreferenceCategory android:title="@string/section_defaults" >
|
||||||
<PreferenceCategory
|
<org.apg.ui.widget.IntegerListPreference
|
||||||
android:title="@string/section_defaults">
|
|
||||||
|
|
||||||
<org.thialfihar.android.apg.ui.widget.IntegerListPreference
|
|
||||||
android:persistent="false"
|
|
||||||
android:key="defaultEncryptionAlgorithm"
|
android:key="defaultEncryptionAlgorithm"
|
||||||
|
android:persistent="false"
|
||||||
android:title="@string/label_encryptionAlgorithm" />
|
android:title="@string/label_encryptionAlgorithm" />
|
||||||
|
<org.apg.ui.widget.IntegerListPreference
|
||||||
<org.thialfihar.android.apg.ui.widget.IntegerListPreference
|
|
||||||
android:persistent="false"
|
|
||||||
android:key="defaultHashAlgorithm"
|
android:key="defaultHashAlgorithm"
|
||||||
|
android:persistent="false"
|
||||||
android:title="@string/label_hashAlgorithm" />
|
android:title="@string/label_hashAlgorithm" />
|
||||||
|
<org.apg.ui.widget.IntegerListPreference
|
||||||
<org.thialfihar.android.apg.ui.widget.IntegerListPreference
|
|
||||||
android:persistent="false"
|
|
||||||
android:key="defaultMessageCompression"
|
android:key="defaultMessageCompression"
|
||||||
android:title="@string/label_messageCompression" />
|
|
||||||
|
|
||||||
<org.thialfihar.android.apg.ui.widget.IntegerListPreference
|
|
||||||
android:persistent="false"
|
android:persistent="false"
|
||||||
|
android:title="@string/label_messageCompression" />
|
||||||
|
<org.apg.ui.widget.IntegerListPreference
|
||||||
android:key="defaultFileCompression"
|
android:key="defaultFileCompression"
|
||||||
|
android:persistent="false"
|
||||||
android:title="@string/label_fileCompression" />
|
android:title="@string/label_fileCompression" />
|
||||||
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:persistent="false"
|
|
||||||
android:key="defaultAsciiArmour"
|
android:key="defaultAsciiArmour"
|
||||||
android:title="@string/label_asciiArmour" />
|
|
||||||
|
|
||||||
</PreferenceCategory>
|
|
||||||
|
|
||||||
<PreferenceCategory
|
|
||||||
android:title="@string/section_advanced">
|
|
||||||
|
|
||||||
<CheckBoxPreference
|
|
||||||
android:persistent="false"
|
android:persistent="false"
|
||||||
|
android:title="@string/label_asciiArmour" />
|
||||||
|
</PreferenceCategory>
|
||||||
|
<PreferenceCategory android:title="@string/section_advanced" >
|
||||||
|
<CheckBoxPreference
|
||||||
android:key="forceV3Signatures"
|
android:key="forceV3Signatures"
|
||||||
|
android:persistent="false"
|
||||||
android:title="@string/label_forceV3Signature" />
|
android:title="@string/label_forceV3Signature" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
|
<!--
|
||||||
|
Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@ -14,8 +15,8 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<searchable
|
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
android:hint="@string/hint_publicKeys"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name" >
|
||||||
android:hint="@string/hint_publicKeys">
|
|
||||||
</searchable>
|
</searchable>
|
@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
|
<!--
|
||||||
|
Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@ -14,8 +15,8 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<searchable
|
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
android:hint="@string/hint_secretKeys"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name" >
|
||||||
android:hint="@string/hint_secretKeys">
|
|
||||||
</searchable>
|
</searchable>
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
|||||||
package org.thialfihar.android.apg;
|
package org.apg;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
@ -11,9 +11,10 @@ import java.util.HashMap;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.thialfihar.android.apg.provider.KeyRings;
|
import org.apg.provider.KeyRings;
|
||||||
import org.thialfihar.android.apg.provider.Keys;
|
import org.apg.provider.Keys;
|
||||||
import org.thialfihar.android.apg.provider.UserIds;
|
import org.apg.provider.UserIds;
|
||||||
|
import org.apg.IApgService;
|
||||||
|
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -31,28 +32,22 @@ public class ApgService extends Service {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder onBind(Intent intent) {
|
public IBinder onBind(Intent intent) {
|
||||||
if( LOCAL_LOGD ) Log.d(TAG, "bound");
|
if (LOCAL_LOGD)
|
||||||
|
Log.d(TAG, "bound");
|
||||||
return mBinder;
|
return mBinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** error status */
|
/** error status */
|
||||||
private static enum error {
|
private static enum error {
|
||||||
ARGUMENTS_MISSING,
|
ARGUMENTS_MISSING, APG_FAILURE, NO_MATCHING_SECRET_KEY, PRIVATE_KEY_PASSPHRASE_WRONG, PRIVATE_KEY_PASSPHRASE_MISSING;
|
||||||
APG_FAILURE,
|
|
||||||
NO_MATCHING_SECRET_KEY,
|
|
||||||
PRIVATE_KEY_PASSPHRASE_WRONG,
|
|
||||||
PRIVATE_KEY_PASSPHRASE_MISSING;
|
|
||||||
|
|
||||||
public int shiftedOrdinal() {
|
public int shiftedOrdinal() {
|
||||||
return ordinal() + 100;
|
return ordinal() + 100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static enum call {
|
private static enum call {
|
||||||
encrypt_with_passphrase,
|
encrypt_with_passphrase, encrypt_with_public_key, decrypt, get_keys
|
||||||
encrypt_with_public_key,
|
|
||||||
decrypt,
|
|
||||||
get_keys
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** all arguments that can be passed by calling application */
|
/** all arguments that can be passed by calling application */
|
||||||
@ -139,42 +134,49 @@ public class ApgService extends Service {
|
|||||||
private static final HashMap<String, Method> FUNCTIONS_DEFAULTS_METHODS = new HashMap<String, Method>();
|
private static final HashMap<String, Method> FUNCTIONS_DEFAULTS_METHODS = new HashMap<String, Method>();
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
FUNCTIONS_DEFAULTS_METHODS.put("getDefaultEncryptionAlgorithm", Preferences.class.getMethod("getDefaultEncryptionAlgorithm"));
|
FUNCTIONS_DEFAULTS_METHODS.put("getDefaultEncryptionAlgorithm",
|
||||||
FUNCTIONS_DEFAULTS_METHODS.put("getDefaultHashAlgorithm", Preferences.class.getMethod("getDefaultHashAlgorithm"));
|
Preferences.class.getMethod("getDefaultEncryptionAlgorithm"));
|
||||||
FUNCTIONS_DEFAULTS_METHODS.put("getDefaultAsciiArmour", Preferences.class.getMethod("getDefaultAsciiArmour"));
|
FUNCTIONS_DEFAULTS_METHODS.put("getDefaultHashAlgorithm",
|
||||||
FUNCTIONS_DEFAULTS_METHODS.put("getForceV3Signatures", Preferences.class.getMethod("getForceV3Signatures"));
|
Preferences.class.getMethod("getDefaultHashAlgorithm"));
|
||||||
FUNCTIONS_DEFAULTS_METHODS.put("getDefaultMessageCompression", Preferences.class.getMethod("getDefaultMessageCompression"));
|
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) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "Function method exception: " + e.getMessage());
|
Log.e(TAG, "Function method exception: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void writeToOutputStream(InputStream is, OutputStream os) throws IOException {
|
private static void writeToOutputStream(InputStream is, OutputStream os) throws IOException {
|
||||||
byte[] buffer = new byte[8];
|
byte[] buffer = new byte[8];
|
||||||
int len = 0;
|
int len = 0;
|
||||||
while( (len = is.read(buffer)) != -1) {
|
while ((len = is.read(buffer)) != -1) {
|
||||||
os.write(buffer, 0, len);
|
os.write(buffer, 0, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Cursor getKeyEntries(HashMap<String, Object> pParams) {
|
private static Cursor getKeyEntries(HashMap<String, Object> pParams) {
|
||||||
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
|
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
|
||||||
qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME
|
qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "("
|
||||||
+ "." + Keys.KEY_RING_ID + " AND " + Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " + UserIds.TABLE_NAME
|
+ KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME + "."
|
||||||
+ " ON " + "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " + UserIds.TABLE_NAME + "."
|
+ Keys.KEY_RING_ID + " AND " + Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY
|
||||||
+ UserIds.RANK + " = '0') ");
|
+ " = '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 typeVal[] = null;
|
||||||
String typeWhere = null;
|
String typeWhere = null;
|
||||||
if (pParams.containsKey("key_type")) {
|
if (pParams.containsKey("key_type")) {
|
||||||
typeWhere = KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?";
|
typeWhere = KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?";
|
||||||
typeVal = new String[] {
|
typeVal = new String[] { "" + pParams.get("key_type") };
|
||||||
"" + 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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* maps fingerprints or user ids of keys to master keys in database
|
* maps fingerprints or user ids of keys to master keys in database
|
||||||
*
|
*
|
||||||
* @param search_keys
|
* @param search_keys
|
||||||
* a list of keys (fingerprints or user ids) to look for in
|
* a list of keys (fingerprints or user ids) to look for in database
|
||||||
* database
|
|
||||||
* @return an array of master keys
|
* @return an array of master keys
|
||||||
*/
|
*/
|
||||||
private static long[] getMasterKey(ArrayList<String> pSearchKeys, Bundle pReturn) {
|
private static long[] getMasterKey(ArrayList<String> pSearchKeys, Bundle pReturn) {
|
||||||
|
|
||||||
HashMap<String, Object> qParams = new HashMap<String, Object>();
|
HashMap<String, Object> qParams = new HashMap<String, Object>();
|
||||||
qParams.put("columns", new String[] {
|
qParams.put("columns", new String[] { KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 0
|
||||||
KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 0
|
|
||||||
UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 1
|
UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 1
|
||||||
});
|
});
|
||||||
qParams.put("key_type", Id.database.type_public);
|
qParams.put("key_type", Id.database.type_public);
|
||||||
|
|
||||||
Cursor mCursor = getKeyEntries(qParams);
|
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<Long> masterKeys = new ArrayList<Long>();
|
ArrayList<Long> masterKeys = new ArrayList<Long>();
|
||||||
while (mCursor.moveToNext()) {
|
while (mCursor.moveToNext()) {
|
||||||
long curMkey = mCursor.getLong(0);
|
long curMkey = mCursor.getLong(0);
|
||||||
String curUser = mCursor.getString(1);
|
String curUser = mCursor.getString(1);
|
||||||
|
|
||||||
String curFprint = Apg.getSmallFingerPrint(curMkey);
|
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 (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);
|
masterKeys.add(curMkey);
|
||||||
pSearchKeys.remove(curFprint);
|
pSearchKeys.remove(curFprint);
|
||||||
} else {
|
} 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();
|
mCursor.close();
|
||||||
@ -243,12 +248,14 @@ public class ApgService extends Service {
|
|||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
Log.w(TAG, "Found not one public key");
|
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) {
|
for (String key : pSearchKeys) {
|
||||||
Log.w(TAG, "Searched for key " + key + " but cannot find it in APG");
|
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;
|
return masterKeyLongs;
|
||||||
@ -269,18 +276,27 @@ public class ApgService extends Service {
|
|||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
arg currentArg = iter.next();
|
arg currentArg = iter.next();
|
||||||
String currentKey = currentArg.name();
|
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);
|
String currentFunctionName = FUNCTIONS_DEFAULTS.get(currentArg);
|
||||||
try {
|
try {
|
||||||
Class<?> returnType = FUNCTIONS_DEFAULTS_METHODS.get(currentFunctionName).getReturnType();
|
Class<?> returnType = FUNCTIONS_DEFAULTS_METHODS.get(currentFunctionName)
|
||||||
|
.getReturnType();
|
||||||
if (returnType == String.class) {
|
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) {
|
} 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) {
|
} 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 {
|
} 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) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "Exception in add_default_arguments " + e.getMessage());
|
Log.e(TAG, "Exception in add_default_arguments " + e.getMessage());
|
||||||
@ -320,19 +336,21 @@ public class ApgService extends Service {
|
|||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
String curArg = iter.next().name();
|
String curArg = iter.next().name();
|
||||||
if (!pArgs.containsKey(curArg)) {
|
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()) ||
|
if (pFunction.equals(call.encrypt_with_passphrase.name())
|
||||||
pFunction.equals(call.encrypt_with_public_key.name()) ||
|
|| pFunction.equals(call.encrypt_with_public_key.name())
|
||||||
pFunction.equals(call.decrypt.name())) {
|
|| pFunction.equals(call.decrypt.name())) {
|
||||||
// check that either MESSAGE or BLOB are there
|
// check that either MESSAGE or BLOB are there
|
||||||
if( !pArgs.containsKey(arg.MESSAGE.name()) && !pArgs.containsKey(arg.BLOB.name())) {
|
if (!pArgs.containsKey(arg.MESSAGE.name()) && !pArgs.containsKey(arg.BLOB.name())) {
|
||||||
pReturn.getStringArrayList(ret.ERRORS.name()).add("Arguments missing: Neither MESSAGE nor BLOG found");
|
pReturn.getStringArrayList(ret.ERRORS.name()).add(
|
||||||
|
"Arguments missing: Neither MESSAGE nor BLOG found");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,7 +381,8 @@ public class ApgService extends Service {
|
|||||||
try {
|
try {
|
||||||
arg curArg = arg.valueOf(curKey);
|
arg curArg = arg.valueOf(curKey);
|
||||||
if (!allArgs.contains(curArg)) {
|
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);
|
unknownArgs.add(curKey);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -386,23 +405,28 @@ public class ApgService extends Service {
|
|||||||
|
|
||||||
/* add default arguments if missing */
|
/* add default arguments if missing */
|
||||||
addDefaultArguments(pCall, pArgs);
|
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 */
|
/* check for required arguments */
|
||||||
checkForRequiredArgs(pCall, pArgs, pReturn);
|
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 */
|
/* check for unknown arguments and add to warning if found */
|
||||||
checkForUnknownArgs(pCall, pArgs, pReturn);
|
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 */
|
/* return if errors happened */
|
||||||
if (pReturn.getStringArrayList(ret.ERRORS.name()).size() != 0) {
|
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());
|
pReturn.putInt(ret.ERROR.name(), error.ARGUMENTS_MISSING.shiftedOrdinal());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if( LOCAL_LOGV ) Log.v(TAG, "error return");
|
if (LOCAL_LOGV)
|
||||||
|
Log.v(TAG, "error return");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -414,7 +438,8 @@ public class ApgService extends Service {
|
|||||||
if (pArgs.containsKey(arg.PUBLIC_KEYS.name())) {
|
if (pArgs.containsKey(arg.PUBLIC_KEYS.name())) {
|
||||||
ArrayList<String> list = pArgs.getStringArrayList(arg.PUBLIC_KEYS.name());
|
ArrayList<String> list = pArgs.getStringArrayList(arg.PUBLIC_KEYS.name());
|
||||||
ArrayList<String> pubKeys = new ArrayList<String>();
|
ArrayList<String> pubKeys = new ArrayList<String>();
|
||||||
if( LOCAL_LOGV ) Log.v(TAG, "Long size: " + list.size());
|
if (LOCAL_LOGV)
|
||||||
|
Log.v(TAG, "Long size: " + list.size());
|
||||||
Iterator<String> iter = list.iterator();
|
Iterator<String> iter = list.iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
pubKeys.add(iter.next());
|
pubKeys.add(iter.next());
|
||||||
@ -423,7 +448,7 @@ public class ApgService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
InputStream inStream = null;
|
InputStream inStream = null;
|
||||||
if(isBlob) {
|
if (isBlob) {
|
||||||
ContentResolver cr = getContentResolver();
|
ContentResolver cr = getContentResolver();
|
||||||
try {
|
try {
|
||||||
inStream = cr.openInputStream(Uri.parse(pArgs.getString(arg.BLOB.name())));
|
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?
|
InputData in = new InputData(inStream, 0); // XXX Size second param?
|
||||||
|
|
||||||
OutputStream out = new ByteArrayOutputStream();
|
OutputStream out = new ByteArrayOutputStream();
|
||||||
if( LOCAL_LOGV ) Log.v(TAG, "About to encrypt");
|
if (LOCAL_LOGV)
|
||||||
|
Log.v(TAG, "About to encrypt");
|
||||||
try {
|
try {
|
||||||
Apg.encrypt(getBaseContext(), // context
|
Apg.encrypt(getBaseContext(), // context
|
||||||
in, // input stream
|
in, // input stream
|
||||||
out, // output stream
|
out, // output stream
|
||||||
pArgs.getBoolean(arg.ARMORED_OUTPUT.name()), // ARMORED_OUTPUT
|
pArgs.getBoolean(arg.ARMORED_OUTPUT.name()), // ARMORED_OUTPUT
|
||||||
pubMasterKeys, // encryption keys
|
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
|
pArgs.getString(arg.PRIVATE_KEY_PASSPHRASE.name()), // signature passphrase
|
||||||
null, // progress
|
null, // progress
|
||||||
pArgs.getInt(arg.ENCRYPTION_ALGORYTHM.name()), // encryption
|
pArgs.getInt(arg.ENCRYPTION_ALGORYTHM.name()), // encryption
|
||||||
@ -451,27 +478,38 @@ public class ApgService extends Service {
|
|||||||
pArgs.getInt(arg.COMPRESSION.name()), // compression
|
pArgs.getInt(arg.COMPRESSION.name()), // compression
|
||||||
pArgs.getBoolean(arg.FORCE_V3_SIGNATURE.name()), // mPreferences.getForceV3Signatures(),
|
pArgs.getBoolean(arg.FORCE_V3_SIGNATURE.name()), // mPreferences.getForceV3Signatures(),
|
||||||
pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) // passPhrase
|
pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) // passPhrase
|
||||||
);
|
);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "Exception in encrypt");
|
Log.e(TAG, "Exception in encrypt");
|
||||||
String msg = e.getMessage();
|
String msg = e.getMessage();
|
||||||
if (msg.equals(getBaseContext().getString(R.string.error_noSignaturePassPhrase))) {
|
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.getStringArrayList(ret.ERRORS.name()).add(
|
||||||
pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_MISSING.shiftedOrdinal());
|
"Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " missing): "
|
||||||
} else if (msg.equals(getBaseContext().getString(R.string.error_couldNotExtractPrivateKey))) {
|
+ msg);
|
||||||
pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot encrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name() + " probably wrong): " + msg);
|
pReturn.putInt(ret.ERROR.name(),
|
||||||
pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.shiftedOrdinal());
|
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 {
|
} 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());
|
pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.shiftedOrdinal());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if( LOCAL_LOGV ) Log.v(TAG, "Encrypted");
|
if (LOCAL_LOGV)
|
||||||
if(isBlob) {
|
Log.v(TAG, "Encrypted");
|
||||||
|
if (isBlob) {
|
||||||
ContentResolver cr = getContentResolver();
|
ContentResolver cr = getContentResolver();
|
||||||
try {
|
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);
|
writeToOutputStream(new ByteArrayInputStream(out.toString().getBytes()), outStream);
|
||||||
outStream.close();
|
outStream.close();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -501,7 +539,8 @@ public class ApgService extends Service {
|
|||||||
ArrayList<String> fPrints = new ArrayList<String>();
|
ArrayList<String> fPrints = new ArrayList<String>();
|
||||||
ArrayList<String> ids = new ArrayList<String>();
|
ArrayList<String> ids = new ArrayList<String>();
|
||||||
while (cursor.moveToNext()) {
|
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)));
|
fPrints.add(Apg.getSmallFingerPrint(cursor.getLong(0)));
|
||||||
ids.add(cursor.getString(1));
|
ids.add(cursor.getString(1));
|
||||||
}
|
}
|
||||||
@ -533,14 +572,15 @@ public class ApgService extends Service {
|
|||||||
if (!prepareArgs("decrypt", pArgs, pReturn)) {
|
if (!prepareArgs("decrypt", pArgs, pReturn)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isBlob = pArgs.containsKey(arg.BLOB.name());
|
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());
|
.getString(arg.PRIVATE_KEY_PASSPHRASE.name());
|
||||||
|
|
||||||
InputStream inStream = null;
|
InputStream inStream = null;
|
||||||
if(isBlob) {
|
if (isBlob) {
|
||||||
ContentResolver cr = getContentResolver();
|
ContentResolver cr = getContentResolver();
|
||||||
try {
|
try {
|
||||||
inStream = cr.openInputStream(Uri.parse(pArgs.getString(arg.BLOB.name())));
|
inStream = cr.openInputStream(Uri.parse(pArgs.getString(arg.BLOB.name())));
|
||||||
@ -550,14 +590,15 @@ public class ApgService extends Service {
|
|||||||
} else {
|
} else {
|
||||||
inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes());
|
inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
InputData in = new InputData(inStream, 0); // XXX what size in second parameter?
|
InputData in = new InputData(inStream, 0); // XXX what size in second parameter?
|
||||||
OutputStream out = new ByteArrayOutputStream();
|
OutputStream out = new ByteArrayOutputStream();
|
||||||
if( LOCAL_LOGV ) Log.v(TAG, "About to decrypt");
|
if (LOCAL_LOGV)
|
||||||
|
Log.v(TAG, "About to decrypt");
|
||||||
try {
|
try {
|
||||||
Apg.decrypt(getBaseContext(), in, out, passphrase, null, // progress
|
Apg.decrypt(getBaseContext(), in, out, passphrase, null, // progress
|
||||||
pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null // symmetric
|
pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null // symmetric
|
||||||
);
|
);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "Exception in decrypt");
|
Log.e(TAG, "Exception in decrypt");
|
||||||
String msg = e.getMessage();
|
String msg = e.getMessage();
|
||||||
@ -565,25 +606,33 @@ public class ApgService extends Service {
|
|||||||
pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt: " + msg);
|
pReturn.getStringArrayList(ret.ERRORS.name()).add("Cannot decrypt: " + msg);
|
||||||
pReturn.putInt(ret.ERROR.name(), error.NO_MATCHING_SECRET_KEY.shiftedOrdinal());
|
pReturn.putInt(ret.ERROR.name(), error.NO_MATCHING_SECRET_KEY.shiftedOrdinal());
|
||||||
} else if (msg.equals(getBaseContext().getString(R.string.error_wrongPassPhrase))) {
|
} 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.getStringArrayList(ret.ERRORS.name()).add(
|
||||||
pReturn.putInt(ret.ERROR.name(), error.PRIVATE_KEY_PASSPHRASE_WRONG.shiftedOrdinal());
|
"Cannot decrypt (" + arg.PRIVATE_KEY_PASSPHRASE.name()
|
||||||
|
+ " wrong/missing): " + msg);
|
||||||
|
pReturn.putInt(ret.ERROR.name(),
|
||||||
|
error.PRIVATE_KEY_PASSPHRASE_WRONG.shiftedOrdinal());
|
||||||
} else {
|
} 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());
|
pReturn.putInt(ret.ERROR.name(), error.APG_FAILURE.shiftedOrdinal());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if( LOCAL_LOGV ) Log.v(TAG, "... decrypted");
|
if (LOCAL_LOGV)
|
||||||
|
Log.v(TAG, "... decrypted");
|
||||||
|
|
||||||
if(isBlob) {
|
if (isBlob) {
|
||||||
ContentResolver cr = getContentResolver();
|
ContentResolver cr = getContentResolver();
|
||||||
try {
|
try {
|
||||||
OutputStream outStream = cr.openOutputStream(Uri.parse(pArgs.getString(arg.BLOB.name())));
|
OutputStream outStream = cr.openOutputStream(Uri.parse(pArgs.getString(arg.BLOB
|
||||||
writeToOutputStream(new ByteArrayInputStream(out.toString().getBytes()), outStream);
|
.name())));
|
||||||
|
writeToOutputStream(new ByteArrayInputStream(out.toString().getBytes()),
|
||||||
|
outStream);
|
||||||
outStream.close();
|
outStream.close();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "... exception on writing blob", e);
|
Log.e(TAG, "... exception on writing blob", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pReturn.putString(ret.RESULT.name(), out.toString());
|
pReturn.putString(ret.RESULT.name(), out.toString());
|
||||||
}
|
}
|
@ -14,12 +14,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg;
|
package org.apg;
|
||||||
|
|
||||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||||
import org.spongycastle.openpgp.PGPException;
|
import org.spongycastle.openpgp.PGPException;
|
||||||
import org.spongycastle.openpgp.PGPPrivateKey;
|
import org.spongycastle.openpgp.PGPPrivateKey;
|
||||||
import org.spongycastle.openpgp.PGPSecretKey;
|
import org.spongycastle.openpgp.PGPSecretKey;
|
||||||
|
import org.apg.R;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
@ -38,7 +39,7 @@ public class AskForSecretKeyPassPhrase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Dialog createDialog(Activity context, long secretKeyId,
|
public static Dialog createDialog(Activity context, long secretKeyId,
|
||||||
PassPhraseCallbackInterface callback) {
|
PassPhraseCallbackInterface callback) {
|
||||||
AlertDialog.Builder alert = new AlertDialog.Builder(context);
|
AlertDialog.Builder alert = new AlertDialog.Builder(context);
|
||||||
|
|
||||||
alert.setTitle(R.string.title_authentication);
|
alert.setTitle(R.string.title_authentication);
|
||||||
@ -66,8 +67,8 @@ public class AskForSecretKeyPassPhrase {
|
|||||||
alert.setMessage(context.getString(R.string.passPhraseFor, userId));
|
alert.setMessage(context.getString(R.string.passPhraseFor, userId));
|
||||||
}
|
}
|
||||||
|
|
||||||
LayoutInflater inflater =
|
LayoutInflater inflater = (LayoutInflater) context
|
||||||
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
View view = inflater.inflate(R.layout.pass_phrase, null);
|
View view = inflater.inflate(R.layout.pass_phrase, null);
|
||||||
final EditText input = (EditText) view.findViewById(R.id.passPhrase);
|
final EditText input = (EditText) view.findViewById(R.id.passPhrase);
|
||||||
final EditText inputNotUsed = (EditText) view.findViewById(R.id.passPhraseAgain);
|
final EditText inputNotUsed = (EditText) view.findViewById(R.id.passPhraseAgain);
|
||||||
@ -76,42 +77,38 @@ public class AskForSecretKeyPassPhrase {
|
|||||||
alert.setView(view);
|
alert.setView(view);
|
||||||
|
|
||||||
final PassPhraseCallbackInterface cb = callback;
|
final PassPhraseCallbackInterface cb = callback;
|
||||||
alert.setPositiveButton(android.R.string.ok,
|
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||||
new DialogInterface.OnClickListener() {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
activity.removeDialog(Id.dialog.pass_phrase);
|
||||||
activity.removeDialog(Id.dialog.pass_phrase);
|
String passPhrase = "" + input.getText();
|
||||||
String passPhrase = "" + input.getText();
|
long keyId;
|
||||||
long keyId;
|
if (secretKey != null) {
|
||||||
if (secretKey != null) {
|
try {
|
||||||
try {
|
PGPPrivateKey testKey = secretKey.extractPrivateKey(
|
||||||
PGPPrivateKey testKey = secretKey.extractPrivateKey(passPhrase.toCharArray(),
|
passPhrase.toCharArray(), new BouncyCastleProvider());
|
||||||
new BouncyCastleProvider());
|
if (testKey == null) {
|
||||||
if (testKey == null) {
|
Toast.makeText(activity, R.string.error_couldNotExtractPrivateKey,
|
||||||
Toast.makeText(activity,
|
Toast.LENGTH_SHORT).show();
|
||||||
R.string.error_couldNotExtractPrivateKey,
|
return;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
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,
|
alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||||
new DialogInterface.OnClickListener() {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
activity.removeDialog(Id.dialog.pass_phrase);
|
||||||
activity.removeDialog(Id.dialog.pass_phrase);
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
return alert.create();
|
return alert.create();
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package org.thialfihar.android.apg;
|
package org.apg;
|
||||||
|
|
||||||
public class CachedPassPhrase {
|
public class CachedPassPhrase {
|
||||||
public final long timestamp;
|
public final long timestamp;
|
||||||
@ -11,14 +11,14 @@ public class CachedPassPhrase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int hc1 = (int)(this.timestamp & 0xffffffff);
|
int hc1 = (int) (this.timestamp & 0xffffffff);
|
||||||
int hc2 = (this.passPhrase == null ? 0 : this.passPhrase.hashCode());
|
int hc2 = (this.passPhrase == null ? 0 : this.passPhrase.hashCode());
|
||||||
return (hc1 + hc2) * hc2 + hc1;
|
return (hc1 + hc2) * hc2 + hc1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object other) {
|
public boolean equals(Object other) {
|
||||||
if (!(other instanceof CachedPassPhrase)) {
|
if (!(other instanceof CachedPassPhrase)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ public class CachedPassPhrase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "(" + timestamp + ", *******)";
|
return "(" + timestamp + ", *******)";
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,14 +14,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg;
|
package org.apg;
|
||||||
|
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
|
|
||||||
public final class Constants {
|
public final class Constants {
|
||||||
|
|
||||||
public static final String tag = "APG";
|
public static final String tag = "APG";
|
||||||
|
|
||||||
public static final class path {
|
public static final class path {
|
||||||
public static final String app_dir = Environment.getExternalStorageDirectory() + "/APG";
|
public static final String app_dir = Environment.getExternalStorageDirectory() + "/APG";
|
||||||
}
|
}
|
81
src/org/apg/DataDestination.java
Normal file
81
src/org/apg/DataDestination.java
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package org.thialfihar.android.apg;
|
package org.apg;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -7,7 +7,8 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
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.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@ -56,8 +57,8 @@ public class DataSource {
|
|||||||
return mData != null || mContentUri != null;
|
return mData != null || mContentUri != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputData getInputData(Context context, boolean withSize)
|
public InputData getInputData(Context context, boolean withSize) throws GeneralException,
|
||||||
throws GeneralException, FileNotFoundException, IOException {
|
FileNotFoundException, IOException {
|
||||||
InputStream in = null;
|
InputStream in = null;
|
||||||
long size = 0;
|
long size = 0;
|
||||||
|
|
||||||
@ -67,7 +68,8 @@ public class DataSource {
|
|||||||
String path = Uri.decode(mContentUri.toString().substring(7));
|
String path = Uri.decode(mContentUri.toString().substring(7));
|
||||||
if (path.startsWith(Environment.getExternalStorageDirectory().getAbsolutePath())) {
|
if (path.startsWith(Environment.getExternalStorageDirectory().getAbsolutePath())) {
|
||||||
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
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);
|
in = new FileInputStream(path);
|
@ -14,7 +14,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg;
|
package org.apg;
|
||||||
|
|
||||||
|
import org.apg.R;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
@ -41,18 +43,17 @@ public class FileDialog {
|
|||||||
|
|
||||||
public static interface OnClickListener {
|
public static interface OnClickListener {
|
||||||
public void onCancelClick();
|
public void onCancelClick();
|
||||||
|
|
||||||
public void onOkClick(String filename, boolean checkbox);
|
public void onOkClick(String filename, boolean checkbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AlertDialog build(Activity activity, String title, String message,
|
public static AlertDialog build(Activity activity, String title, String message,
|
||||||
String defaultFile, OnClickListener onClickListener,
|
String defaultFile, OnClickListener onClickListener, String fileManagerTitle,
|
||||||
String fileManagerTitle, String fileManagerButton,
|
String fileManagerButton, String checkboxText, int requestCode) {
|
||||||
String checkboxText,
|
|
||||||
int requestCode) {
|
|
||||||
// TODO: fileManagerTitle and fileManagerButton are deprecated, no use for them right now,
|
// 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
|
// but maybe the Intent now used will someday support them again, so leaving them in
|
||||||
LayoutInflater inflater =
|
LayoutInflater inflater = (LayoutInflater) activity
|
||||||
(LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
AlertDialog.Builder alert = new AlertDialog.Builder(activity);
|
AlertDialog.Builder alert = new AlertDialog.Builder(activity);
|
||||||
|
|
||||||
alert.setTitle(title);
|
alert.setTitle(title);
|
||||||
@ -87,22 +88,20 @@ public class FileDialog {
|
|||||||
final OnClickListener clickListener = onClickListener;
|
final OnClickListener clickListener = onClickListener;
|
||||||
|
|
||||||
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
boolean checked = false;
|
boolean checked = false;
|
||||||
if (mCheckBox.isEnabled()) {
|
if (mCheckBox.isEnabled()) {
|
||||||
checked = mCheckBox.isChecked();
|
checked = mCheckBox.isChecked();
|
||||||
}
|
}
|
||||||
clickListener.onOkClick(mFilename.getText().toString(),
|
clickListener.onOkClick(mFilename.getText().toString(), checked);
|
||||||
checked);
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
alert.setNegativeButton(android.R.string.cancel,
|
alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||||
new DialogInterface.OnClickListener() {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
clickListener.onCancelClick();
|
||||||
clickListener.onCancelClick();
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
return alert.create();
|
return alert.create();
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package org.thialfihar.android.apg;
|
package org.apg;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -56,9 +56,15 @@ public class HkpKeyServer extends KeyServer {
|
|||||||
private short mPort = 11371;
|
private short mPort = 11371;
|
||||||
|
|
||||||
// example:
|
// example:
|
||||||
// pub 2048R/<a href="/pks/lookup?op=get&search=0x887DF4BE9F5C9090">9F5C9090</a> 2009-08-17 <a href="/pks/lookup?op=vindex&search=0x887DF4BE9F5C9090">Jörg Runge <joerg@joergrunge.de></a>
|
// pub 2048R/<a href="/pks/lookup?op=get&search=0x887DF4BE9F5C9090">9F5C9090</a> 2009-08-17 <a
|
||||||
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);
|
// href="/pks/lookup?op=vindex&search=0x887DF4BE9F5C9090">Jörg Runge
|
||||||
public static Pattern USER_ID_LINE = Pattern.compile("^ +(.+)$", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
|
// <joerg@joergrunge.de></a>
|
||||||
|
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) {
|
public HkpKeyServer(String host) {
|
||||||
mHost = host;
|
mHost = host;
|
||||||
@ -119,7 +125,8 @@ public class HkpKeyServer extends KeyServer {
|
|||||||
|
|
||||||
// TODO: replace this with httpclient
|
// TODO: replace this with httpclient
|
||||||
@Override
|
@Override
|
||||||
List<KeyInfo> search(String query) throws QueryException, TooManyResponses, InsufficientQuery {
|
public List<KeyInfo> search(String query) throws QueryException, TooManyResponses,
|
||||||
|
InsufficientQuery {
|
||||||
Vector<KeyInfo> results = new Vector<KeyInfo>();
|
Vector<KeyInfo> results = new Vector<KeyInfo>();
|
||||||
|
|
||||||
if (query.length() < 3) {
|
if (query.length() < 3) {
|
||||||
@ -160,7 +167,8 @@ public class HkpKeyServer extends KeyServer {
|
|||||||
info.keyId = Apg.keyFromHex(matcher.group(3));
|
info.keyId = Apg.keyFromHex(matcher.group(3));
|
||||||
info.fingerPrint = Apg.getSmallFingerPrint(info.keyId);
|
info.fingerPrint = Apg.getSmallFingerPrint(info.keyId);
|
||||||
String chunks[] = matcher.group(4).split("-");
|
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<String>();
|
info.userIds = new Vector<String>();
|
||||||
if (matcher.group(5).startsWith("*** KEY")) {
|
if (matcher.group(5).startsWith("*** KEY")) {
|
||||||
info.revoked = matcher.group(5);
|
info.revoked = matcher.group(5);
|
||||||
@ -184,16 +192,17 @@ public class HkpKeyServer extends KeyServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String get(long keyId) throws QueryException {
|
public String get(long keyId) throws QueryException {
|
||||||
HttpClient client = new DefaultHttpClient();
|
HttpClient client = new DefaultHttpClient();
|
||||||
try {
|
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);
|
HttpResponse response = client.execute(get);
|
||||||
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
|
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
|
||||||
throw new QueryException("not found");
|
throw new QueryException("not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpEntity entity = response.getEntity();
|
HttpEntity entity = response.getEntity();
|
||||||
InputStream is = entity.getContent();
|
InputStream is = entity.getContent();
|
||||||
String data = readAll(is, EntityUtils.getContentCharSet(entity));
|
String data = readAll(is, EntityUtils.getContentCharSet(entity));
|
||||||
@ -206,7 +215,7 @@ public class HkpKeyServer extends KeyServer {
|
|||||||
} finally {
|
} finally {
|
||||||
client.getConnectionManager().shutdown();
|
client.getConnectionManager().shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,11 +224,11 @@ public class HkpKeyServer extends KeyServer {
|
|||||||
HttpClient client = new DefaultHttpClient();
|
HttpClient client = new DefaultHttpClient();
|
||||||
try {
|
try {
|
||||||
HttpPost post = new HttpPost("http://" + mHost + ":" + mPort + "/pks/add");
|
HttpPost post = new HttpPost("http://" + mHost + ":" + mPort + "/pks/add");
|
||||||
|
|
||||||
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
|
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
|
||||||
nameValuePairs.add(new BasicNameValuePair("keytext", armouredText));
|
nameValuePairs.add(new BasicNameValuePair("keytext", armouredText));
|
||||||
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
|
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
|
||||||
|
|
||||||
HttpResponse response = client.execute(post);
|
HttpResponse response = client.execute(post);
|
||||||
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
|
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
|
||||||
throw new AddKeyException();
|
throw new AddKeyException();
|
@ -1,4 +1,4 @@
|
|||||||
package org.thialfihar.android.apg;
|
package org.apg;
|
||||||
|
|
||||||
interface IApgService {
|
interface IApgService {
|
||||||
|
|
@ -14,14 +14,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg;
|
package org.apg;
|
||||||
|
|
||||||
import org.spongycastle.bcpg.CompressionAlgorithmTags;
|
import org.spongycastle.bcpg.CompressionAlgorithmTags;
|
||||||
|
|
||||||
public final class Id {
|
public final class Id {
|
||||||
|
|
||||||
public static final String TAG = "APG";
|
public static final String TAG = "APG";
|
||||||
|
|
||||||
public static final class menu {
|
public static final class menu {
|
||||||
public static final int export = 0x21070001;
|
public static final int export = 0x21070001;
|
||||||
public static final int delete = 0x21070002;
|
public static final int delete = 0x21070002;
|
@ -1,4 +1,4 @@
|
|||||||
package org.thialfihar.android.apg;
|
package org.apg;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
@ -6,7 +6,7 @@ public class InputData {
|
|||||||
private PositionAwareInputStream mInputStream;
|
private PositionAwareInputStream mInputStream;
|
||||||
private long mSize;
|
private long mSize;
|
||||||
|
|
||||||
InputData(InputStream inputStream, long size) {
|
public InputData(InputStream inputStream, long size) {
|
||||||
mInputStream = new PositionAwareInputStream(inputStream);
|
mInputStream = new PositionAwareInputStream(inputStream);
|
||||||
mSize = size;
|
mSize = size;
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package org.thialfihar.android.apg;
|
package org.apg;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -8,35 +8,39 @@ import java.util.Vector;
|
|||||||
public abstract class KeyServer {
|
public abstract class KeyServer {
|
||||||
static public class QueryException extends Exception {
|
static public class QueryException extends Exception {
|
||||||
private static final long serialVersionUID = 2703768928624654512L;
|
private static final long serialVersionUID = 2703768928624654512L;
|
||||||
|
|
||||||
public QueryException(String message) {
|
public QueryException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static public class TooManyResponses extends Exception {
|
static public class TooManyResponses extends Exception {
|
||||||
private static final long serialVersionUID = 2703768928624654513L;
|
private static final long serialVersionUID = 2703768928624654513L;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public class InsufficientQuery extends Exception {
|
static public class InsufficientQuery extends Exception {
|
||||||
private static final long serialVersionUID = 2703768928624654514L;
|
private static final long serialVersionUID = 2703768928624654514L;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public class AddKeyException extends Exception {
|
static public class AddKeyException extends Exception {
|
||||||
private static final long serialVersionUID = -507574859137295530L;
|
private static final long serialVersionUID = -507574859137295530L;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public class KeyInfo implements Serializable {
|
static public class KeyInfo implements Serializable {
|
||||||
private static final long serialVersionUID = -7797972113284992662L;
|
private static final long serialVersionUID = -7797972113284992662L;
|
||||||
Vector<String> userIds;
|
public Vector<String> userIds;
|
||||||
String revoked;
|
public String revoked;
|
||||||
Date date;
|
public Date date;
|
||||||
String fingerPrint;
|
public String fingerPrint;
|
||||||
long keyId;
|
public long keyId;
|
||||||
int size;
|
public int size;
|
||||||
String algorithm;
|
public String algorithm;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract List<KeyInfo> search(String query) throws QueryException, TooManyResponses, InsufficientQuery;
|
abstract List<KeyInfo> search(String query) throws QueryException, TooManyResponses,
|
||||||
|
InsufficientQuery;
|
||||||
|
|
||||||
abstract String get(long keyId) throws QueryException;
|
abstract String get(long keyId) throws QueryException;
|
||||||
|
|
||||||
abstract void add(String armouredText) throws AddKeyException;
|
abstract void add(String armouredText) throws AddKeyException;
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package org.thialfihar.android.apg;
|
package org.apg;
|
||||||
|
|
||||||
public class PausableThread extends Thread {
|
public class PausableThread extends Thread {
|
||||||
private boolean mPaused = false;
|
private boolean mPaused = false;
|
||||||
@ -22,8 +22,8 @@ public class PausableThread extends Thread {
|
|||||||
|
|
||||||
public void unpause() {
|
public void unpause() {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
mPaused = false;
|
mPaused = false;
|
||||||
notify();
|
notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package org.thialfihar.android.apg;
|
package org.apg;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
@ -1,4 +1,4 @@
|
|||||||
package org.thialfihar.android.apg;
|
package org.apg;
|
||||||
|
|
||||||
import org.spongycastle.bcpg.HashAlgorithmTags;
|
import org.spongycastle.bcpg.HashAlgorithmTags;
|
||||||
import org.spongycastle.openpgp.PGPEncryptedData;
|
import org.spongycastle.openpgp.PGPEncryptedData;
|
||||||
@ -15,17 +15,15 @@ public class Preferences {
|
|||||||
public static synchronized Preferences getPreferences(Context context) {
|
public static synchronized Preferences getPreferences(Context context) {
|
||||||
return getPreferences(context, false);
|
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) {
|
if (mPreferences == null || force_new) {
|
||||||
mPreferences = new Preferences(context);
|
mPreferences = new Preferences(context);
|
||||||
}
|
}
|
||||||
return mPreferences;
|
return mPreferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Preferences(Context context)
|
private Preferences(Context context) {
|
||||||
{
|
|
||||||
mSharedPreferences = context.getSharedPreferences("APG.main", Context.MODE_PRIVATE);
|
mSharedPreferences = context.getSharedPreferences("APG.main", Context.MODE_PRIVATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +55,7 @@ public class Preferences {
|
|||||||
|
|
||||||
public int getDefaultEncryptionAlgorithm() {
|
public int getDefaultEncryptionAlgorithm() {
|
||||||
return mSharedPreferences.getInt(Constants.pref.default_encryption_algorithm,
|
return mSharedPreferences.getInt(Constants.pref.default_encryption_algorithm,
|
||||||
PGPEncryptedData.AES_256);
|
PGPEncryptedData.AES_256);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDefaultEncryptionAlgorithm(int value) {
|
public void setDefaultEncryptionAlgorithm(int value) {
|
||||||
@ -68,7 +66,7 @@ public class Preferences {
|
|||||||
|
|
||||||
public int getDefaultHashAlgorithm() {
|
public int getDefaultHashAlgorithm() {
|
||||||
return mSharedPreferences.getInt(Constants.pref.default_hash_algorithm,
|
return mSharedPreferences.getInt(Constants.pref.default_hash_algorithm,
|
||||||
HashAlgorithmTags.SHA256);
|
HashAlgorithmTags.SHA256);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDefaultHashAlgorithm(int value) {
|
public void setDefaultHashAlgorithm(int value) {
|
||||||
@ -79,7 +77,7 @@ public class Preferences {
|
|||||||
|
|
||||||
public int getDefaultMessageCompression() {
|
public int getDefaultMessageCompression() {
|
||||||
return mSharedPreferences.getInt(Constants.pref.default_message_compression,
|
return mSharedPreferences.getInt(Constants.pref.default_message_compression,
|
||||||
Id.choice.compression.zlib);
|
Id.choice.compression.zlib);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDefaultMessageCompression(int value) {
|
public void setDefaultMessageCompression(int value) {
|
||||||
@ -90,7 +88,7 @@ public class Preferences {
|
|||||||
|
|
||||||
public int getDefaultFileCompression() {
|
public int getDefaultFileCompression() {
|
||||||
return mSharedPreferences.getInt(Constants.pref.default_file_compression,
|
return mSharedPreferences.getInt(Constants.pref.default_file_compression,
|
||||||
Id.choice.compression.none);
|
Id.choice.compression.none);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDefaultFileCompression(int value) {
|
public void setDefaultFileCompression(int value) {
|
||||||
@ -120,8 +118,7 @@ public class Preferences {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSeenChangeLog(String version) {
|
public boolean hasSeenChangeLog(String version) {
|
||||||
return mSharedPreferences.getBoolean(Constants.pref.has_seen_change_log + version,
|
return mSharedPreferences.getBoolean(Constants.pref.has_seen_change_log + version, false);
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHasSeenChangeLog(String version, boolean value) {
|
public void setHasSeenChangeLog(String version, boolean value) {
|
||||||
@ -142,7 +139,7 @@ public class Preferences {
|
|||||||
|
|
||||||
public String[] getKeyServers() {
|
public String[] getKeyServers() {
|
||||||
String rawData = mSharedPreferences.getString(Constants.pref.key_servers,
|
String rawData = mSharedPreferences.getString(Constants.pref.key_servers,
|
||||||
Constants.defaults.key_servers);
|
Constants.defaults.key_servers);
|
||||||
Vector<String> servers = new Vector<String>();
|
Vector<String> servers = new Vector<String>();
|
||||||
String chunks[] = rawData.split(",");
|
String chunks[] = rawData.split(",");
|
||||||
for (int i = 0; i < chunks.length; ++i) {
|
for (int i = 0; i < chunks.length; ++i) {
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg;
|
package org.apg;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
@ -14,10 +14,12 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg;
|
package org.apg;
|
||||||
|
|
||||||
public interface ProgressDialogUpdater {
|
public interface ProgressDialogUpdater {
|
||||||
void setProgress(String message, int current, int total);
|
void setProgress(String message, int current, int total);
|
||||||
|
|
||||||
void setProgress(int resourceId, int current, int total);
|
void setProgress(int resourceId, int current, int total);
|
||||||
|
|
||||||
void setProgress(int current, int total);
|
void setProgress(int current, int total);
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package org.thialfihar.android.apg;
|
package org.apg;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg.provider;
|
package org.apg.provider;
|
||||||
|
|
||||||
import android.provider.BaseColumns;
|
import android.provider.BaseColumns;
|
||||||
|
|
@ -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.ContentUris;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
@ -1,7 +1,7 @@
|
|||||||
package org.thialfihar.android.apg.provider;
|
package org.apg.provider;
|
||||||
|
|
||||||
import org.thialfihar.android.apg.ApgService;
|
import org.apg.ApgService;
|
||||||
import org.thialfihar.android.apg.Constants;
|
import org.apg.Constants;
|
||||||
|
|
||||||
import android.content.ContentProvider;
|
import android.content.ContentProvider;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
@ -14,13 +14,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg.provider;
|
package org.apg.provider;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import org.thialfihar.android.apg.Id;
|
import org.apg.Id;
|
||||||
|
|
||||||
import android.content.ContentProvider;
|
import android.content.ContentProvider;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
@ -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.PGPException;
|
||||||
import org.spongycastle.openpgp.PGPPublicKey;
|
import org.spongycastle.openpgp.PGPPublicKey;
|
||||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.spongycastle.openpgp.PGPSecretKey;
|
import org.spongycastle.openpgp.PGPSecretKey;
|
||||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
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.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg.provider;
|
package org.apg.provider;
|
||||||
|
|
||||||
import android.provider.BaseColumns;
|
import android.provider.BaseColumns;
|
||||||
|
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg.provider;
|
package org.apg.provider;
|
||||||
|
|
||||||
import android.provider.BaseColumns;
|
import android.provider.BaseColumns;
|
||||||
|
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg.provider;
|
package org.apg.provider;
|
||||||
|
|
||||||
import android.provider.BaseColumns;
|
import android.provider.BaseColumns;
|
||||||
|
|
461
src/org/apg/ui/BaseActivity.java
Normal file
461
src/org/apg/ui/BaseActivity.java
Normal file
@ -0,0 +1,461 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.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());
|
||||||
|
}
|
||||||
|
}
|
@ -14,13 +14,22 @@
|
|||||||
* limitations under the License.
|
* 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.jce.provider.BouncyCastleProvider;
|
||||||
import org.spongycastle.openpgp.PGPException;
|
import org.spongycastle.openpgp.PGPException;
|
||||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.thialfihar.android.apg.provider.DataProvider;
|
import org.apg.R;
|
||||||
import org.thialfihar.android.apg.utils.Compatibility;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
@ -14,15 +14,19 @@
|
|||||||
* limitations under the License.
|
* 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.PGPException;
|
||||||
import org.spongycastle.openpgp.PGPSecretKey;
|
import org.spongycastle.openpgp.PGPSecretKey;
|
||||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.thialfihar.android.apg.provider.Database;
|
import org.apg.R;
|
||||||
import org.thialfihar.android.apg.ui.widget.KeyEditor;
|
|
||||||
import org.thialfihar.android.apg.ui.widget.SectionView;
|
|
||||||
import org.thialfihar.android.apg.utils.IterableIterator;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
@ -104,8 +108,7 @@ public class EditKeyActivity extends BaseActivity implements OnClickListener {
|
|||||||
mSaveButton.setOnClickListener(this);
|
mSaveButton.setOnClickListener(this);
|
||||||
mDiscardButton.setOnClickListener(this);
|
mDiscardButton.setOnClickListener(this);
|
||||||
|
|
||||||
LayoutInflater inflater =
|
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
|
|
||||||
LinearLayout container = (LinearLayout) findViewById(R.id.container);
|
LinearLayout container = (LinearLayout) findViewById(R.id.container);
|
||||||
mUserIds = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false);
|
mUserIds = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false);
|
||||||
@ -124,8 +127,9 @@ public class EditKeyActivity extends BaseActivity implements OnClickListener {
|
|||||||
|
|
||||||
updatePassPhraseButtonText();
|
updatePassPhraseButtonText();
|
||||||
|
|
||||||
Toast.makeText(this, getString(R.string.warningMessage, getString(R.string.keyEditingIsBeta)),
|
Toast.makeText(this,
|
||||||
Toast.LENGTH_LONG).show();
|
getString(R.string.warningMessage, getString(R.string.keyEditingIsBeta)),
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getMasterKeyId() {
|
private long getMasterKeyId() {
|
||||||
@ -136,75 +140,72 @@ public class EditKeyActivity extends BaseActivity implements OnClickListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean havePassPhrase() {
|
public boolean havePassPhrase() {
|
||||||
return (!mCurrentPassPhrase.equals("")) ||
|
return (!mCurrentPassPhrase.equals(""))
|
||||||
(mNewPassPhrase != null && !mNewPassPhrase.equals(""));
|
|| (mNewPassPhrase != null && !mNewPassPhrase.equals(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
menu.add(0, Id.menu.option.preferences, 0, R.string.menu_preferences)
|
menu.add(0, Id.menu.option.preferences, 0, R.string.menu_preferences).setIcon(
|
||||||
.setIcon(android.R.drawable.ic_menu_preferences);
|
android.R.drawable.ic_menu_preferences);
|
||||||
menu.add(0, Id.menu.option.about, 1, R.string.menu_about)
|
menu.add(0, Id.menu.option.about, 1, R.string.menu_about).setIcon(
|
||||||
.setIcon(android.R.drawable.ic_menu_info_details);
|
android.R.drawable.ic_menu_info_details);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Dialog onCreateDialog(int id) {
|
protected Dialog onCreateDialog(int id) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case Id.dialog.new_pass_phrase: {
|
case Id.dialog.new_pass_phrase: {
|
||||||
AlertDialog.Builder alert = new AlertDialog.Builder(this);
|
AlertDialog.Builder alert = new AlertDialog.Builder(this);
|
||||||
|
|
||||||
if (havePassPhrase()) {
|
if (havePassPhrase()) {
|
||||||
alert.setTitle(R.string.title_changePassPhrase);
|
alert.setTitle(R.string.title_changePassPhrase);
|
||||||
} else {
|
} else {
|
||||||
alert.setTitle(R.string.title_setPassPhrase);
|
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 =
|
alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||||
(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
View view = inflater.inflate(R.layout.pass_phrase, null);
|
removeDialog(Id.dialog.new_pass_phrase);
|
||||||
final EditText input1 = (EditText) view.findViewById(R.id.passPhrase);
|
}
|
||||||
final EditText input2 = (EditText) view.findViewById(R.id.passPhraseAgain);
|
});
|
||||||
|
|
||||||
alert.setView(view);
|
return alert.create();
|
||||||
|
}
|
||||||
|
|
||||||
alert.setPositiveButton(android.R.string.ok,
|
default: {
|
||||||
new DialogInterface.OnClickListener() {
|
return super.onCreateDialog(id);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,8 +276,8 @@ public class EditKeyActivity extends BaseActivity implements OnClickListener {
|
|||||||
|
|
||||||
String error = data.getString(Apg.EXTRA_ERROR);
|
String error = data.getString(Apg.EXTRA_ERROR);
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
Toast.makeText(EditKeyActivity.this,
|
Toast.makeText(EditKeyActivity.this, getString(R.string.errorMessage, error),
|
||||||
getString(R.string.errorMessage, error), Toast.LENGTH_SHORT).show();
|
Toast.LENGTH_SHORT).show();
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(EditKeyActivity.this, R.string.keySaved, Toast.LENGTH_SHORT).show();
|
Toast.makeText(EditKeyActivity.this, R.string.keySaved, Toast.LENGTH_SHORT).show();
|
||||||
setResult(RESULT_OK);
|
setResult(RESULT_OK);
|
||||||
@ -285,7 +286,7 @@ public class EditKeyActivity extends BaseActivity implements OnClickListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updatePassPhraseButtonText() {
|
private void updatePassPhraseButtonText() {
|
||||||
mChangePassPhrase.setText(
|
mChangePassPhrase.setText(havePassPhrase() ? R.string.btn_changePassPhrase
|
||||||
havePassPhrase() ? R.string.btn_changePassPhrase : R.string.btn_setPassPhrase);
|
: R.string.btn_setPassPhrase);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,16 +14,24 @@
|
|||||||
* limitations under the License.
|
* 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.PGPException;
|
||||||
import org.spongycastle.openpgp.PGPPublicKey;
|
import org.spongycastle.openpgp.PGPPublicKey;
|
||||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.spongycastle.openpgp.PGPSecretKey;
|
import org.spongycastle.openpgp.PGPSecretKey;
|
||||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.thialfihar.android.apg.provider.DataProvider;
|
import org.apg.R;
|
||||||
import org.thialfihar.android.apg.utils.Choice;
|
|
||||||
import org.thialfihar.android.apg.utils.Compatibility;
|
|
||||||
|
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
@ -121,9 +129,9 @@ public class EncryptActivity extends BaseActivity {
|
|||||||
mSourcePrevious.setOnClickListener(new OnClickListener() {
|
mSourcePrevious.setOnClickListener(new OnClickListener() {
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
mSource.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this,
|
mSource.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this,
|
||||||
R.anim.push_right_in));
|
R.anim.push_right_in));
|
||||||
mSource.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this,
|
mSource.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this,
|
||||||
R.anim.push_right_out));
|
R.anim.push_right_out));
|
||||||
mSource.showPrevious();
|
mSource.showPrevious();
|
||||||
updateSource();
|
updateSource();
|
||||||
}
|
}
|
||||||
@ -133,9 +141,9 @@ public class EncryptActivity extends BaseActivity {
|
|||||||
OnClickListener nextSourceClickListener = new OnClickListener() {
|
OnClickListener nextSourceClickListener = new OnClickListener() {
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
mSource.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this,
|
mSource.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this,
|
||||||
R.anim.push_left_in));
|
R.anim.push_left_in));
|
||||||
mSource.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this,
|
mSource.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this,
|
||||||
R.anim.push_left_out));
|
R.anim.push_left_out));
|
||||||
mSource.showNext();
|
mSource.showNext();
|
||||||
updateSource();
|
updateSource();
|
||||||
}
|
}
|
||||||
@ -154,9 +162,9 @@ public class EncryptActivity extends BaseActivity {
|
|||||||
mModePrevious.setOnClickListener(new OnClickListener() {
|
mModePrevious.setOnClickListener(new OnClickListener() {
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
mMode.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this,
|
mMode.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this,
|
||||||
R.anim.push_right_in));
|
R.anim.push_right_in));
|
||||||
mMode.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this,
|
mMode.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this,
|
||||||
R.anim.push_right_out));
|
R.anim.push_right_out));
|
||||||
mMode.showPrevious();
|
mMode.showPrevious();
|
||||||
updateMode();
|
updateMode();
|
||||||
}
|
}
|
||||||
@ -165,9 +173,9 @@ public class EncryptActivity extends BaseActivity {
|
|||||||
OnClickListener nextModeClickListener = new OnClickListener() {
|
OnClickListener nextModeClickListener = new OnClickListener() {
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
mMode.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this,
|
mMode.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this,
|
||||||
R.anim.push_left_in));
|
R.anim.push_left_in));
|
||||||
mMode.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this,
|
mMode.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this,
|
||||||
R.anim.push_left_out));
|
R.anim.push_left_out));
|
||||||
mMode.showNext();
|
mMode.showNext();
|
||||||
updateMode();
|
updateMode();
|
||||||
}
|
}
|
||||||
@ -205,14 +213,14 @@ public class EncryptActivity extends BaseActivity {
|
|||||||
|
|
||||||
mFileCompression = (Spinner) findViewById(R.id.fileCompression);
|
mFileCompression = (Spinner) findViewById(R.id.fileCompression);
|
||||||
Choice[] choices = new Choice[] {
|
Choice[] choices = new Choice[] {
|
||||||
new Choice(Id.choice.compression.none, getString(R.string.choice_none) +
|
new Choice(Id.choice.compression.none, getString(R.string.choice_none) + " ("
|
||||||
" (" + getString(R.string.fast) + ")"),
|
+ getString(R.string.fast) + ")"),
|
||||||
new Choice(Id.choice.compression.zip, "ZIP (" + 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.zlib, "ZLIB (" + getString(R.string.fast) + ")"),
|
||||||
new Choice(Id.choice.compression.bzip2, "BZIP2 (" + getString(R.string.very_slow) + ")"),
|
new Choice(Id.choice.compression.bzip2, "BZIP2 (" + getString(R.string.very_slow)
|
||||||
};
|
+ ")"), };
|
||||||
ArrayAdapter<Choice> adapter =
|
ArrayAdapter<Choice> adapter = new ArrayAdapter<Choice>(this,
|
||||||
new ArrayAdapter<Choice>(this, android.R.layout.simple_spinner_item, choices);
|
android.R.layout.simple_spinner_item, choices);
|
||||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
mFileCompression.setAdapter(adapter);
|
mFileCompression.setAdapter(adapter);
|
||||||
|
|
||||||
@ -265,18 +273,18 @@ public class EncryptActivity extends BaseActivity {
|
|||||||
});
|
});
|
||||||
|
|
||||||
mIntent = getIntent();
|
mIntent = getIntent();
|
||||||
if (Apg.Intent.ENCRYPT.equals(mIntent.getAction()) ||
|
if (Apg.Intent.ENCRYPT.equals(mIntent.getAction())
|
||||||
Apg.Intent.ENCRYPT_FILE.equals(mIntent.getAction()) ||
|
|| Apg.Intent.ENCRYPT_FILE.equals(mIntent.getAction())
|
||||||
Apg.Intent.ENCRYPT_AND_RETURN.equals(mIntent.getAction()) ||
|
|| Apg.Intent.ENCRYPT_AND_RETURN.equals(mIntent.getAction())
|
||||||
Apg.Intent.GENERATE_SIGNATURE.equals(mIntent.getAction())) {
|
|| Apg.Intent.GENERATE_SIGNATURE.equals(mIntent.getAction())) {
|
||||||
mContentUri = mIntent.getData();
|
mContentUri = mIntent.getData();
|
||||||
Bundle extras = mIntent.getExtras();
|
Bundle extras = mIntent.getExtras();
|
||||||
if (extras == null) {
|
if (extras == null) {
|
||||||
extras = new Bundle();
|
extras = new Bundle();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Apg.Intent.ENCRYPT_AND_RETURN.equals(mIntent.getAction()) ||
|
if (Apg.Intent.ENCRYPT_AND_RETURN.equals(mIntent.getAction())
|
||||||
Apg.Intent.GENERATE_SIGNATURE.equals(mIntent.getAction())) {
|
|| Apg.Intent.GENERATE_SIGNATURE.equals(mIntent.getAction())) {
|
||||||
mReturnResult = true;
|
mReturnResult = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,9 +349,9 @@ public class EncryptActivity extends BaseActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Apg.Intent.ENCRYPT.equals(mIntent.getAction()) ||
|
if (Apg.Intent.ENCRYPT.equals(mIntent.getAction())
|
||||||
Apg.Intent.ENCRYPT_AND_RETURN.equals(mIntent.getAction()) ||
|
|| Apg.Intent.ENCRYPT_AND_RETURN.equals(mIntent.getAction())
|
||||||
Apg.Intent.GENERATE_SIGNATURE.equals(mIntent.getAction())) {
|
|| Apg.Intent.GENERATE_SIGNATURE.equals(mIntent.getAction())) {
|
||||||
if (textData != null) {
|
if (textData != null) {
|
||||||
mMessage.setText(textData);
|
mMessage.setText(textData);
|
||||||
}
|
}
|
||||||
@ -385,11 +393,9 @@ public class EncryptActivity extends BaseActivity {
|
|||||||
|
|
||||||
updateButtons();
|
updateButtons();
|
||||||
|
|
||||||
if (mReturnResult &&
|
if (mReturnResult
|
||||||
(mMessage.getText().length() > 0 || mData != null || mContentUri != null) &&
|
&& (mMessage.getText().length() > 0 || mData != null || mContentUri != null)
|
||||||
((mEncryptionKeyIds != null &&
|
&& ((mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0) || getSecretKeyId() != 0)) {
|
||||||
mEncryptionKeyIds.length > 0) ||
|
|
||||||
getSecretKeyId() != 0)) {
|
|
||||||
encryptClicked();
|
encryptClicked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -420,39 +426,69 @@ public class EncryptActivity extends BaseActivity {
|
|||||||
|
|
||||||
private void updateSource() {
|
private void updateSource() {
|
||||||
switch (mSource.getCurrentView().getId()) {
|
switch (mSource.getCurrentView().getId()) {
|
||||||
case R.id.sourceFile: {
|
case R.id.sourceFile: {
|
||||||
mSourceLabel.setText(R.string.label_file);
|
mSourceLabel.setText(R.string.label_file);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case R.id.sourceMessage: {
|
case R.id.sourceMessage: {
|
||||||
mSourceLabel.setText(R.string.label_message);
|
mSourceLabel.setText(R.string.label_message);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateButtons();
|
updateButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateButtons() {
|
private void updateButtons() {
|
||||||
switch (mSource.getCurrentView().getId()) {
|
switch (mSource.getCurrentView().getId()) {
|
||||||
case R.id.sourceFile: {
|
case R.id.sourceFile: {
|
||||||
mEncryptToClipboardButton.setVisibility(View.INVISIBLE);
|
mEncryptToClipboardButton.setVisibility(View.INVISIBLE);
|
||||||
mEncryptButton.setText(R.string.btn_encrypt);
|
mEncryptButton.setText(R.string.btn_encrypt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case R.id.sourceMessage: {
|
case R.id.sourceMessage: {
|
||||||
mSourceLabel.setText(R.string.label_message);
|
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) {
|
if (mReturnResult) {
|
||||||
mEncryptToClipboardButton.setVisibility(View.INVISIBLE);
|
mEncryptButton.setText(R.string.btn_encrypt);
|
||||||
} else {
|
} 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) {
|
if (mReturnResult) {
|
||||||
mEncryptButton.setText(R.string.btn_encrypt);
|
mEncryptButton.setText(R.string.btn_encrypt);
|
||||||
} else {
|
} else {
|
||||||
@ -461,62 +497,32 @@ public class EncryptActivity extends BaseActivity {
|
|||||||
mEncryptButton.setEnabled(true);
|
mEncryptButton.setEnabled(true);
|
||||||
mEncryptToClipboardButton.setText(R.string.btn_encryptToClipboard);
|
mEncryptToClipboardButton.setText(R.string.btn_encryptToClipboard);
|
||||||
mEncryptToClipboardButton.setEnabled(true);
|
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: {
|
default: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateMode() {
|
private void updateMode() {
|
||||||
switch (mMode.getCurrentView().getId()) {
|
switch (mMode.getCurrentView().getId()) {
|
||||||
case R.id.modeAsymmetric: {
|
case R.id.modeAsymmetric: {
|
||||||
mModeLabel.setText(R.string.label_asymmetric);
|
mModeLabel.setText(R.string.label_asymmetric);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case R.id.modeSymmetric: {
|
case R.id.modeSymmetric: {
|
||||||
mModeLabel.setText(R.string.label_symmetric);
|
mModeLabel.setText(R.string.label_symmetric);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateButtons();
|
updateButtons();
|
||||||
}
|
}
|
||||||
@ -550,9 +556,10 @@ public class EncryptActivity extends BaseActivity {
|
|||||||
if (!mInputFilename.startsWith("content")) {
|
if (!mInputFilename.startsWith("content")) {
|
||||||
File file = new File(mInputFilename);
|
File file = new File(mInputFilename);
|
||||||
if (!file.exists() || !file.isFile()) {
|
if (!file.exists() || !file.isFile()) {
|
||||||
Toast.makeText(this, getString(R.string.errorMessage,
|
Toast.makeText(
|
||||||
getString(R.string.error_fileNotFound)),
|
this,
|
||||||
Toast.LENGTH_SHORT).show();
|
getString(R.string.errorMessage, getString(R.string.error_fileNotFound)),
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -582,8 +589,8 @@ public class EncryptActivity extends BaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!encryptIt && getSecretKeyId() == 0) {
|
if (!encryptIt && getSecretKeyId() == 0) {
|
||||||
Toast.makeText(this, R.string.selectEncryptionOrSignatureKey,
|
Toast.makeText(this, R.string.selectEncryptionOrSignatureKey, Toast.LENGTH_SHORT)
|
||||||
Toast.LENGTH_SHORT).show();
|
.show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,55 +673,49 @@ public class EncryptActivity extends BaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mGenerateSignature) {
|
if (mGenerateSignature) {
|
||||||
Apg.generateSignature(this, in, out, useAsciiArmour, mDataSource.isBinary(),
|
Apg.generateSignature(this, in, out, useAsciiArmour, mDataSource.isBinary(),
|
||||||
getSecretKeyId(),
|
getSecretKeyId(), Apg.getCachedPassPhrase(getSecretKeyId()),
|
||||||
Apg.getCachedPassPhrase(getSecretKeyId()),
|
mPreferences.getDefaultHashAlgorithm(),
|
||||||
mPreferences.getDefaultHashAlgorithm(),
|
mPreferences.getForceV3Signatures(), this);
|
||||||
mPreferences.getForceV3Signatures(),
|
|
||||||
this);
|
|
||||||
} else if (signOnly) {
|
} else if (signOnly) {
|
||||||
Apg.signText(this, in, out, getSecretKeyId(),
|
Apg.signText(this, in, out, getSecretKeyId(),
|
||||||
Apg.getCachedPassPhrase(getSecretKeyId()),
|
Apg.getCachedPassPhrase(getSecretKeyId()),
|
||||||
mPreferences.getDefaultHashAlgorithm(),
|
mPreferences.getDefaultHashAlgorithm(),
|
||||||
mPreferences.getForceV3Signatures(),
|
mPreferences.getForceV3Signatures(), this);
|
||||||
this);
|
|
||||||
} else {
|
} else {
|
||||||
Apg.encrypt(this, in, out, useAsciiArmour,
|
Apg.encrypt(this, in, out, useAsciiArmour, encryptionKeyIds, signatureKeyId,
|
||||||
encryptionKeyIds, signatureKeyId,
|
Apg.getCachedPassPhrase(signatureKeyId), this,
|
||||||
Apg.getCachedPassPhrase(signatureKeyId), this,
|
mPreferences.getDefaultEncryptionAlgorithm(),
|
||||||
mPreferences.getDefaultEncryptionAlgorithm(),
|
mPreferences.getDefaultHashAlgorithm(), compressionId,
|
||||||
mPreferences.getDefaultHashAlgorithm(),
|
mPreferences.getForceV3Signatures(), passPhrase);
|
||||||
compressionId,
|
|
||||||
mPreferences.getForceV3Signatures(),
|
|
||||||
passPhrase);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out.close();
|
out.close();
|
||||||
if (mEncryptTarget != Id.target.file) {
|
if (mEncryptTarget != Id.target.file) {
|
||||||
|
|
||||||
if(out instanceof ByteArrayOutputStream) {
|
if (out instanceof ByteArrayOutputStream) {
|
||||||
if (useAsciiArmour) {
|
if (useAsciiArmour) {
|
||||||
String extraData = new String(((ByteArrayOutputStream)out).toByteArray());
|
String extraData = new String(((ByteArrayOutputStream) out).toByteArray());
|
||||||
if (mGenerateSignature) {
|
if (mGenerateSignature) {
|
||||||
data.putString(Apg.EXTRA_SIGNATURE_TEXT, extraData);
|
data.putString(Apg.EXTRA_SIGNATURE_TEXT, extraData);
|
||||||
} else {
|
} else {
|
||||||
data.putString(Apg.EXTRA_ENCRYPTED_MESSAGE, extraData);
|
data.putString(Apg.EXTRA_ENCRYPTED_MESSAGE, extraData);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byte extraData[] = ((ByteArrayOutputStream)out).toByteArray();
|
byte extraData[] = ((ByteArrayOutputStream) out).toByteArray();
|
||||||
if (mGenerateSignature) {
|
if (mGenerateSignature) {
|
||||||
data.putByteArray(Apg.EXTRA_SIGNATURE_DATA, extraData);
|
data.putByteArray(Apg.EXTRA_SIGNATURE_DATA, extraData);
|
||||||
} else {
|
} else {
|
||||||
data.putByteArray(Apg.EXTRA_ENCRYPTED_DATA, extraData);
|
data.putByteArray(Apg.EXTRA_ENCRYPTED_DATA, extraData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(out instanceof FileOutputStream) {
|
} else if (out instanceof FileOutputStream) {
|
||||||
String fileName = mDataDestination.getStreamFilename();
|
String fileName = mDataDestination.getStreamFilename();
|
||||||
String uri = "content://" + DataProvider.AUTHORITY + "/data/" + fileName;
|
String uri = "content://" + DataProvider.AUTHORITY + "/data/" + fileName;
|
||||||
data.putString(Apg.EXTRA_RESULT_URI, uri);
|
data.putString(Apg.EXTRA_RESULT_URI, uri);
|
||||||
} else {
|
} else {
|
||||||
throw new Apg.GeneralException("No output-data found.");
|
throw new Apg.GeneralException("No output-data found.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
error = "" + e;
|
error = "" + e;
|
||||||
@ -746,8 +747,8 @@ public class EncryptActivity extends BaseActivity {
|
|||||||
} else if (mEncryptionKeyIds.length == 1) {
|
} else if (mEncryptionKeyIds.length == 1) {
|
||||||
mSelectKeysButton.setText(R.string.oneKeySelected);
|
mSelectKeysButton.setText(R.string.oneKeySelected);
|
||||||
} else {
|
} else {
|
||||||
mSelectKeysButton.setText("" + mEncryptionKeyIds.length + " " +
|
mSelectKeysButton.setText("" + mEncryptionKeyIds.length + " "
|
||||||
getResources().getString(R.string.nKeysSelected));
|
+ getResources().getString(R.string.nKeysSelected));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getSecretKeyId() == 0) {
|
if (getSecretKeyId() == 0) {
|
||||||
@ -788,7 +789,7 @@ public class EncryptActivity extends BaseActivity {
|
|||||||
keyIds.add(mEncryptionKeyIds[i]);
|
keyIds.add(mEncryptionKeyIds[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
long [] initialKeyIds = null;
|
long[] initialKeyIds = null;
|
||||||
if (keyIds.size() > 0) {
|
if (keyIds.size() > 0) {
|
||||||
initialKeyIds = new long[keyIds.size()];
|
initialKeyIds = new long[keyIds.size()];
|
||||||
for (int i = 0; i < keyIds.size(); ++i) {
|
for (int i = 0; i < keyIds.size(); ++i) {
|
||||||
@ -807,60 +808,60 @@ public class EncryptActivity extends BaseActivity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
case Id.request.filename: {
|
case Id.request.filename: {
|
||||||
if (resultCode == RESULT_OK && data != null) {
|
if (resultCode == RESULT_OK && data != null) {
|
||||||
String filename = data.getDataString();
|
String filename = data.getDataString();
|
||||||
if (filename != null) {
|
if (filename != null) {
|
||||||
// Get rid of URI prefix:
|
// Get rid of URI prefix:
|
||||||
if (filename.startsWith("file://")) {
|
if (filename.startsWith("file://")) {
|
||||||
filename = filename.substring(7);
|
filename = filename.substring(7);
|
||||||
}
|
|
||||||
// replace %20 and so on
|
|
||||||
filename = Uri.decode(filename);
|
|
||||||
|
|
||||||
mFilename.setText(filename);
|
|
||||||
}
|
}
|
||||||
|
// replace %20 and so on
|
||||||
|
filename = Uri.decode(filename);
|
||||||
|
|
||||||
|
mFilename.setText(filename);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case Id.request.output_filename: {
|
case Id.request.output_filename: {
|
||||||
if (resultCode == RESULT_OK && data != null) {
|
if (resultCode == RESULT_OK && data != null) {
|
||||||
String filename = data.getDataString();
|
String filename = data.getDataString();
|
||||||
if (filename != null) {
|
if (filename != null) {
|
||||||
// Get rid of URI prefix:
|
// Get rid of URI prefix:
|
||||||
if (filename.startsWith("file://")) {
|
if (filename.startsWith("file://")) {
|
||||||
filename = filename.substring(7);
|
filename = filename.substring(7);
|
||||||
}
|
|
||||||
// replace %20 and so on
|
|
||||||
filename = Uri.decode(filename);
|
|
||||||
|
|
||||||
FileDialog.setFilename(filename);
|
|
||||||
}
|
}
|
||||||
}
|
// replace %20 and so on
|
||||||
return;
|
filename = Uri.decode(filename);
|
||||||
}
|
|
||||||
|
|
||||||
case Id.request.secret_keys: {
|
FileDialog.setFilename(filename);
|
||||||
if (resultCode == RESULT_OK) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
}
|
}
|
||||||
updateView();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case Id.request.public_keys: {
|
case Id.request.secret_keys: {
|
||||||
if (resultCode == RESULT_OK) {
|
if (resultCode == RESULT_OK) {
|
||||||
Bundle bundle = data.getExtras();
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
mEncryptionKeyIds = bundle.getLongArray(Apg.EXTRA_SELECTION);
|
|
||||||
}
|
|
||||||
updateView();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
updateView();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
case Id.request.public_keys: {
|
||||||
break;
|
if (resultCode == RESULT_OK) {
|
||||||
|
Bundle bundle = data.getExtras();
|
||||||
|
mEncryptionKeyIds = bundle.getLongArray(Apg.EXTRA_SELECTION);
|
||||||
}
|
}
|
||||||
|
updateView();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
@ -875,88 +876,82 @@ public class EncryptActivity extends BaseActivity {
|
|||||||
Bundle data = msg.getData();
|
Bundle data = msg.getData();
|
||||||
String error = data.getString(Apg.EXTRA_ERROR);
|
String error = data.getString(Apg.EXTRA_ERROR);
|
||||||
if (error != null) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
switch (mEncryptTarget) {
|
switch (mEncryptTarget) {
|
||||||
case Id.target.clipboard: {
|
case Id.target.clipboard: {
|
||||||
String message = data.getString(Apg.EXTRA_ENCRYPTED_MESSAGE);
|
String message = data.getString(Apg.EXTRA_ENCRYPTED_MESSAGE);
|
||||||
Compatibility.copyToClipboard(this, message);
|
Compatibility.copyToClipboard(this, message);
|
||||||
Toast.makeText(this, R.string.encryptionToClipboardSuccessful,
|
Toast.makeText(this, R.string.encryptionToClipboardSuccessful, Toast.LENGTH_SHORT)
|
||||||
Toast.LENGTH_SHORT).show();
|
.show();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Id.target.email: {
|
||||||
|
if (mReturnResult) {
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.putExtras(data);
|
||||||
|
setResult(RESULT_OK, intent);
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Id.target.email: {
|
String message = data.getString(Apg.EXTRA_ENCRYPTED_MESSAGE);
|
||||||
if (mReturnResult) {
|
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
|
||||||
Intent intent = new Intent();
|
emailIntent.setType("text/plain; charset=utf-8");
|
||||||
intent.putExtras(data);
|
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, message);
|
||||||
setResult(RESULT_OK, intent);
|
if (mSubject != null) {
|
||||||
finish();
|
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, mSubject);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
if (mSendTo != null) {
|
||||||
case Id.target.file: {
|
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] { mSendTo });
|
||||||
Toast.makeText(this, R.string.encryptionSuccessful, Toast.LENGTH_SHORT).show();
|
|
||||||
if (mDeleteAfter.isChecked()) {
|
|
||||||
setDeleteFile(mInputFilename);
|
|
||||||
showDialog(Id.dialog.delete_file);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
EncryptActivity.this.startActivity(Intent.createChooser(emailIntent,
|
||||||
|
getString(R.string.title_sendEmail)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
case Id.target.file: {
|
||||||
// shouldn't happen
|
Toast.makeText(this, R.string.encryptionSuccessful, Toast.LENGTH_SHORT).show();
|
||||||
break;
|
if (mDeleteAfter.isChecked()) {
|
||||||
|
setDeleteFile(mInputFilename);
|
||||||
|
showDialog(Id.dialog.delete_file);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
// shouldn't happen
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Dialog onCreateDialog(int id) {
|
protected Dialog onCreateDialog(int id) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case Id.dialog.output_filename: {
|
case Id.dialog.output_filename: {
|
||||||
return FileDialog.build(this, getString(R.string.title_encryptToFile),
|
return FileDialog.build(this, getString(R.string.title_encryptToFile),
|
||||||
getString(R.string.specifyFileToEncryptTo),
|
getString(R.string.specifyFileToEncryptTo), mOutputFilename,
|
||||||
mOutputFilename,
|
new FileDialog.OnClickListener() {
|
||||||
new FileDialog.OnClickListener() {
|
public void onOkClick(String filename, boolean checked) {
|
||||||
public void onOkClick(String filename, boolean checked) {
|
removeDialog(Id.dialog.output_filename);
|
||||||
removeDialog(Id.dialog.output_filename);
|
mOutputFilename = filename;
|
||||||
mOutputFilename = filename;
|
encryptStart();
|
||||||
encryptStart();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void onCancelClick() {
|
public void onCancelClick() {
|
||||||
removeDialog(Id.dialog.output_filename);
|
removeDialog(Id.dialog.output_filename);
|
||||||
}
|
}
|
||||||
},
|
}, getString(R.string.filemanager_titleSave),
|
||||||
getString(R.string.filemanager_titleSave),
|
getString(R.string.filemanager_btnSave), null, Id.request.output_filename);
|
||||||
getString(R.string.filemanager_btnSave),
|
}
|
||||||
null,
|
|
||||||
Id.request.output_filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.onCreateDialog(id);
|
return super.onCreateDialog(id);
|
@ -1,4 +1,4 @@
|
|||||||
package org.thialfihar.android.apg;
|
package org.apg.ui;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
@ -6,7 +6,10 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Vector;
|
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.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
@ -1,11 +1,16 @@
|
|||||||
package org.thialfihar.android.apg;
|
package org.apg.ui;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
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.PGPKeyRing;
|
||||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.thialfihar.android.apg.KeyServer.QueryException;
|
import org.apg.R;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
@ -14,14 +14,20 @@
|
|||||||
* limitations under the License.
|
* 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.PGPException;
|
||||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.thialfihar.android.apg.provider.KeyRings;
|
import org.apg.R;
|
||||||
import org.thialfihar.android.apg.provider.Keys;
|
|
||||||
import org.thialfihar.android.apg.provider.UserIds;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
@ -14,13 +14,15 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg;
|
package org.apg.ui;
|
||||||
|
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import org.thialfihar.android.apg.ui.widget.Editor;
|
import org.apg.Apg;
|
||||||
import org.thialfihar.android.apg.ui.widget.Editor.EditorListener;
|
import org.apg.ui.widget.Editor;
|
||||||
import org.thialfihar.android.apg.ui.widget.KeyServerEditor;
|
import org.apg.ui.widget.KeyServerEditor;
|
||||||
|
import org.apg.ui.widget.Editor.EditorListener;
|
||||||
|
import org.apg.R;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
@ -1,12 +1,17 @@
|
|||||||
package org.thialfihar.android.apg;
|
package org.apg.ui;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import org.thialfihar.android.apg.KeyServer.InsufficientQuery;
|
import org.apg.Apg;
|
||||||
import org.thialfihar.android.apg.KeyServer.KeyInfo;
|
import org.apg.Constants;
|
||||||
import org.thialfihar.android.apg.KeyServer.QueryException;
|
import org.apg.HkpKeyServer;
|
||||||
import org.thialfihar.android.apg.KeyServer.TooManyResponses;
|
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.Activity;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
@ -14,11 +14,15 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg;
|
package org.apg.ui;
|
||||||
|
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import org.apg.Apg;
|
||||||
|
import org.apg.Preferences;
|
||||||
|
import org.apg.R;
|
||||||
|
|
||||||
import android.app.ListActivity;
|
import android.app.ListActivity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
@ -14,14 +14,20 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg;
|
package org.apg.ui;
|
||||||
|
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
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.spongycastle.jce.provider.BouncyCastleProvider;
|
||||||
import org.thialfihar.android.apg.provider.Accounts;
|
import org.apg.R;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
@ -14,11 +14,20 @@
|
|||||||
* limitations under the License.
|
* 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.bcpg.HashAlgorithmTags;
|
||||||
import org.spongycastle.openpgp.PGPEncryptedData;
|
import org.spongycastle.openpgp.PGPEncryptedData;
|
||||||
import org.thialfihar.android.apg.ui.widget.IntegerListPreference;
|
import org.apg.R;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
@ -14,9 +14,18 @@
|
|||||||
* limitations under the License.
|
* 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.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
|
import org.apg.R;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
@ -14,7 +14,19 @@
|
|||||||
* limitations under the License.
|
* 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.app.Dialog;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
@ -14,10 +14,16 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg;
|
package org.apg.ui;
|
||||||
|
|
||||||
import java.util.Vector;
|
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.app.SearchManager;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
@ -14,13 +14,17 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg;
|
package org.apg.ui;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import org.thialfihar.android.apg.provider.KeyRings;
|
import org.apg.Apg;
|
||||||
import org.thialfihar.android.apg.provider.Keys;
|
import org.apg.Id;
|
||||||
import org.thialfihar.android.apg.provider.UserIds;
|
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.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
@ -14,7 +14,13 @@
|
|||||||
* limitations under the License.
|
* 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.app.SearchManager;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
@ -1,10 +1,14 @@
|
|||||||
package org.thialfihar.android.apg;
|
package org.apg.ui;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import org.thialfihar.android.apg.provider.KeyRings;
|
import org.apg.Apg;
|
||||||
import org.thialfihar.android.apg.provider.Keys;
|
import org.apg.Id;
|
||||||
import org.thialfihar.android.apg.provider.UserIds;
|
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.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
@ -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.PGPKeyRing;
|
||||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
|
import org.apg.R;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
@ -1,10 +1,19 @@
|
|||||||
package org.thialfihar.android.apg;
|
package org.apg.ui;
|
||||||
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.NoSuchProviderException;
|
import java.security.NoSuchProviderException;
|
||||||
import java.security.SignatureException;
|
import java.security.SignatureException;
|
||||||
import java.util.Iterator;
|
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.jce.provider.BouncyCastleProvider;
|
||||||
import org.spongycastle.openpgp.PGPException;
|
import org.spongycastle.openpgp.PGPException;
|
||||||
import org.spongycastle.openpgp.PGPPrivateKey;
|
import org.spongycastle.openpgp.PGPPrivateKey;
|
||||||
@ -16,6 +25,7 @@ import org.spongycastle.openpgp.PGPSignatureGenerator;
|
|||||||
import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
|
import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
|
||||||
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
|
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
|
||||||
import org.spongycastle.openpgp.PGPUtil;
|
import org.spongycastle.openpgp.PGPUtil;
|
||||||
|
import org.apg.R;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg.ui.widget;
|
package org.apg.ui.widget;
|
||||||
|
|
||||||
public interface Editor {
|
public interface Editor {
|
||||||
public interface EditorListener {
|
public interface EditorListener {
|
@ -14,7 +14,7 @@
|
|||||||
* the License.
|
* the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg.ui.widget;
|
package org.apg.ui.widget;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.preference.ListPreference;
|
import android.preference.ListPreference;
|
@ -14,14 +14,14 @@
|
|||||||
* limitations under the License.
|
* 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.PGPPublicKey;
|
||||||
import org.spongycastle.openpgp.PGPSecretKey;
|
import org.spongycastle.openpgp.PGPSecretKey;
|
||||||
import org.thialfihar.android.apg.Apg;
|
import org.apg.R;
|
||||||
import org.thialfihar.android.apg.Id;
|
|
||||||
import org.thialfihar.android.apg.R;
|
|
||||||
import org.thialfihar.android.apg.utils.Choice;
|
|
||||||
|
|
||||||
import android.app.DatePickerDialog;
|
import android.app.DatePickerDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
@ -14,9 +14,9 @@
|
|||||||
* limitations under the License.
|
* 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.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
@ -14,15 +14,15 @@
|
|||||||
* limitations under the License.
|
* 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.PGPException;
|
||||||
import org.spongycastle.openpgp.PGPSecretKey;
|
import org.spongycastle.openpgp.PGPSecretKey;
|
||||||
import org.thialfihar.android.apg.Apg;
|
import org.apg.R;
|
||||||
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 android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
@ -14,12 +14,12 @@
|
|||||||
* limitations under the License.
|
* 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.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.thialfihar.android.apg.R;
|
import org.apg.R;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
@ -14,10 +14,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg.utils;
|
package org.apg.util;
|
||||||
|
|
||||||
import org.thialfihar.android.apg.IApgService;
|
import org.apg.util.ApgConInterface.OnCallFinishListener;
|
||||||
import org.thialfihar.android.apg.utils.ApgConInterface.OnCallFinishListener;
|
import org.apg.IApgService;
|
||||||
|
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
@ -1,4 +1,4 @@
|
|||||||
package org.thialfihar.android.apg.utils;
|
package org.apg.util;
|
||||||
|
|
||||||
public interface ApgConInterface {
|
public interface ApgConInterface {
|
||||||
public static interface OnCallFinishListener {
|
public static interface OnCallFinishListener {
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg.utils;
|
package org.apg.util;
|
||||||
|
|
||||||
public class Choice {
|
public class Choice {
|
||||||
private String mName;
|
private String mName;
|
@ -1,4 +1,4 @@
|
|||||||
package org.thialfihar.android.apg.utils;
|
package org.apg.util;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.thialfihar.android.apg.utils;
|
package org.apg.util;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
@ -1,464 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.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());
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user