aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--org_apg/libs/sc-bzip2-1.47.0.2.jarbin0 -> 26285 bytes
-rw-r--r--org_apg/libs/sc-light-jdk15on-1.47.0.2.jar (renamed from org_apg/libs/scprov-jdk15on-1.47.0.1.jar)bin2468697 -> 1482715 bytes
-rw-r--r--org_apg/libs/scpg-jdk15on-1.47.0.2.jar (renamed from org_apg/libs/scpg-jdk15on-1.47.0.1.jar)bin278987 -> 278984 bytes
-rw-r--r--org_apg/libs/scprov-jdk15on-1.47.0.2.jarbin0 -> 987827 bytes
-rw-r--r--org_apg/src/org/thialfihar/android/apg/deprecated/ApgService2.java9
-rw-r--r--org_apg/src/org/thialfihar/android/apg/deprecated/GeneralActivity.java196
-rw-r--r--org_apg/src/org/thialfihar/android/apg/helper/PGPConversionHelper.java23
-rw-r--r--org_apg/src/org/thialfihar/android/apg/helper/PGPHelper.java1922
-rw-r--r--org_apg/src/org/thialfihar/android/apg/helper/PGPMain.java1971
-rw-r--r--org_apg/src/org/thialfihar/android/apg/passphrase/AskForPassphrase.java7
-rw-r--r--org_apg/src/org/thialfihar/android/apg/passphrase/PassphraseCacheService.java4
-rw-r--r--org_apg/src/org/thialfihar/android/apg/service/ApgService.java80
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/BaseActivity.java6
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java31
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java29
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java11
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/ImportFromQRCodeActivity.java3
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/KeyListActivity.java15
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/KeyServerExportActivity.java6
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/KeyServerQueryActivity.java1
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/MailListActivity.java6
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/MainActivity.java2
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/PreferencesActivity.java2
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/PreferencesKeyServerActivity.java2
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/PublicKeyListActivity.java5
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/SecretKeyListActivity.java9
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListActivity.java2
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/SelectSecretKeyListActivity.java2
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java16
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/dialog/FileDialogFragment.java1
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/dialog/PassphraseDialogFragment.java14
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/widget/KeyEditor.java1
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/widget/SectionView.java4
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/widget/SelectPublicKeyListAdapter.java3
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/widget/SelectSecretKeyListAdapter.java3
-rw-r--r--org_apg/src/org/thialfihar/android/apg/util/HkpKeyServer.java3
37 files changed, 2155 insertions, 2237 deletions
diff --git a/README.md b/README.md
index fe072337d..e8d08a0f3 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,6 @@ Fork APG and do a merge request. I will merge your changes back into the main pr
1. New -> Android Project -> Create project from existing source, choose com_actionbarsherlock
2. New -> Android Project -> Create project from existing source, choose org_apg
3. Add com_actionbarsherlock as Android Lib (Properties of org_apg -> Android -> Library -> add)
-4. Optional (As of Android Tools r17 the libraries are automatically added from the libs folder): Add Java libs (Properties of org_apg -> Java Build Path -> Libraries -> add all libraries from libs folder in org_apg)
5. Now APG+ can be build
# Libraries
@@ -35,7 +34,7 @@ Fork APG and do a merge request. I will merge your changes back into the main pr
The Libraries are provided in the git repository.
* ActionBarSherlock to provide an ActionBar for Android < 3.0
-* Spongy Castle as the main Crypto Lib
+* Spongy Castle Crypto Lib (Android version of Bouncy Castle)
* android-support-v4.jar: Compatibility Lib
* barcodescanner-android-integration-supportv4.jar: Barcode Scanner Integration
diff --git a/org_apg/libs/sc-bzip2-1.47.0.2.jar b/org_apg/libs/sc-bzip2-1.47.0.2.jar
new file mode 100644
index 000000000..3bc42f30e
--- /dev/null
+++ b/org_apg/libs/sc-bzip2-1.47.0.2.jar
Binary files differ
diff --git a/org_apg/libs/scprov-jdk15on-1.47.0.1.jar b/org_apg/libs/sc-light-jdk15on-1.47.0.2.jar
index 4fca4fed3..7cdbf856e 100644
--- a/org_apg/libs/scprov-jdk15on-1.47.0.1.jar
+++ b/org_apg/libs/sc-light-jdk15on-1.47.0.2.jar
Binary files differ
diff --git a/org_apg/libs/scpg-jdk15on-1.47.0.1.jar b/org_apg/libs/scpg-jdk15on-1.47.0.2.jar
index dc7f635c8..f290334d8 100644
--- a/org_apg/libs/scpg-jdk15on-1.47.0.1.jar
+++ b/org_apg/libs/scpg-jdk15on-1.47.0.2.jar
Binary files differ
diff --git a/org_apg/libs/scprov-jdk15on-1.47.0.2.jar b/org_apg/libs/scprov-jdk15on-1.47.0.2.jar
new file mode 100644
index 000000000..221a36b29
--- /dev/null
+++ b/org_apg/libs/scprov-jdk15on-1.47.0.2.jar
Binary files differ
diff --git a/org_apg/src/org/thialfihar/android/apg/deprecated/ApgService2.java b/org_apg/src/org/thialfihar/android/apg/deprecated/ApgService2.java
index 955d9c8ff..b13110f50 100644
--- a/org_apg/src/org/thialfihar/android/apg/deprecated/ApgService2.java
+++ b/org_apg/src/org/thialfihar/android/apg/deprecated/ApgService2.java
@@ -32,6 +32,7 @@ import org.thialfihar.android.apg.deprecated.IApgService2.Stub;
import org.thialfihar.android.apg.Id.database;
import org.thialfihar.android.apg.R.string;
import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.helper.Preferences;
import org.thialfihar.android.apg.passphrase.PassphraseCacheService;
import org.thialfihar.android.apg.provider.KeyRings;
@@ -204,7 +205,7 @@ public class ApgService2 extends PassphraseCacheService {
typeWhere = KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?";
typeVal = new String[] { "" + pParams.get("key_type") };
}
- return qb.query(PGPHelper.getDatabase().db(), (String[]) pParams.get("columns"), typeWhere,
+ return qb.query(PGPMain.getDatabase().db(), (String[]) pParams.get("columns"), typeWhere,
typeVal, null, null, orderBy);
}
@@ -427,7 +428,7 @@ public class ApgService2 extends PassphraseCacheService {
}
private boolean prepareArgs(String pCall, Bundle pArgs, Bundle pReturn) {
- PGPHelper.initialize(getBaseContext());
+ PGPMain.initialize(getBaseContext());
/* add default return values for all functions */
addDefaultReturns(pReturn);
@@ -493,7 +494,7 @@ public class ApgService2 extends PassphraseCacheService {
if (LOCAL_LOGV)
Log.v(TAG, "About to encrypt");
try {
- PGPHelper.encrypt(getBaseContext(), // context
+ PGPMain.encrypt(getBaseContext(), // context
in, // input stream
out, // output stream
pArgs.getBoolean(arg.ARMORED_OUTPUT.name()), // ARMORED_OUTPUT
@@ -625,7 +626,7 @@ public class ApgService2 extends PassphraseCacheService {
if (LOCAL_LOGV)
Log.v(TAG, "About to decrypt");
try {
- PGPHelper.decrypt(getBaseContext(), in, out, passphrase, null, // progress
+ PGPMain.decrypt(getBaseContext(), in, out, passphrase, null, // progress
pArgs.getString(arg.SYMMETRIC_PASSPHRASE.name()) != null // symmetric
);
} catch (Exception e) {
diff --git a/org_apg/src/org/thialfihar/android/apg/deprecated/GeneralActivity.java b/org_apg/src/org/thialfihar/android/apg/deprecated/GeneralActivity.java
deleted file mode 100644
index 7a3d99232..000000000
--- a/org_apg/src/org/thialfihar/android/apg/deprecated/GeneralActivity.java
+++ /dev/null
@@ -1,196 +0,0 @@
-///*
-// * 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.deprecated;
-//
-//import java.io.ByteArrayInputStream;
-//import java.io.FileNotFoundException;
-//import java.io.IOException;
-//import java.io.InputStream;
-//import java.util.Vector;
-//
-//import org.thialfihar.android.apg.R;
-//import org.thialfihar.android.apg.Id;
-//import org.thialfihar.android.apg.helper.PGPHelper;
-//import org.thialfihar.android.apg.ui.BaseActivity;
-//import org.thialfihar.android.apg.ui.DecryptActivity;
-//import org.thialfihar.android.apg.ui.EncryptActivity;
-//import org.thialfihar.android.apg.ui.PublicKeyListActivity;
-//import org.thialfihar.android.apg.ui.SecretKeyListActivity;
-//import org.thialfihar.android.apg.util.Choice;
-//
-//import android.content.Intent;
-//import android.net.Uri;
-//import android.os.Bundle;
-//import android.view.View;
-//import android.view.View.OnClickListener;
-//import android.widget.AdapterView;
-//import android.widget.AdapterView.OnItemClickListener;
-//import android.widget.ArrayAdapter;
-//import android.widget.Button;
-//import android.widget.ListView;
-//import android.widget.Toast;
-//
-//public class GeneralActivity extends BaseActivity {
-// private Intent mIntent;
-// private ArrayAdapter<Choice> mAdapter;
-// private ListView mList;
-// private Button mCancelButton;
-// private String mDataString;
-// private Uri mDataUri;
-//
-// @Override
-// protected void onCreate(Bundle savedInstanceState) {
-// super.onCreate(savedInstanceState);
-//
-// setContentView(R.layout.general);
-//
-// mIntent = getIntent();
-//
-// InputStream inStream = null;
-// {
-// String data = mIntent.getStringExtra(Intent.EXTRA_TEXT);
-// if (data != null) {
-// mDataString = data;
-// inStream = new ByteArrayInputStream(data.getBytes());
-// }
-// }
-//
-// if (inStream == null) {
-// Uri data = mIntent.getData();
-// if (data != null) {
-// mDataUri = data;
-// try {
-// inStream = getContentResolver().openInputStream(data);
-// } catch (FileNotFoundException e) {
-// // didn't work
-// Toast.makeText(this, "failed to open stream", Toast.LENGTH_SHORT).show();
-// }
-// }
-// }
-//
-// if (inStream == null) {
-// Toast.makeText(this, "no data found", Toast.LENGTH_SHORT).show();
-// finish();
-// return;
-// }
-//
-// int contentType = Id.content.unknown;
-// try {
-// contentType = PGPHelper.getStreamContent(this, inStream);
-// inStream.close();
-// } catch (IOException e) {
-// // just means that there's no PGP data in there
-// }
-//
-// mList = (ListView) findViewById(R.id.options);
-// Vector<Choice> choices = new Vector<Choice>();
-//
-// if (contentType == Id.content.keys) {
-// choices.add(new Choice(Id.choice.action.import_public,
-// getString(R.string.action_importPublic)));
-// choices.add(new Choice(Id.choice.action.import_secret,
-// getString(R.string.action_importSecret)));
-// }
-//
-// if (contentType == Id.content.encrypted_data) {
-// choices.add(new Choice(Id.choice.action.decrypt, getString(R.string.action_decrypt)));
-// }
-//
-// if (contentType == Id.content.unknown) {
-// choices.add(new Choice(Id.choice.action.encrypt, getString(R.string.action_encrypt)));
-// }
-//
-// mAdapter = new ArrayAdapter<Choice>(this, android.R.layout.simple_list_item_1, choices);
-// mList.setAdapter(mAdapter);
-//
-// mList.setOnItemClickListener(new OnItemClickListener() {
-// public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
-// clicked(mAdapter.getItem(arg2).getId());
-// }
-// });
-//
-// mCancelButton = (Button) findViewById(R.id.btn_cancel);
-// mCancelButton.setOnClickListener(new OnClickListener() {
-// public void onClick(View v) {
-// GeneralActivity.this.finish();
-// }
-// });
-//
-// if (choices.size() == 1) {
-// clicked(choices.get(0).getId());
-// }
-// }
-//
-// private void clicked(int id) {
-// Intent intent = new Intent();
-// switch (id) {
-// case Id.choice.action.encrypt: {
-// intent.setClass(this, EncryptActivity.class);
-// if (mDataString != null) {
-// intent.setAction(EncryptActivity.ENCRYPT);
-// intent.putExtra(PGPHelper.EXTRA_TEXT, mDataString);
-// } else if (mDataUri != null) {
-// intent.setAction(EncryptActivity.ENCRYPT_FILE);
-// intent.setDataAndType(mDataUri, mIntent.getType());
-// }
-//
-// break;
-// }
-//
-// case Id.choice.action.decrypt: {
-// intent.setClass(this, DecryptActivity.class);
-// if (mDataString != null) {
-// intent.setAction(DecryptActivity.DECRYPT);
-// intent.putExtra(PGPHelper.EXTRA_TEXT, mDataString);
-// } else if (mDataUri != null) {
-// intent.setAction(DecryptActivity.DECRYPT_FILE);
-// intent.setDataAndType(mDataUri, mIntent.getType());
-// }
-//
-// break;
-// }
-//
-// case Id.choice.action.import_public: {
-// intent.setClass(this, PublicKeyListActivity.class);
-// intent.setAction(PublicKeyListActivity.IMPORT);
-// if (mDataString != null) {
-// intent.putExtra(PGPHelper.EXTRA_TEXT, mDataString);
-// } else if (mDataUri != null) {
-// intent.setDataAndType(mDataUri, mIntent.getType());
-// }
-// break;
-// }
-//
-// case Id.choice.action.import_secret: {
-// intent.setClass(this, SecretKeyListActivity.class);
-// intent.setAction(SecretKeyListActivity.IMPORT);
-// if (mDataString != null) {
-// intent.putExtra(PGPHelper.EXTRA_TEXT, mDataString);
-// } else if (mDataUri != null) {
-// intent.setDataAndType(mDataUri, mIntent.getType());
-// }
-// break;
-// }
-//
-// default: {
-// // shouldn't happen
-// return;
-// }
-// }
-//
-// startActivity(intent);
-// finish();
-// }
-//}
diff --git a/org_apg/src/org/thialfihar/android/apg/helper/PGPConversionHelper.java b/org_apg/src/org/thialfihar/android/apg/helper/PGPConversionHelper.java
index a406bf6e8..f1bd530a8 100644
--- a/org_apg/src/org/thialfihar/android/apg/helper/PGPConversionHelper.java
+++ b/org_apg/src/org/thialfihar/android/apg/helper/PGPConversionHelper.java
@@ -23,6 +23,7 @@ import java.util.Iterator;
import java.util.Vector;
import org.spongycastle.openpgp.PGPObjectFactory;
+import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.thialfihar.android.apg.Constants;
@@ -54,7 +55,7 @@ public class PGPConversionHelper {
}
/**
- * Convert from byte[] to ArrayList<PGPSecretKey>
+ * Convert from byte[] to PGPSecretKeyRing
*
* @param keysBytes
* @return
@@ -72,6 +73,26 @@ public class PGPConversionHelper {
return keyRing;
}
+
+ /**
+ * Convert from byte[] to PGPPublicKeyRing
+ *
+ * @param keysBytes
+ * @return
+ */
+ public static PGPPublicKeyRing BytesToPGPPublicKeyRing(byte[] keysBytes) {
+ PGPObjectFactory factory = new PGPObjectFactory(keysBytes);
+ PGPPublicKeyRing keyRing = null;
+ try {
+ if ((keyRing = (PGPPublicKeyRing) factory.nextObject()) == null) {
+ Log.e(Constants.TAG, "No keys given!");
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return keyRing;
+ }
public static ArrayList<PGPSecretKey> BytesToPGPSecretKeyList(byte[] keysBytes) {
PGPSecretKeyRing keyRing = BytesToPGPSecretKeyRing(keysBytes);
diff --git a/org_apg/src/org/thialfihar/android/apg/helper/PGPHelper.java b/org_apg/src/org/thialfihar/android/apg/helper/PGPHelper.java
index ffd8bbea6..0b6191f67 100644
--- a/org_apg/src/org/thialfihar/android/apg/helper/PGPHelper.java
+++ b/org_apg/src/org/thialfihar/android/apg/helper/PGPHelper.java
@@ -17,587 +17,29 @@
package org.thialfihar.android.apg.helper;
-import org.spongycastle.bcpg.ArmoredInputStream;
-import org.spongycastle.bcpg.ArmoredOutputStream;
-import org.spongycastle.bcpg.BCPGOutputStream;
-import org.spongycastle.bcpg.CompressionAlgorithmTags;
-import org.spongycastle.bcpg.HashAlgorithmTags;
-import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Vector;
+
import org.spongycastle.bcpg.sig.KeyFlags;
-import org.spongycastle.jce.provider.BouncyCastleProvider;
-import org.spongycastle.jce.spec.ElGamalParameterSpec;
-import org.spongycastle.openpgp.PGPCompressedData;
-import org.spongycastle.openpgp.PGPCompressedDataGenerator;
-import org.spongycastle.openpgp.PGPEncryptedData;
-import org.spongycastle.openpgp.PGPEncryptedDataGenerator;
-import org.spongycastle.openpgp.PGPEncryptedDataList;
-import org.spongycastle.openpgp.PGPException;
-import org.spongycastle.openpgp.PGPKeyPair;
import org.spongycastle.openpgp.PGPKeyRing;
-import org.spongycastle.openpgp.PGPKeyRingGenerator;
-import org.spongycastle.openpgp.PGPLiteralData;
-import org.spongycastle.openpgp.PGPLiteralDataGenerator;
import org.spongycastle.openpgp.PGPObjectFactory;
-import org.spongycastle.openpgp.PGPOnePassSignature;
-import org.spongycastle.openpgp.PGPOnePassSignatureList;
-import org.spongycastle.openpgp.PGPPBEEncryptedData;
-import org.spongycastle.openpgp.PGPPrivateKey;
import org.spongycastle.openpgp.PGPPublicKey;
-import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPSignature;
-import org.spongycastle.openpgp.PGPSignatureGenerator;
-import org.spongycastle.openpgp.PGPSignatureList;
-import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
import org.spongycastle.openpgp.PGPUtil;
-import org.spongycastle.openpgp.PGPV3SignatureGenerator;
-import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
-import org.spongycastle.openpgp.operator.PBESecretKeyEncryptor;
-import org.spongycastle.openpgp.operator.PGPContentSignerBuilder;
-import org.spongycastle.openpgp.operator.PGPDigestCalculator;
-import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
-import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
-import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
-import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
-import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
-import org.thialfihar.android.apg.Id.choice;
-import org.thialfihar.android.apg.Id.content;
-import org.thialfihar.android.apg.Id.database;
-import org.thialfihar.android.apg.Id.key;
-import org.thialfihar.android.apg.Id.return_value;
-import org.thialfihar.android.apg.Id.type;
-import org.thialfihar.android.apg.Id.choice.algorithm;
-import org.thialfihar.android.apg.Id.choice.compression;
-import org.thialfihar.android.apg.Id.choice.usage;
-import org.thialfihar.android.apg.R.string;
-import org.thialfihar.android.apg.passphrase.CachedPassPhrase;
-import org.thialfihar.android.apg.provider.DataProvider;
-import org.thialfihar.android.apg.provider.Database;
-import org.thialfihar.android.apg.provider.KeyRings;
-import org.thialfihar.android.apg.provider.Keys;
-import org.thialfihar.android.apg.provider.UserIds;
-import org.thialfihar.android.apg.service.ApgService;
-import org.thialfihar.android.apg.ui.BaseActivity;
-import org.thialfihar.android.apg.ui.widget.KeyEditor;
-import org.thialfihar.android.apg.ui.widget.SectionView;
-import org.thialfihar.android.apg.ui.widget.UserIdEditor;
-import org.thialfihar.android.apg.util.HkpKeyServer;
-import org.thialfihar.android.apg.util.InputData;
-import org.thialfihar.android.apg.util.IterableIterator;
-import org.thialfihar.android.apg.util.KeyServer;
-import org.thialfihar.android.apg.util.PositionAwareInputStream;
-import org.thialfihar.android.apg.util.Primes;
-import org.thialfihar.android.apg.util.KeyServer.AddKeyException;
-import org.thialfihar.android.apg.Constants;
-import org.thialfihar.android.apg.Id;
-import org.thialfihar.android.apg.ProgressDialogUpdater;
import org.thialfihar.android.apg.R;
+import org.thialfihar.android.apg.util.IterableIterator;
-import android.app.Activity;
import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.Message;
-import android.util.Log;
-import android.view.ViewGroup;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.EOFException;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.RandomAccessFile;
-import java.math.BigInteger;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.SecureRandom;
-import java.security.Security;
-import java.security.SignatureException;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Vector;
-import java.util.regex.Pattern;
-
-/**
- * TODO:
- *
- * - Externalize the authority and content uri constants
- *
- * - Separate this file into different helpers
- *
- */
-public class PGPHelper {
-
- static {
- // register spongy castle provider
- Security.addProvider(new BouncyCastleProvider());
- }
-
- public static final String AUTHORITY = DataProvider.AUTHORITY;
-
- public static final Uri CONTENT_URI_SECRET_KEY_RINGS = Uri.parse("content://" + AUTHORITY
- + "/key_rings/secret/");
- public static final Uri CONTENT_URI_SECRET_KEY_RING_BY_KEY_ID = Uri.parse("content://"
- + AUTHORITY + "/key_rings/secret/key_id/");
- public static final Uri CONTENT_URI_SECRET_KEY_RING_BY_EMAILS = Uri.parse("content://"
- + AUTHORITY + "/key_rings/secret/emails/");
-
- public static final Uri CONTENT_URI_PUBLIC_KEY_RINGS = Uri.parse("content://" + AUTHORITY
- + "/key_rings/public/");
- public static final Uri CONTENT_URI_PUBLIC_KEY_RING_BY_KEY_ID = Uri.parse("content://"
- + AUTHORITY + "/key_rings/public/key_id/");
- public static final Uri CONTENT_URI_PUBLIC_KEY_RING_BY_EMAILS = Uri.parse("content://"
- + AUTHORITY + "/key_rings/public/emails/");
-
- private static String VERSION = null;
-
- private static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[] {
- SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192,
- SymmetricKeyAlgorithmTags.AES_128, SymmetricKeyAlgorithmTags.CAST5,
- SymmetricKeyAlgorithmTags.TRIPLE_DES };
- private static final int[] PREFERRED_HASH_ALGORITHMS = new int[] { HashAlgorithmTags.SHA1,
- HashAlgorithmTags.SHA256, HashAlgorithmTags.RIPEMD160 };
- private static final int[] PREFERRED_COMPRESSION_ALGORITHMS = new int[] {
- CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.BZIP2,
- CompressionAlgorithmTags.ZIP };
-
- public static Pattern PGP_MESSAGE = Pattern.compile(
- ".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", Pattern.DOTALL);
-
- public static Pattern PGP_SIGNED_MESSAGE = Pattern
- .compile(
- ".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*",
- Pattern.DOTALL);
-
- public static Pattern PGP_PUBLIC_KEY = Pattern.compile(
- ".*?(-----BEGIN PGP PUBLIC KEY BLOCK-----.*?-----END PGP PUBLIC KEY BLOCK-----).*",
- Pattern.DOTALL);
-
- private static HashMap<Long, CachedPassPhrase> mPassPhraseCache = new HashMap<Long, CachedPassPhrase>();
- private static String mEditPassPhrase = null;
-
- private static Database mDatabase = null;
-
- public static class GeneralException extends Exception {
- static final long serialVersionUID = 0xf812773342L;
-
- public GeneralException(String message) {
- super(message);
- }
- }
-
- public static class NoAsymmetricEncryptionException extends Exception {
- static final long serialVersionUID = 0xf812773343L;
-
- public NoAsymmetricEncryptionException() {
- super();
- }
- }
-
- public static void initialize(Context context) {
- if (mDatabase == null) {
- mDatabase = new Database(context);
- }
- }
-
- public static Database getDatabase() {
- return mDatabase;
- }
-
- public static void setEditPassPhrase(String passPhrase) {
- mEditPassPhrase = passPhrase;
- }
-
- public static String getEditPassPhrase() {
- return mEditPassPhrase;
- }
-
- public static void setCachedPassPhrase(long keyId, String passPhrase) {
- mPassPhraseCache.put(keyId, new CachedPassPhrase(new Date().getTime(), passPhrase));
- }
-
- public static String getCachedPassPhrase(long keyId) {
- long realId = keyId;
- if (realId != Id.key.symmetric) {
- PGPSecretKeyRing keyRing = getSecretKeyRing(keyId);
- if (keyRing == null) {
- return null;
- }
- PGPSecretKey masterKey = getMasterKey(keyRing);
- if (masterKey == null) {
- return null;
- }
- realId = masterKey.getKeyID();
- }
- CachedPassPhrase cpp = mPassPhraseCache.get(realId);
- if (cpp == null) {
- return null;
- }
- // set it again to reset the cache life cycle
- setCachedPassPhrase(realId, cpp.passPhrase);
- return cpp.passPhrase;
- }
-
- public static int cleanUpCache(int ttl, int initialDelay) {
- int delay = initialDelay;
- long realTtl = ttl * 1000;
- long now = new Date().getTime();
- Vector<Long> oldKeys = new Vector<Long>();
- for (Map.Entry<Long, CachedPassPhrase> pair : mPassPhraseCache.entrySet()) {
- long lived = now - pair.getValue().timestamp;
- if (lived >= realTtl) {
- oldKeys.add(pair.getKey());
- } else {
- // see, whether the remaining time for this cache entry improves our
- // check delay
- long nextCheck = realTtl - lived + 1000;
- if (nextCheck < delay) {
- delay = (int) nextCheck;
- }
- }
- }
-
- for (long keyId : oldKeys) {
- mPassPhraseCache.remove(keyId);
- }
-
- return delay;
- }
-
- /**
- * Creates new secret key. The returned PGPSecretKeyRing contains only one newly generated key
- * when this key is the new masterkey. If a masterkey is supplied in the parameters
- * PGPSecretKeyRing contains the masterkey and the new key as a subkey (certified by the
- * masterkey).
- *
- * @param context
- * @param algorithmChoice
- * @param keySize
- * @param passPhrase
- * @param masterSecretKey
- * @return
- * @throws NoSuchAlgorithmException
- * @throws PGPException
- * @throws NoSuchProviderException
- * @throws GeneralException
- * @throws InvalidAlgorithmParameterException
- */
- public static PGPSecretKeyRing createKey(Context context, int algorithmChoice, int keySize,
- String passPhrase, PGPSecretKey masterSecretKey) throws NoSuchAlgorithmException,
- PGPException, NoSuchProviderException, GeneralException,
- InvalidAlgorithmParameterException {
-
- if (keySize < 512) {
- throw new GeneralException(context.getString(R.string.error_keySizeMinimum512bit));
- }
-
- if (passPhrase == null) {
- passPhrase = "";
- }
-
- int algorithm = 0;
- KeyPairGenerator keyGen = null;
-
- switch (algorithmChoice) {
- case Id.choice.algorithm.dsa: {
- keyGen = KeyPairGenerator.getInstance("DSA", "SC");
- keyGen.initialize(keySize, new SecureRandom());
- algorithm = PGPPublicKey.DSA;
- break;
- }
-
- case Id.choice.algorithm.elgamal: {
- if (masterSecretKey == null) {
- throw new GeneralException(
- context.getString(R.string.error_masterKeyMustNotBeElGamal));
- }
- keyGen = KeyPairGenerator.getInstance("ELGAMAL", "SC");
- BigInteger p = Primes.getBestPrime(keySize);
- BigInteger g = new BigInteger("2");
-
- ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g);
-
- keyGen.initialize(elParams);
- algorithm = PGPPublicKey.ELGAMAL_ENCRYPT;
- break;
- }
-
- case Id.choice.algorithm.rsa: {
- keyGen = KeyPairGenerator.getInstance("RSA", "SC");
- keyGen.initialize(keySize, new SecureRandom());
-
- algorithm = PGPPublicKey.RSA_GENERAL;
- break;
- }
-
- default: {
- throw new GeneralException(context.getString(R.string.error_unknownAlgorithmChoice));
- }
- }
-
- // build new key pair
- PGPKeyPair keyPair = new JcaPGPKeyPair(algorithm, keyGen.generateKeyPair(), new Date());
-
- // define hashing and signing algos
- PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(
- HashAlgorithmTags.SHA1);
- PGPContentSignerBuilder certificationSignerBuilder = new JcaPGPContentSignerBuilder(keyPair
- .getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1);
-
- // Build key encrypter and decrypter based on passphrase
- PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
- PGPEncryptedData.CAST5, sha1Calc).setProvider("SC").build(passPhrase.toCharArray());
- PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
- .setProvider("SC").build(passPhrase.toCharArray());
-
- PGPKeyRingGenerator ringGen = null;
- if (masterSecretKey == null) {
-
- // build keyRing with only this one master key in it!
- ringGen = new PGPKeyRingGenerator(PGPSignature.DEFAULT_CERTIFICATION, keyPair, "",
- sha1Calc, null, null, certificationSignerBuilder, keyEncryptor);
- } else {
- PGPPublicKey masterPublicKey = masterSecretKey.getPublicKey();
- PGPPrivateKey masterPrivateKey = masterSecretKey.extractPrivateKey(keyDecryptor);
- PGPKeyPair masterKeyPair = new PGPKeyPair(masterPublicKey, masterPrivateKey);
-
- // build keyRing with master key and new key as subkey (certified by masterkey)
- ringGen = new PGPKeyRingGenerator(PGPSignature.DEFAULT_CERTIFICATION, masterKeyPair,
- "", sha1Calc, null, null, certificationSignerBuilder, keyEncryptor);
-
- ringGen.addSubKey(keyPair);
- }
-
- PGPSecretKeyRing secKeyRing = ringGen.generateSecretKeyRing();
-
- return secKeyRing;
- }
-
- public static void buildSecretKey(Context context, ArrayList<String> userIds,
- ArrayList<PGPSecretKey> keys, ArrayList<Integer> keysUsages, long masterKeyId,
- String oldPassPhrase, String newPassPhrase, ProgressDialogUpdater progress)
- throws PGPHelper.GeneralException, NoSuchProviderException, PGPException,
- NoSuchAlgorithmException, SignatureException, IOException, Database.GeneralException {
-
- if (progress != null)
- progress.setProgress(R.string.progress_buildingKey, 0, 100);
-
- if (oldPassPhrase == null || oldPassPhrase.equals("")) {
- oldPassPhrase = "";
- }
-
- if (newPassPhrase == null || newPassPhrase.equals("")) {
- newPassPhrase = "";
- }
-
- // Vector<String> userIds = new Vector<String>();
- // Vector<PGPSecretKey> keys = new Vector<PGPSecretKey>();
-
- // ViewGroup userIdEditors = userIdsView.getEditors();
- // ViewGroup keyEditors = keysView.getEditors();
- //
- // boolean gotMainUserId = false;
- // for (int i = 0; i < userIdEditors.getChildCount(); ++i) {
- // UserIdEditor editor = (UserIdEditor) userIdEditors.getChildAt(i);
- // String userId = null;
- // try {
- // userId = editor.getValue();
- // } catch (UserIdEditor.NoNameException e) {
- // throw new Apg.GeneralException(context.getString(R.string.error_userIdNeedsAName));
- // } catch (UserIdEditor.NoEmailException e) {
- // throw new Apg.GeneralException(
- // context.getString(R.string.error_userIdNeedsAnEmailAddress));
- // } catch (UserIdEditor.InvalidEmailException e) {
- // throw new Apg.GeneralException("" + e);
- // }
- //
- // if (userId.equals("")) {
- // continue;
- // }
- //
- // if (editor.isMainUserId()) {
- // userIds.insertElementAt(userId, 0);
- // gotMainUserId = true;
- // } else {
- // userIds.add(userId);
- // }
- // }
-
- // if (userIds.size() == 0) {
- // throw new Apg.GeneralException(context.getString(R.string.error_keyNeedsAUserId));
- // }
- //
- // if (!gotMainUserId) {
- // throw new Apg.GeneralException(
- // context.getString(R.string.error_mainUserIdMustNotBeEmpty));
- // }
-
- // if (keyEditors.getChildCount() == 0) {
- // throw new Apg.GeneralException(context.getString(R.string.error_keyNeedsMasterKey));
- // }
- //
- // for (int i = 0; i < keyEditors.getChildCount(); ++i) {
- // KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
- // keys.add(editor.getValue());
- // }
-
- if (progress != null)
- progress.setProgress(R.string.progress_preparingMasterKey, 10, 100);
-
- // KeyEditor keyEditor = (KeyEditor) keyEditors.getChildAt(0);
- // int usageId = keyEditor.getUsage();
-
- int usageId = keysUsages.get(0);
- boolean canSign = (usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt);
- boolean canEncrypt = (usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt);
-
- String mainUserId = userIds.get(0);
-
- PGPSecretKey masterKey = keys.get(0);
- PGPPublicKey tmpKey = masterKey.getPublicKey();
- PGPPublicKey masterPublicKey = new PGPPublicKey(tmpKey.getAlgorithm(),
- tmpKey.getKey(new BouncyCastleProvider()), tmpKey.getCreationTime());
- PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
- .setProvider("SC").build(oldPassPhrase.toCharArray());
- PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(keyDecryptor);
-
- if (progress != null)
- progress.setProgress(R.string.progress_certifyingMasterKey, 20, 100);
- for (int i = 0; i < userIds.size(); ++i) {
- String userId = userIds.get(i);
-
- PGPSignatureGenerator sGen = new PGPSignatureGenerator(masterPublicKey.getAlgorithm(),
- HashAlgorithmTags.SHA1, new BouncyCastleProvider());
-
- sGen.initSign(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey);
-
- PGPSignature certification = sGen.generateCertification(userId, masterPublicKey);
-
- masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification);
- }
-
- // TODO: cross-certify the master key with every sub key
-
- PGPKeyPair masterKeyPair = new PGPKeyPair(masterPublicKey, masterPrivateKey);
-
- PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator();
- PGPSignatureSubpacketGenerator unhashedPacketsGen = new PGPSignatureSubpacketGenerator();
-
- int keyFlags = KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA;
- if (canEncrypt) {
- keyFlags |= KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE;
- }
- hashedPacketsGen.setKeyFlags(true, keyFlags);
-
- hashedPacketsGen.setPreferredSymmetricAlgorithms(true, PREFERRED_SYMMETRIC_ALGORITHMS);
- hashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS);
- hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS);
-
- // TODO: this doesn't work quite right yet
- // if (keyEditor.getExpiryDate() != null) {
- // GregorianCalendar creationDate = new GregorianCalendar();
- // creationDate.setTime(getCreationDate(masterKey));
- // GregorianCalendar expiryDate = keyEditor.getExpiryDate();
- // long numDays = Utils.getNumDaysBetween(creationDate, expiryDate);
- // if (numDays <= 0) {
- // throw new GeneralException(
- // context.getString(R.string.error_expiryMustComeAfterCreation));
- // }
- // hashedPacketsGen.setKeyExpirationTime(true, numDays * 86400);
- // }
-
- if (progress != null) {
- progress.setProgress(R.string.progress_buildingMasterKeyRing, 30, 100);
- }
-
- PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION,
- masterKeyPair, mainUserId, PGPEncryptedData.CAST5, newPassPhrase.toCharArray(),
- hashedPacketsGen.generate(), unhashedPacketsGen.generate(), new SecureRandom(),
- new BouncyCastleProvider().getName());
-
- if (progress != null)
- progress.setProgress(R.string.progress_addingSubKeys, 40, 100);
- for (int i = 1; i < keys.size(); ++i) {
- if (progress != null)
- progress.setProgress(40 + 50 * (i - 1) / (keys.size() - 1), 100);
- PGPSecretKey subKey = keys.get(i);
- // keyEditor = (KeyEditor) keyEditors.getChildAt(i);
- PGPPublicKey subPublicKey = subKey.getPublicKey();
-
- PBESecretKeyDecryptor keyDecryptor2 = new JcePBESecretKeyDecryptorBuilder()
- .setProvider("SC").build(oldPassPhrase.toCharArray());
- PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(keyDecryptor2);
- PGPKeyPair subKeyPair = new PGPKeyPair(subPublicKey.getAlgorithm(),
- subPublicKey.getKey(new BouncyCastleProvider()), subPrivateKey.getKey(),
- subPublicKey.getCreationTime());
-
- hashedPacketsGen = new PGPSignatureSubpacketGenerator();
- unhashedPacketsGen = new PGPSignatureSubpacketGenerator();
-
- keyFlags = 0;
- // usageId = keyEditor.getUsage();
-
- usageId = keysUsages.get(i);
- canSign = (usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt);
- canEncrypt = (usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt);
- if (canSign) {
- keyFlags |= KeyFlags.SIGN_DATA;
- }
- if (canEncrypt) {
- keyFlags |= KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE;
- }
- hashedPacketsGen.setKeyFlags(true, keyFlags);
-
- // TODO: this doesn't work quite right yet
- // if (keyEditor.getExpiryDate() != null) {
- // GregorianCalendar creationDate = new GregorianCalendar();
- // creationDate.setTime(getCreationDate(masterKey));
- // GregorianCalendar expiryDate = keyEditor.getExpiryDate();
- // long numDays = Utils.getNumDaysBetween(creationDate, expiryDate);
- // if (numDays <= 0) {
- // throw new GeneralException(
- // context.getString(R.string.error_expiryMustComeAfterCreation));
- // }
- // hashedPacketsGen.setKeyExpirationTime(true, numDays * 86400);
- // }
-
- keyGen.addSubKey(subKeyPair, hashedPacketsGen.generate(), unhashedPacketsGen.generate());
- }
-
- PGPSecretKeyRing secretKeyRing = keyGen.generateSecretKeyRing();
- PGPPublicKeyRing publicKeyRing = keyGen.generatePublicKeyRing();
-
- if (progress != null)
- progress.setProgress(R.string.progress_savingKeyRing, 90, 100);
- mDatabase.saveKeyRing(secretKeyRing);
- mDatabase.saveKeyRing(publicKeyRing);
-
- if (progress != null)
- progress.setProgress(R.string.progress_done, 100, 100);
- }
+public class PGPHelper {
public static PGPKeyRing decodeKeyRing(InputStream is) throws IOException {
InputStream in = PGPUtil.getDecoderStream(is);
PGPObjectFactory objectFactory = new PGPObjectFactory(in);
@@ -610,184 +52,6 @@ public class PGPHelper {
return null;
}
- public static int storeKeyRingInCache(PGPKeyRing keyring) {
- int status = Integer.MIN_VALUE; // out of bounds value (Id.retrun_value.*)
- try {
- if (keyring instanceof PGPSecretKeyRing) {
- PGPSecretKeyRing secretKeyRing = (PGPSecretKeyRing) keyring;
- boolean save = true;
- try {
- PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
- .setProvider("SC").build(new char[] {});
- PGPPrivateKey testKey = secretKeyRing.getSecretKey().extractPrivateKey(
- keyDecryptor);
- if (testKey == null) {
- // this is bad, something is very wrong... likely a --export-secret-subkeys
- // export
- save = false;
- status = Id.return_value.bad;
- }
- } catch (PGPException e) {
- // all good if this fails, we likely didn't use the right password
- }
-
- if (save) {
- status = mDatabase.saveKeyRing(secretKeyRing);
- }
- } else if (keyring instanceof PGPPublicKeyRing) {
- PGPPublicKeyRing publicKeyRing = (PGPPublicKeyRing) keyring;
- status = mDatabase.saveKeyRing(publicKeyRing);
- }
- } catch (IOException e) {
- status = Id.return_value.error;
- } catch (Database.GeneralException e) {
- status = Id.return_value.error;
- }
-
- return status;
- }
-
- public static boolean uploadKeyRingToServer(HkpKeyServer server, PGPPublicKeyRing keyring) {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- ArmoredOutputStream aos = new ArmoredOutputStream(bos);
- try {
- aos.write(keyring.getEncoded());
- aos.close();
-
- String armouredKey = bos.toString("UTF-8");
- server.add(armouredKey);
-
- return true;
- } catch (IOException e) {
- return false;
- } catch (AddKeyException e) {
- // TODO: tell the user?
- return false;
- } finally {
- try {
- bos.close();
- } catch (IOException e) {
- }
- }
- }
-
- public static Bundle importKeyRings(Activity context, int type, InputData data,
- ProgressDialogUpdater progress) throws GeneralException, FileNotFoundException,
- PGPException, IOException {
- Bundle returnData = new Bundle();
-
- if (type == Id.type.secret_key) {
- if (progress != null)
- progress.setProgress(R.string.progress_importingSecretKeys, 0, 100);
- } else {
- if (progress != null)
- progress.setProgress(R.string.progress_importingPublicKeys, 0, 100);
- }
-
- if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- throw new GeneralException(context.getString(R.string.error_externalStorageNotReady));
- }
-
- PositionAwareInputStream progressIn = new PositionAwareInputStream(data.getInputStream());
- // need to have access to the bufferedInput, so we can reuse it for the possible
- // PGPObject chunks after the first one, e.g. files with several consecutive ASCII
- // armour blocks
- BufferedInputStream bufferedInput = new BufferedInputStream(progressIn);
- int newKeys = 0;
- int oldKeys = 0;
- int badKeys = 0;
- try {
- PGPKeyRing keyring = decodeKeyRing(bufferedInput);
- while (keyring != null) {
- int status = Integer.MIN_VALUE; // out of bounds value
-
- // if this key is what we expect it to be, save it
- if ((type == Id.type.secret_key && keyring instanceof PGPSecretKeyRing)
- || (type == Id.type.public_key && keyring instanceof PGPPublicKeyRing)) {
- status = storeKeyRingInCache(keyring);
- }
-
- if (status == Id.return_value.error) {
- throw new GeneralException(context.getString(R.string.error_savingKeys));
- }
-
- // update the counts to display to the user at the end
- if (status == Id.return_value.updated) {
- ++oldKeys;
- } else if (status == Id.return_value.ok) {
- ++newKeys;
- } else if (status == Id.return_value.bad) {
- ++badKeys;
- }
-
- if (progress != null) {
- progress.setProgress((int) (100 * progressIn.position() / data.getSize()), 100);
- }
- // TODO: needed?
- // obj = objectFactory.nextObject();
-
- keyring = decodeKeyRing(bufferedInput);
- }
- } catch (EOFException e) {
- // nothing to do, we are done
- }
-
- returnData.putInt("added", newKeys);
- returnData.putInt("updated", oldKeys);
- returnData.putInt("bad", badKeys);
-
- if (progress != null)
- progress.setProgress(R.string.progress_done, 100, 100);
-
- return returnData;
- }
-
- public static Bundle exportKeyRings(Activity context, Vector<Integer> keyRingIds,
- OutputStream outStream, ProgressDialogUpdater progress) throws GeneralException,
- FileNotFoundException, PGPException, IOException {
- Bundle returnData = new Bundle();
-
- if (keyRingIds.size() == 1) {
- if (progress != null)
- progress.setProgress(R.string.progress_exportingKey, 0, 100);
- } else {
- if (progress != null)
- progress.setProgress(R.string.progress_exportingKeys, 0, 100);
- }
-
- if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- throw new GeneralException(context.getString(R.string.error_externalStorageNotReady));
- }
- ArmoredOutputStream out = new ArmoredOutputStream(outStream);
-
- int numKeys = 0;
- for (int i = 0; i < keyRingIds.size(); ++i) {
- if (progress != null)
- progress.setProgress(i * 100 / keyRingIds.size(), 100);
- Object obj = mDatabase.getKeyRing(keyRingIds.get(i));
- PGPPublicKeyRing publicKeyRing;
- PGPSecretKeyRing secretKeyRing;
-
- if (obj instanceof PGPSecretKeyRing) {
- secretKeyRing = (PGPSecretKeyRing) obj;
- secretKeyRing.encode(out);
- } else if (obj instanceof PGPPublicKeyRing) {
- publicKeyRing = (PGPPublicKeyRing) obj;
- publicKeyRing.encode(out);
- } else {
- continue;
- }
- ++numKeys;
- }
- out.close();
- returnData.putInt("exported", numKeys);
-
- if (progress != null)
- progress.setProgress(R.string.progress_done, 100, 100);
-
- return returnData;
- }
-
public static Date getCreationDate(PGPPublicKey key) {
return key.getCreationTime();
}
@@ -922,7 +186,8 @@ public class PGPHelper {
}
public static PGPPublicKey getEncryptPublicKey(long masterKeyId) {
- PGPPublicKeyRing keyRing = getPublicKeyRing(masterKeyId);
+ //TODO: externalize getSecretKeyRing from PGPWrapper into a DatabaseHelper
+ PGPPublicKeyRing keyRing = PGPMain.getPublicKeyRing(masterKeyId);
if (keyRing == null) {
return null;
}
@@ -934,7 +199,8 @@ public class PGPHelper {
}
public static PGPSecretKey getSigningKey(long masterKeyId) {
- PGPSecretKeyRing keyRing = getSecretKeyRing(masterKeyId);
+ //TODO: externalize getSecretKeyRing from PGPWrapper into a DatabaseHelper
+ PGPSecretKeyRing keyRing = PGPMain.getSecretKeyRing(masterKeyId);
if (keyRing == null) {
return null;
}
@@ -1115,9 +381,9 @@ public class PGPHelper {
}
public static String getFingerPrint(long keyId) {
- PGPPublicKey key = PGPHelper.getPublicKey(keyId);
+ PGPPublicKey key = PGPMain.getPublicKey(keyId);
if (key == null) {
- PGPSecretKey secretKey = PGPHelper.getSecretKey(keyId);
+ PGPSecretKey secretKey = PGPMain.getSecretKey(keyId);
if (secretKey == null) {
return "";
}
@@ -1145,1162 +411,4 @@ public class PGPHelper {
String s1 = data.substring(0, len - 8);
return (Long.parseLong(s1, 16) << 32) | Long.parseLong(s2, 16);
}
-
- public static void deleteKey(int keyRingId) {
- mDatabase.deleteKeyRing(keyRingId);
- }
-
- public static PGPKeyRing getKeyRing(int keyRingId) {
- return (PGPKeyRing) mDatabase.getKeyRing(keyRingId);
- }
-
- public static PGPSecretKeyRing getSecretKeyRing(long keyId) {
- byte[] data = mDatabase.getKeyRingDataFromKeyId(Id.database.type_secret, keyId);
- if (data == null) {
- return null;
- }
- try {
- return new PGPSecretKeyRing(data);
- } catch (IOException e) {
- // no good way to handle this, return null
- // TODO: some info?
- } catch (PGPException e) {
- // no good way to handle this, return null
- // TODO: some info?
- }
- return null;
- }
-
- public static PGPPublicKeyRing getPublicKeyRing(long keyId) {
- byte[] data = mDatabase.getKeyRingDataFromKeyId(Id.database.type_public, keyId);
- if (data == null) {
- return null;
- }
- try {
- return new PGPPublicKeyRing(data);
- } catch (IOException e) {
- // no good way to handle this, return null
- // TODO: some info?
- }
- return null;
- }
-
- public static PGPSecretKey getSecretKey(long keyId) {
- PGPSecretKeyRing keyRing = getSecretKeyRing(keyId);
- if (keyRing == null) {
- return null;
- }
- return keyRing.getSecretKey(keyId);
- }
-
- public static PGPPublicKey getPublicKey(long keyId) {
- PGPPublicKeyRing keyRing = getPublicKeyRing(keyId);
- if (keyRing == null) {
- return null;
- }
-
- return keyRing.getPublicKey(keyId);
- }
-
- public static Vector<Integer> getKeyRingIds(int type) {
- SQLiteDatabase db = mDatabase.db();
- Vector<Integer> keyIds = new Vector<Integer>();
- Cursor c = db.query(KeyRings.TABLE_NAME, new String[] { KeyRings._ID }, KeyRings.TYPE
- + " = ?", new String[] { "" + type }, null, null, null);
- if (c != null && c.moveToFirst()) {
- do {
- keyIds.add(c.getInt(0));
- } while (c.moveToNext());
- }
-
- if (c != null) {
- c.close();
- }
-
- return keyIds;
- }
-
- public static String getMainUserId(long keyId, int type) {
- SQLiteDatabase db = mDatabase.db();
- Cursor c = db.query(Keys.TABLE_NAME + " INNER JOIN " + KeyRings.TABLE_NAME + " ON ("
- + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME + "."
- + Keys.KEY_RING_ID + ") " + " INNER JOIN " + Keys.TABLE_NAME + " AS masterKey ON ("
- + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + "masterKey."
- + Keys.KEY_RING_ID + " AND " + "masterKey." + Keys.IS_MASTER_KEY + " = '1') "
- + " INNER JOIN " + UserIds.TABLE_NAME + " ON (" + UserIds.TABLE_NAME + "."
- + UserIds.KEY_ID + " = " + "masterKey." + Keys._ID + " AND " + UserIds.TABLE_NAME
- + "." + UserIds.RANK + " = '0')", new String[] { UserIds.USER_ID }, Keys.TABLE_NAME
- + "." + Keys.KEY_ID + " = ? AND " + KeyRings.TABLE_NAME + "." + KeyRings.TYPE
- + " = ?", new String[] { "" + keyId, "" + type, }, null, null, null);
- String userId = "";
- if (c != null && c.moveToFirst()) {
- do {
- userId = c.getString(0);
- } while (c.moveToNext());
- }
-
- if (c != null) {
- c.close();
- }
-
- return userId;
- }
-
- public static void encrypt(Context context, InputData data, OutputStream outStream,
- boolean armored, long encryptionKeyIds[], long signatureKeyId,
- String signaturePassPhrase, ProgressDialogUpdater progress, int symmetricAlgorithm,
- int hashAlgorithm, int compression, boolean forceV3Signature, String passPhrase)
- throws IOException, GeneralException, PGPException, NoSuchProviderException,
- NoSuchAlgorithmException, SignatureException {
-
- if (encryptionKeyIds == null) {
- encryptionKeyIds = new long[0];
- }
-
- ArmoredOutputStream armorOut = null;
- OutputStream out = null;
- OutputStream encryptOut = null;
- if (armored) {
- armorOut = new ArmoredOutputStream(outStream);
- armorOut.setHeader("Version", getFullVersion(context));
- out = armorOut;
- } else {
- out = outStream;
- }
- PGPSecretKey signingKey = null;
- PGPSecretKeyRing signingKeyRing = null;
- PGPPrivateKey signaturePrivateKey = null;
-
- if (encryptionKeyIds.length == 0 && passPhrase == null) {
- throw new GeneralException(
- context.getString(R.string.error_noEncryptionKeysOrPassPhrase));
- }
-
- if (signatureKeyId != Id.key.none) {
- signingKeyRing = getSecretKeyRing(signatureKeyId);
- signingKey = getSigningKey(signatureKeyId);
- if (signingKey == null) {
- throw new GeneralException(context.getString(R.string.error_signatureFailed));
- }
-
- if (signaturePassPhrase == null) {
- throw new GeneralException(context.getString(R.string.error_noSignaturePassPhrase));
- }
- if (progress != null)
- progress.setProgress(R.string.progress_extractingSignatureKey, 0, 100);
- PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
- "SC").build(signaturePassPhrase.toCharArray());
- signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
- if (signaturePrivateKey == null) {
- throw new GeneralException(
- context.getString(R.string.error_couldNotExtractPrivateKey));
- }
- }
- if (progress != null)
- progress.setProgress(R.string.progress_preparingStreams, 5, 100);
-
- // encrypt and compress input file content
- PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(symmetricAlgorithm, true,
- new SecureRandom(), new BouncyCastleProvider());
-
- if (encryptionKeyIds.length == 0) {
- // symmetric encryption
- Log.d(Constants.TAG, "encryptionKeyIds length is 0 -> symmetric encryption");
- cPk.addMethod(passPhrase.toCharArray());
- }
- for (int i = 0; i < encryptionKeyIds.length; ++i) {
- PGPPublicKey key = getEncryptPublicKey(encryptionKeyIds[i]);
- if (key != null) {
- cPk.addMethod(key);
- }
- }
- encryptOut = cPk.open(out, new byte[1 << 16]);
-
- PGPSignatureGenerator signatureGenerator = null;
- PGPV3SignatureGenerator signatureV3Generator = null;
-
- if (signatureKeyId != Id.key.none) {
- if (progress != null)
- progress.setProgress(R.string.progress_preparingSignature, 10, 100);
- if (forceV3Signature) {
- signatureV3Generator = new PGPV3SignatureGenerator(signingKey.getPublicKey()
- .getAlgorithm(), hashAlgorithm, new BouncyCastleProvider());
- signatureV3Generator.initSign(PGPSignature.BINARY_DOCUMENT, signaturePrivateKey);
- } else {
- signatureGenerator = new PGPSignatureGenerator(signingKey.getPublicKey()
- .getAlgorithm(), hashAlgorithm, new BouncyCastleProvider());
- signatureGenerator.initSign(PGPSignature.BINARY_DOCUMENT, signaturePrivateKey);
-
- String userId = getMainUserId(getMasterKey(signingKeyRing));
- PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
- spGen.setSignerUserID(false, userId);
- signatureGenerator.setHashedSubpackets(spGen.generate());
- }
- }
-
- PGPCompressedDataGenerator compressGen = null;
- BCPGOutputStream bcpgOut = null;
- if (compression == Id.choice.compression.none) {
- bcpgOut = new BCPGOutputStream(encryptOut);
- } else {
- compressGen = new PGPCompressedDataGenerator(compression);
- bcpgOut = new BCPGOutputStream(compressGen.open(encryptOut));
- }
- if (signatureKeyId != Id.key.none) {
- if (forceV3Signature) {
- signatureV3Generator.generateOnePassVersion(false).encode(bcpgOut);
- } else {
- signatureGenerator.generateOnePassVersion(false).encode(bcpgOut);
- }
- }
-
- PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator();
- // file name not needed, so empty string
- OutputStream pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "", new Date(),
- new byte[1 << 16]);
- if (progress != null)
- progress.setProgress(R.string.progress_encrypting, 20, 100);
-
- long done = 0;
- int n = 0;
- byte[] buffer = new byte[1 << 16];
- InputStream in = data.getInputStream();
- while ((n = in.read(buffer)) > 0) {
- pOut.write(buffer, 0, n);
- if (signatureKeyId != Id.key.none) {
- if (forceV3Signature) {
- signatureV3Generator.update(buffer, 0, n);
- } else {
- signatureGenerator.update(buffer, 0, n);
- }
- }
- done += n;
- if (data.getSize() != 0) {
- if (progress != null)
- progress.setProgress((int) (20 + (95 - 20) * done / data.getSize()), 100);
- }
- }
-
- literalGen.close();
-
- if (signatureKeyId != Id.key.none) {
- if (progress != null)
- progress.setProgress(R.string.progress_generatingSignature, 95, 100);
- if (forceV3Signature) {
- signatureV3Generator.generate().encode(pOut);
- } else {
- signatureGenerator.generate().encode(pOut);
- }
- }
- if (compressGen != null) {
- compressGen.close();
- }
- encryptOut.close();
- if (armored) {
- armorOut.close();
- }
-
- if (progress != null)
- progress.setProgress(R.string.progress_done, 100, 100);
- }
-
- public static void signText(Context context, InputData data, OutputStream outStream,
- long signatureKeyId, String signaturePassPhrase, int hashAlgorithm,
- boolean forceV3Signature, ProgressDialogUpdater progress) throws GeneralException,
- PGPException, IOException, NoSuchAlgorithmException, SignatureException {
-
- ArmoredOutputStream armorOut = new ArmoredOutputStream(outStream);
- armorOut.setHeader("Version", getFullVersion(context));
-
- PGPSecretKey signingKey = null;
- PGPSecretKeyRing signingKeyRing = null;
- PGPPrivateKey signaturePrivateKey = null;
-
- if (signatureKeyId == 0) {
- throw new GeneralException(context.getString(R.string.error_noSignatureKey));
- }
-
- signingKeyRing = getSecretKeyRing(signatureKeyId);
- signingKey = getSigningKey(signatureKeyId);
- if (signingKey == null) {
- throw new GeneralException(context.getString(R.string.error_signatureFailed));
- }
-
- if (signaturePassPhrase == null) {
- throw new GeneralException(context.getString(R.string.error_noSignaturePassPhrase));
- }
- PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
- .setProvider("SC").build(signaturePassPhrase.toCharArray());
- signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
- if (signaturePrivateKey == null) {
- throw new GeneralException(context.getString(R.string.error_couldNotExtractPrivateKey));
- }
- if (progress != null)
- progress.setProgress(R.string.progress_preparingStreams, 0, 100);
-
- if (progress != null)
- progress.setProgress(R.string.progress_preparingSignature, 30, 100);
-
- PGPSignatureGenerator signatureGenerator = null;
- PGPV3SignatureGenerator signatureV3Generator = null;
-
- if (forceV3Signature) {
- signatureV3Generator = new PGPV3SignatureGenerator(signingKey.getPublicKey()
- .getAlgorithm(), hashAlgorithm, new BouncyCastleProvider());
- signatureV3Generator
- .initSign(PGPSignature.CANONICAL_TEXT_DOCUMENT, signaturePrivateKey);
- } else {
- signatureGenerator = new PGPSignatureGenerator(
- signingKey.getPublicKey().getAlgorithm(), hashAlgorithm,
- new BouncyCastleProvider());
- signatureGenerator.initSign(PGPSignature.CANONICAL_TEXT_DOCUMENT, signaturePrivateKey);
-
- PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
- String userId = getMainUserId(getMasterKey(signingKeyRing));
- spGen.setSignerUserID(false, userId);
- signatureGenerator.setHashedSubpackets(spGen.generate());
- }
-
- if (progress != null)
- progress.setProgress(R.string.progress_signing, 40, 100);
-
- armorOut.beginClearText(hashAlgorithm);
-
- InputStream inStream = data.getInputStream();
- final BufferedReader reader = new BufferedReader(new InputStreamReader(inStream));
-
- final byte[] newline = "\r\n".getBytes("UTF-8");
-
- if (forceV3Signature) {
- processLine(reader.readLine(), armorOut, signatureV3Generator);
- } else {
- processLine(reader.readLine(), armorOut, signatureGenerator);
- }
-
- while (true) {
- final String line = reader.readLine();
-
- if (line == null) {
- armorOut.write(newline);
- break;
- }
-
- armorOut.write(newline);
- if (forceV3Signature) {
- signatureV3Generator.update(newline);
- processLine(line, armorOut, signatureV3Generator);
- } else {
- signatureGenerator.update(newline);
- processLine(line, armorOut, signatureGenerator);
- }
- }
-
- armorOut.endClearText();
-
- BCPGOutputStream bOut = new BCPGOutputStream(armorOut);
- if (forceV3Signature) {
- signatureV3Generator.generate().encode(bOut);
- } else {
- signatureGenerator.generate().encode(bOut);
- }
- armorOut.close();
-
- if (progress != null)
- progress.setProgress(R.string.progress_done, 100, 100);
- }
-
- public static void generateSignature(Context context, InputData data, OutputStream outStream,
- boolean armored, boolean binary, long signatureKeyId, String signaturePassPhrase,
- int hashAlgorithm, boolean forceV3Signature, ProgressDialogUpdater progress)
- throws GeneralException, PGPException, IOException, NoSuchAlgorithmException,
- SignatureException {
-
- ArmoredOutputStream armorOut = null;
- OutputStream out = null;
- if (armored) {
- armorOut = new ArmoredOutputStream(outStream);
- armorOut.setHeader("Version", getFullVersion(context));
- out = armorOut;
- } else {
- out = outStream;
- }
-
- PGPSecretKey signingKey = null;
- PGPSecretKeyRing signingKeyRing = null;
- PGPPrivateKey signaturePrivateKey = null;
-
- if (signatureKeyId == 0) {
- throw new GeneralException(context.getString(R.string.error_noSignatureKey));
- }
-
- signingKeyRing = getSecretKeyRing(signatureKeyId);
- signingKey = getSigningKey(signatureKeyId);
- if (signingKey == null) {
- throw new GeneralException(context.getString(R.string.error_signatureFailed));
- }
-
- if (signaturePassPhrase == null) {
- throw new GeneralException(context.getString(R.string.error_noSignaturePassPhrase));
- }
- PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
- .setProvider("SC").build(signaturePassPhrase.toCharArray());
- signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
- if (signaturePrivateKey == null) {
- throw new GeneralException(context.getString(R.string.error_couldNotExtractPrivateKey));
- }
- if (progress != null)
- progress.setProgress(R.string.progress_preparingStreams, 0, 100);
-
- if (progress != null)
- progress.setProgress(R.string.progress_preparingSignature, 30, 100);
-
- PGPSignatureGenerator signatureGenerator = null;
- PGPV3SignatureGenerator signatureV3Generator = null;
-
- int type = PGPSignature.CANONICAL_TEXT_DOCUMENT;
- if (binary) {
- type = PGPSignature.BINARY_DOCUMENT;
- }
-
- if (forceV3Signature) {
- signatureV3Generator = new PGPV3SignatureGenerator(signingKey.getPublicKey()
- .getAlgorithm(), hashAlgorithm, new BouncyCastleProvider());
- signatureV3Generator.initSign(type, signaturePrivateKey);
- } else {
- signatureGenerator = new PGPSignatureGenerator(
- signingKey.getPublicKey().getAlgorithm(), hashAlgorithm,
- new BouncyCastleProvider());
- signatureGenerator.initSign(type, signaturePrivateKey);
-
- PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
- String userId = getMainUserId(getMasterKey(signingKeyRing));
- spGen.setSignerUserID(false, userId);
- signatureGenerator.setHashedSubpackets(spGen.generate());
- }
-
- if (progress != null)
- progress.setProgress(R.string.progress_signing, 40, 100);
-
- InputStream inStream = data.getInputStream();
- if (binary) {
- byte[] buffer = new byte[1 << 16];
- int n = 0;
- while ((n = inStream.read(buffer)) > 0) {
- if (forceV3Signature) {
- signatureV3Generator.update(buffer, 0, n);
- } else {
- signatureGenerator.update(buffer, 0, n);
- }
- }
- } else {
- final BufferedReader reader = new BufferedReader(new InputStreamReader(inStream));
- final byte[] newline = "\r\n".getBytes("UTF-8");
-
- while (true) {
- final String line = reader.readLine();
-
- if (line == null) {
- break;
- }
-
- if (forceV3Signature) {
- processLine(line, null, signatureV3Generator);
- signatureV3Generator.update(newline);
- } else {
- processLine(line, null, signatureGenerator);
- signatureGenerator.update(newline);
- }
- }
- }
-
- BCPGOutputStream bOut = new BCPGOutputStream(out);
- if (forceV3Signature) {
- signatureV3Generator.generate().encode(bOut);
- } else {
- signatureGenerator.generate().encode(bOut);
- }
- out.close();
- outStream.close();
-
- if (progress != null)
- progress.setProgress(R.string.progress_done, 100, 100);
- }
-
- public static long getDecryptionKeyId(Context context, InputStream inputStream)
- throws GeneralException, NoAsymmetricEncryptionException, IOException {
- InputStream in = PGPUtil.getDecoderStream(inputStream);
- PGPObjectFactory pgpF = new PGPObjectFactory(in);
- PGPEncryptedDataList enc;
- Object o = pgpF.nextObject();
-
- // the first object might be a PGP marker packet.
- if (o instanceof PGPEncryptedDataList) {
- enc = (PGPEncryptedDataList) o;
- } else {
- enc = (PGPEncryptedDataList) pgpF.nextObject();
- }
-
- if (enc == null) {
- throw new GeneralException(context.getString(R.string.error_invalidData));
- }
-
- // TODO: currently we always only look at the first known key
- // find the secret key
- PGPSecretKey secretKey = null;
- Iterator<?> it = enc.getEncryptedDataObjects();
- boolean gotAsymmetricEncryption = false;
- while (it.hasNext()) {
- Object obj = it.next();
- if (obj instanceof PGPPublicKeyEncryptedData) {
- gotAsymmetricEncryption = true;
- PGPPublicKeyEncryptedData pbe = (PGPPublicKeyEncryptedData) obj;
- secretKey = getSecretKey(pbe.getKeyID());
- if (secretKey != null) {
- break;
- }
- }
- }
-
- if (!gotAsymmetricEncryption) {
- throw new NoAsymmetricEncryptionException();
- }
-
- if (secretKey == null) {
- return Id.key.none;
- }
-
- return secretKey.getKeyID();
- }
-
- public static boolean hasSymmetricEncryption(Context context, InputStream inputStream)
- throws GeneralException, IOException {
- InputStream in = PGPUtil.getDecoderStream(inputStream);
- PGPObjectFactory pgpF = new PGPObjectFactory(in);
- PGPEncryptedDataList enc;
- Object o = pgpF.nextObject();
-
- // the first object might be a PGP marker packet.
- if (o instanceof PGPEncryptedDataList) {
- enc = (PGPEncryptedDataList) o;
- } else {
- enc = (PGPEncryptedDataList) pgpF.nextObject();
- }
-
- if (enc == null) {
- throw new GeneralException(context.getString(R.string.error_invalidData));
- }
-
- Iterator<?> it = enc.getEncryptedDataObjects();
- while (it.hasNext()) {
- Object obj = it.next();
- if (obj instanceof PGPPBEEncryptedData) {
- return true;
- }
- }
-
- return false;
- }
-
- public static Bundle decrypt(Context context, InputData data, OutputStream outStream,
- String passPhrase, ProgressDialogUpdater progress, boolean assumeSymmetric)
- throws IOException, GeneralException, PGPException, SignatureException {
- if (passPhrase == null) {
- passPhrase = "";
- }
- Bundle returnData = new Bundle();
- InputStream in = PGPUtil.getDecoderStream(data.getInputStream());
- PGPObjectFactory pgpF = new PGPObjectFactory(in);
- PGPEncryptedDataList enc;
- Object o = pgpF.nextObject();
- long signatureKeyId = 0;
-
- int currentProgress = 0;
- if (progress != null)
- progress.setProgress(R.string.progress_readingData, currentProgress, 100);
-
- if (o instanceof PGPEncryptedDataList) {
- enc = (PGPEncryptedDataList) o;
- } else {
- enc = (PGPEncryptedDataList) pgpF.nextObject();
- }
-
- if (enc == null) {
- throw new GeneralException(context.getString(R.string.error_invalidData));
- }
-
- InputStream clear = null;
- PGPEncryptedData encryptedData = null;
-
- currentProgress += 5;
-
- // TODO: currently we always only look at the first known key or symmetric encryption,
- // there might be more...
- if (assumeSymmetric) {
- PGPPBEEncryptedData pbe = null;
- Iterator<?> it = enc.getEncryptedDataObjects();
- // find secret key
- while (it.hasNext()) {
- Object obj = it.next();
- if (obj instanceof PGPPBEEncryptedData) {
- pbe = (PGPPBEEncryptedData) obj;
- break;
- }
- }
-
- if (pbe == null) {
- throw new GeneralException(
- context.getString(R.string.error_noSymmetricEncryptionPacket));
- }
-
- if (progress != null)
- progress.setProgress(R.string.progress_preparingStreams, currentProgress, 100);
- clear = pbe.getDataStream(passPhrase.toCharArray(), new BouncyCastleProvider());
- encryptedData = pbe;
- currentProgress += 5;
- } else {
- if (progress != null)
- progress.setProgress(R.string.progress_findingKey, currentProgress, 100);
- PGPPublicKeyEncryptedData pbe = null;
- PGPSecretKey secretKey = null;
- Iterator<?> it = enc.getEncryptedDataObjects();
- // find secret key
- while (it.hasNext()) {
- Object obj = it.next();
- if (obj instanceof PGPPublicKeyEncryptedData) {
- PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj;
- secretKey = getSecretKey(encData.getKeyID());
- if (secretKey != null) {
- pbe = encData;
- break;
- }
- }
- }
-
- if (secretKey == null) {
- throw new GeneralException(context.getString(R.string.error_noSecretKeyFound));
- }
-
- currentProgress += 5;
- if (progress != null)
- progress.setProgress(R.string.progress_extractingKey, currentProgress, 100);
- PGPPrivateKey privateKey = null;
- try {
- PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
- .setProvider("SC").build(passPhrase.toCharArray());
- privateKey = secretKey.extractPrivateKey(keyDecryptor);
- } catch (PGPException e) {
- throw new PGPException(context.getString(R.string.error_wrongPassPhrase));
- }
- if (privateKey == null) {
- throw new GeneralException(
- context.getString(R.string.error_couldNotExtractPrivateKey));
- }
- currentProgress += 5;
- if (progress != null)
- progress.setProgress(R.string.progress_preparingStreams, currentProgress, 100);
- clear = pbe.getDataStream(privateKey, new BouncyCastleProvider());
- encryptedData = pbe;
- currentProgress += 5;
- }
-
- PGPObjectFactory plainFact = new PGPObjectFactory(clear);
- Object dataChunk = plainFact.nextObject();
- PGPOnePassSignature signature = null;
- PGPPublicKey signatureKey = null;
- int signatureIndex = -1;
-
- if (dataChunk instanceof PGPCompressedData) {
- if (progress != null)
- progress.setProgress(R.string.progress_decompressingData, currentProgress, 100);
- PGPObjectFactory fact = new PGPObjectFactory(
- ((PGPCompressedData) dataChunk).getDataStream());
- dataChunk = fact.nextObject();
- plainFact = fact;
- currentProgress += 10;
- }
-
- if (dataChunk instanceof PGPOnePassSignatureList) {
- if (progress != null)
- progress.setProgress(R.string.progress_processingSignature, currentProgress, 100);
- returnData.putBoolean(ApgService.EXTRA_SIGNATURE, true);
- PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk;
- for (int i = 0; i < sigList.size(); ++i) {
- signature = sigList.get(i);
- signatureKey = getPublicKey(signature.getKeyID());
- if (signatureKeyId == 0) {
- signatureKeyId = signature.getKeyID();
- }
- if (signatureKey == null) {
- signature = null;
- } else {
- signatureIndex = i;
- signatureKeyId = signature.getKeyID();
- String userId = null;
- PGPPublicKeyRing sigKeyRing = getPublicKeyRing(signatureKeyId);
- if (sigKeyRing != null) {
- userId = getMainUserId(getMasterKey(sigKeyRing));
- }
- returnData.putString(ApgService.EXTRA_SIGNATURE_USER_ID, userId);
- break;
- }
- }
-
- returnData.putLong(ApgService.EXTRA_SIGNATURE_KEY_ID, signatureKeyId);
-
- if (signature != null) {
- signature.initVerify(signatureKey, new BouncyCastleProvider());
- } else {
- returnData.putBoolean(ApgService.EXTRA_SIGNATURE_UNKNOWN, true);
- }
-
- dataChunk = plainFact.nextObject();
- currentProgress += 10;
- }
-
- if (dataChunk instanceof PGPSignatureList) {
- dataChunk = plainFact.nextObject();
- }
-
- if (dataChunk instanceof PGPLiteralData) {
- if (progress != null)
- progress.setProgress(R.string.progress_decrypting, currentProgress, 100);
- PGPLiteralData literalData = (PGPLiteralData) dataChunk;
- OutputStream out = outStream;
-
- byte[] buffer = new byte[1 << 16];
- InputStream dataIn = literalData.getInputStream();
-
- int startProgress = currentProgress;
- int endProgress = 100;
- if (signature != null) {
- endProgress = 90;
- } else if (encryptedData.isIntegrityProtected()) {
- endProgress = 95;
- }
- int n = 0;
- int done = 0;
- long startPos = data.getStreamPosition();
- while ((n = dataIn.read(buffer)) > 0) {
- out.write(buffer, 0, n);
- done += n;
- if (signature != null) {
- try {
- signature.update(buffer, 0, n);
- } catch (SignatureException e) {
- returnData.putBoolean(ApgService.EXTRA_SIGNATURE_SUCCESS, false);
- signature = null;
- }
- }
- // unknown size, but try to at least have a moving, slowing down progress bar
- currentProgress = startProgress + (endProgress - startProgress) * done
- / (done + 100000);
- if (data.getSize() - startPos == 0) {
- currentProgress = endProgress;
- } else {
- currentProgress = (int) (startProgress + (endProgress - startProgress)
- * (data.getStreamPosition() - startPos) / (data.getSize() - startPos));
- }
- if (progress != null)
- progress.setProgress(currentProgress, 100);
- }
-
- if (signature != null) {
- if (progress != null)
- progress.setProgress(R.string.progress_verifyingSignature, 90, 100);
- PGPSignatureList signatureList = (PGPSignatureList) plainFact.nextObject();
- PGPSignature messageSignature = signatureList.get(signatureIndex);
- if (signature.verify(messageSignature)) {
- returnData.putBoolean(ApgService.EXTRA_SIGNATURE_SUCCESS, true);
- } else {
- returnData.putBoolean(ApgService.EXTRA_SIGNATURE_SUCCESS, false);
- }
- }
- }
-
- // TODO: add integrity somewhere
- if (encryptedData.isIntegrityProtected()) {
- if (progress != null)
- progress.setProgress(R.string.progress_verifyingIntegrity, 95, 100);
- if (encryptedData.verify()) {
- // passed
- } else {
- // failed
- }
- } else {
- // no integrity check
- }
-
- if (progress != null)
- progress.setProgress(R.string.progress_done, 100, 100);
- return returnData;
- }
-
- public static Bundle verifyText(Context context, InputData data, OutputStream outStream,
- ProgressDialogUpdater progress) throws IOException, GeneralException, PGPException,
- SignatureException {
- Bundle returnData = new Bundle();
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- ArmoredInputStream aIn = new ArmoredInputStream(data.getInputStream());
-
- if (progress != null)
- progress.setProgress(R.string.progress_done, 0, 100);
-
- // mostly taken from ClearSignedFileProcessor
- ByteArrayOutputStream lineOut = new ByteArrayOutputStream();
- int lookAhead = readInputLine(lineOut, aIn);
- byte[] lineSep = getLineSeparator();
-
- byte[] line = lineOut.toByteArray();
- out.write(line, 0, getLengthWithoutSeparator(line));
- out.write(lineSep);
-
- while (lookAhead != -1 && aIn.isClearText()) {
- lookAhead = readInputLine(lineOut, lookAhead, aIn);
- line = lineOut.toByteArray();
- out.write(line, 0, getLengthWithoutSeparator(line));
- out.write(lineSep);
- }
-
- out.close();
-
- byte[] clearText = out.toByteArray();
- outStream.write(clearText);
-
- returnData.putBoolean(ApgService.EXTRA_SIGNATURE, true);
-
- if (progress != null)
- progress.setProgress(R.string.progress_processingSignature, 60, 100);
- PGPObjectFactory pgpFact = new PGPObjectFactory(aIn);
-
- PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject();
- if (sigList == null) {
- throw new GeneralException(context.getString(R.string.error_corruptData));
- }
- PGPSignature signature = null;
- long signatureKeyId = 0;
- PGPPublicKey signatureKey = null;
- for (int i = 0; i < sigList.size(); ++i) {
- signature = sigList.get(i);
- signatureKey = getPublicKey(signature.getKeyID());
- if (signatureKeyId == 0) {
- signatureKeyId = signature.getKeyID();
- }
- if (signatureKey == null) {
- // TODO: reimplement!
- // Bundle pauseData = new Bundle();
- // pauseData.putInt(Constants.extras.STATUS, Id.message.unknown_signature_key);
- // pauseData.putLong(Constants.extras.KEY_ID, signatureKeyId);
- // Message msg = new Message();
- // msg.setData(pauseData);
- // context.sendMessage(msg);
- // // pause here
- // context.getRunningThread().pause();
- // // see whether the key was found in the meantime
- // signatureKey = getPublicKey(signature.getKeyID());
- }
-
- if (signatureKey == null) {
- signature = null;
- } else {
- signatureKeyId = signature.getKeyID();
- String userId = null;
- PGPPublicKeyRing sigKeyRing = getPublicKeyRing(signatureKeyId);
- if (sigKeyRing != null) {
- userId = getMainUserId(getMasterKey(sigKeyRing));
- }
- returnData.putString(ApgService.EXTRA_SIGNATURE_USER_ID, userId);
- break;
- }
- }
-
- returnData.putLong(ApgService.EXTRA_SIGNATURE_KEY_ID, signatureKeyId);
-
- if (signature == null) {
- returnData.putBoolean(ApgService.EXTRA_SIGNATURE_UNKNOWN, true);
- if (progress != null)
- progress.setProgress(R.string.progress_done, 100, 100);
- return returnData;
- }
-
- signature.initVerify(signatureKey, new BouncyCastleProvider());
-
- InputStream sigIn = new BufferedInputStream(new ByteArrayInputStream(clearText));
-
- lookAhead = readInputLine(lineOut, sigIn);
-
- processLine(signature, lineOut.toByteArray());
-
- if (lookAhead != -1) {
- do {
- lookAhead = readInputLine(lineOut, lookAhead, sigIn);
-
- signature.update((byte) '\r');
- signature.update((byte) '\n');
-
- processLine(signature, lineOut.toByteArray());
- } while (lookAhead != -1);
- }
-
- returnData.putBoolean(ApgService.EXTRA_SIGNATURE_SUCCESS, signature.verify());
-
- if (progress != null)
- progress.setProgress(R.string.progress_done, 100, 100);
- return returnData;
- }
-
- public static int getStreamContent(Context context, InputStream inStream) throws IOException {
- InputStream in = PGPUtil.getDecoderStream(inStream);
- PGPObjectFactory pgpF = new PGPObjectFactory(in);
- Object object = pgpF.nextObject();
- while (object != null) {
- if (object instanceof PGPPublicKeyRing || object instanceof PGPSecretKeyRing) {
- return Id.content.keys;
- } else if (object instanceof PGPEncryptedDataList) {
- return Id.content.encrypted_data;
- }
- object = pgpF.nextObject();
- }
-
- return Id.content.unknown;
- }
-
- private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput,
- final PGPSignatureGenerator pSignatureGenerator) throws IOException, SignatureException {
-
- if (pLine == null) {
- return;
- }
-
- final char[] chars = pLine.toCharArray();
- int len = chars.length;
-
- while (len > 0) {
- if (!Character.isWhitespace(chars[len - 1])) {
- break;
- }
- len--;
- }
-
- final byte[] data = pLine.substring(0, len).getBytes("UTF-8");
-
- if (pArmoredOutput != null) {
- pArmoredOutput.write(data);
- }
- pSignatureGenerator.update(data);
- }
-
- private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput,
- final PGPV3SignatureGenerator pSignatureGenerator) throws IOException,
- SignatureException {
-
- if (pLine == null) {
- return;
- }
-
- final char[] chars = pLine.toCharArray();
- int len = chars.length;
-
- while (len > 0) {
- if (!Character.isWhitespace(chars[len - 1])) {
- break;
- }
- len--;
- }
-
- final byte[] data = pLine.substring(0, len).getBytes("UTF-8");
-
- if (pArmoredOutput != null) {
- pArmoredOutput.write(data);
- }
- pSignatureGenerator.update(data);
- }
-
- // taken from ClearSignedFileProcessor in BC
- private static void processLine(PGPSignature sig, byte[] line) throws SignatureException,
- IOException {
- int length = getLengthWithoutWhiteSpace(line);
- if (length > 0) {
- sig.update(line, 0, length);
- }
- }
-
- private static int readInputLine(ByteArrayOutputStream bOut, InputStream fIn)
- throws IOException {
- bOut.reset();
-
- int lookAhead = -1;
- int ch;
-
- while ((ch = fIn.read()) >= 0) {
- bOut.write(ch);
- if (ch == '\r' || ch == '\n') {
- lookAhead = readPassedEOL(bOut, ch, fIn);
- break;
- }
- }
-
- return lookAhead;
- }
-
- private static int readInputLine(ByteArrayOutputStream bOut, int lookAhead, InputStream fIn)
- throws IOException {
- bOut.reset();
-
- int ch = lookAhead;
-
- do {
- bOut.write(ch);
- if (ch == '\r' || ch == '\n') {
- lookAhead = readPassedEOL(bOut, ch, fIn);
- break;
- }
- } while ((ch = fIn.read()) >= 0);
-
- if (ch < 0) {
- lookAhead = -1;
- }
-
- return lookAhead;
- }
-
- private static int readPassedEOL(ByteArrayOutputStream bOut, int lastCh, InputStream fIn)
- throws IOException {
- int lookAhead = fIn.read();
-
- if (lastCh == '\r' && lookAhead == '\n') {
- bOut.write(lookAhead);
- lookAhead = fIn.read();
- }
-
- return lookAhead;
- }
-
- private static int getLengthWithoutSeparator(byte[] line) {
- int end = line.length - 1;
-
- while (end >= 0 && isLineEnding(line[end])) {
- end--;
- }
-
- return end + 1;
- }
-
- private static boolean isLineEnding(byte b) {
- return b == '\r' || b == '\n';
- }
-
- private static int getLengthWithoutWhiteSpace(byte[] line) {
- int end = line.length - 1;
-
- while (end >= 0 && isWhiteSpace(line[end])) {
- end--;
- }
-
- return end + 1;
- }
-
- private static boolean isWhiteSpace(byte b) {
- return b == '\r' || b == '\n' || b == '\t' || b == ' ';
- }
-
- private static byte[] getLineSeparator() {
- String nl = System.getProperty("line.separator");
- byte[] nlBytes = new byte[nl.length()];
-
- for (int i = 0; i != nlBytes.length; i++) {
- nlBytes[i] = (byte) nl.charAt(i);
- }
-
- return nlBytes;
- }
-
- public static boolean isReleaseVersion(Context context) {
- try {
- PackageInfo pi = context.getPackageManager().getPackageInfo(Constants.PACKAGE_NAME, 0);
- if (pi.versionCode % 100 == 99) {
- return true;
- } else {
- return false;
- }
- } catch (NameNotFoundException e) {
- // impossible!
- return false;
- }
- }
-
- public static String getVersion(Context context) {
- if (VERSION != null) {
- return VERSION;
- }
- try {
- PackageInfo pi = context.getPackageManager().getPackageInfo(Constants.PACKAGE_NAME, 0);
- VERSION = pi.versionName;
- return VERSION;
- } catch (NameNotFoundException e) {
- // impossible!
- return "0.0.0";
- }
- }
-
- public static String getFullVersion(Context context) {
- return "APG v" + getVersion(context);
- }
-
- public static String generateRandomString(int length) {
- SecureRandom random = new SecureRandom();
- /*
- * try { random = SecureRandom.getInstance("SHA1PRNG", new BouncyCastleProvider()); } catch
- * (NoSuchAlgorithmException e) { // TODO: need to handle this case somehow return null; }
- */
- byte bytes[] = new byte[length];
- random.nextBytes(bytes);
- String result = "";
- for (int i = 0; i < length; ++i) {
- int v = (bytes[i] + 256) % 64;
- if (v < 10) {
- result += (char) ('0' + v);
- } else if (v < 36) {
- result += (char) ('A' + v - 10);
- } else if (v < 62) {
- result += (char) ('a' + v - 36);
- } else if (v == 62) {
- result += '_';
- } else if (v == 63) {
- result += '.';
- }
- }
- return result;
- }
-
- public static long getLengthOfStream(InputStream in) throws IOException {
- long size = 0;
- long n = 0;
- byte dummy[] = new byte[0x10000];
- while ((n = in.read(dummy)) > 0) {
- size += n;
- }
- return size;
- }
-
- public static void deleteFileSecurely(Context context, File file, ProgressDialogUpdater progress)
- throws FileNotFoundException, IOException {
- long length = file.length();
- SecureRandom random = new SecureRandom();
- RandomAccessFile raf = new RandomAccessFile(file, "rws");
- raf.seek(0);
- raf.getFilePointer();
- byte[] data = new byte[1 << 16];
- int pos = 0;
- String msg = context.getString(R.string.progress_deletingSecurely, file.getName());
- while (pos < length) {
- if (progress != null)
- progress.setProgress(msg, (int) (100 * pos / length), 100);
- random.nextBytes(data);
- raf.write(data);
- pos += data.length;
- }
- raf.close();
- file.delete();
- }
}
diff --git a/org_apg/src/org/thialfihar/android/apg/helper/PGPMain.java b/org_apg/src/org/thialfihar/android/apg/helper/PGPMain.java
new file mode 100644
index 000000000..780fc47f2
--- /dev/null
+++ b/org_apg/src/org/thialfihar/android/apg/helper/PGPMain.java
@@ -0,0 +1,1971 @@
+/*
+ * Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.thialfihar.android.apg.helper;
+
+import org.spongycastle.bcpg.ArmoredInputStream;
+import org.spongycastle.bcpg.ArmoredOutputStream;
+import org.spongycastle.bcpg.BCPGOutputStream;
+import org.spongycastle.bcpg.CompressionAlgorithmTags;
+import org.spongycastle.bcpg.HashAlgorithmTags;
+import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
+import org.spongycastle.bcpg.sig.KeyFlags;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.jce.spec.ElGamalParameterSpec;
+import org.spongycastle.openpgp.PGPCompressedData;
+import org.spongycastle.openpgp.PGPCompressedDataGenerator;
+import org.spongycastle.openpgp.PGPEncryptedData;
+import org.spongycastle.openpgp.PGPEncryptedDataGenerator;
+import org.spongycastle.openpgp.PGPEncryptedDataList;
+import org.spongycastle.openpgp.PGPException;
+import org.spongycastle.openpgp.PGPKeyPair;
+import org.spongycastle.openpgp.PGPKeyRing;
+import org.spongycastle.openpgp.PGPKeyRingGenerator;
+import org.spongycastle.openpgp.PGPLiteralData;
+import org.spongycastle.openpgp.PGPLiteralDataGenerator;
+import org.spongycastle.openpgp.PGPObjectFactory;
+import org.spongycastle.openpgp.PGPOnePassSignature;
+import org.spongycastle.openpgp.PGPOnePassSignatureList;
+import org.spongycastle.openpgp.PGPPBEEncryptedData;
+import org.spongycastle.openpgp.PGPPrivateKey;
+import org.spongycastle.openpgp.PGPPublicKey;
+import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
+import org.spongycastle.openpgp.PGPPublicKeyRing;
+import org.spongycastle.openpgp.PGPSecretKey;
+import org.spongycastle.openpgp.PGPSecretKeyRing;
+import org.spongycastle.openpgp.PGPSignature;
+import org.spongycastle.openpgp.PGPSignatureGenerator;
+import org.spongycastle.openpgp.PGPSignatureList;
+import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
+import org.spongycastle.openpgp.PGPUtil;
+import org.spongycastle.openpgp.PGPV3SignatureGenerator;
+import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
+import org.spongycastle.openpgp.operator.PBESecretKeyEncryptor;
+import org.spongycastle.openpgp.operator.PGPContentSignerBuilder;
+import org.spongycastle.openpgp.operator.PGPDigestCalculator;
+import org.spongycastle.openpgp.operator.PublicKeyKeyEncryptionMethodGenerator;
+import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
+import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
+import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
+import org.spongycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator;
+import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
+import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
+import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
+import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
+import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
+import org.thialfihar.android.apg.passphrase.CachedPassPhrase;
+import org.thialfihar.android.apg.provider.DataProvider;
+import org.thialfihar.android.apg.provider.Database;
+import org.thialfihar.android.apg.provider.KeyRings;
+import org.thialfihar.android.apg.provider.Keys;
+import org.thialfihar.android.apg.provider.UserIds;
+import org.thialfihar.android.apg.service.ApgService;
+import org.thialfihar.android.apg.util.HkpKeyServer;
+import org.thialfihar.android.apg.util.InputData;
+import org.thialfihar.android.apg.util.PositionAwareInputStream;
+import org.thialfihar.android.apg.util.Primes;
+import org.thialfihar.android.apg.util.KeyServer.AddKeyException;
+import org.thialfihar.android.apg.Constants;
+import org.thialfihar.android.apg.Id;
+import org.thialfihar.android.apg.ProgressDialogUpdater;
+import org.thialfihar.android.apg.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.util.Log;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.SignatureException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Vector;
+import java.util.regex.Pattern;
+
+/**
+ * TODO:
+ *
+ * - Externalize the authority and content uri constants
+ *
+ * - Separate this file into different helpers
+ *
+ */
+public class PGPMain {
+
+ static {
+ // register spongy castle provider
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
+ // Not BC due to the use of Spongy Castle for Android
+ public static final String BOUNCY_CASTLE_PROVIDER_NAME = "SC";
+
+ public static final String AUTHORITY = DataProvider.AUTHORITY;
+
+ public static final Uri CONTENT_URI_SECRET_KEY_RINGS = Uri.parse("content://" + AUTHORITY
+ + "/key_rings/secret/");
+ public static final Uri CONTENT_URI_SECRET_KEY_RING_BY_KEY_ID = Uri.parse("content://"
+ + AUTHORITY + "/key_rings/secret/key_id/");
+ public static final Uri CONTENT_URI_SECRET_KEY_RING_BY_EMAILS = Uri.parse("content://"
+ + AUTHORITY + "/key_rings/secret/emails/");
+
+ public static final Uri CONTENT_URI_PUBLIC_KEY_RINGS = Uri.parse("content://" + AUTHORITY
+ + "/key_rings/public/");
+ public static final Uri CONTENT_URI_PUBLIC_KEY_RING_BY_KEY_ID = Uri.parse("content://"
+ + AUTHORITY + "/key_rings/public/key_id/");
+ public static final Uri CONTENT_URI_PUBLIC_KEY_RING_BY_EMAILS = Uri.parse("content://"
+ + AUTHORITY + "/key_rings/public/emails/");
+
+ private static String VERSION = null;
+
+ private static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[] {
+ SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192,
+ SymmetricKeyAlgorithmTags.AES_128, SymmetricKeyAlgorithmTags.CAST5,
+ SymmetricKeyAlgorithmTags.TRIPLE_DES };
+ private static final int[] PREFERRED_HASH_ALGORITHMS = new int[] { HashAlgorithmTags.SHA1,
+ HashAlgorithmTags.SHA256, HashAlgorithmTags.RIPEMD160 };
+ private static final int[] PREFERRED_COMPRESSION_ALGORITHMS = new int[] {
+ CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.BZIP2,
+ CompressionAlgorithmTags.ZIP };
+
+ public static Pattern PGP_MESSAGE = Pattern.compile(
+ ".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", Pattern.DOTALL);
+
+ public static Pattern PGP_SIGNED_MESSAGE = Pattern
+ .compile(
+ ".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*",
+ Pattern.DOTALL);
+
+ public static Pattern PGP_PUBLIC_KEY = Pattern.compile(
+ ".*?(-----BEGIN PGP PUBLIC KEY BLOCK-----.*?-----END PGP PUBLIC KEY BLOCK-----).*",
+ Pattern.DOTALL);
+
+ private static HashMap<Long, CachedPassPhrase> mPassPhraseCache = new HashMap<Long, CachedPassPhrase>();
+ private static String mEditPassPhrase = null;
+
+ private static Database mDatabase = null;
+
+ public static class GeneralException extends Exception {
+ static final long serialVersionUID = 0xf812773342L;
+
+ public GeneralException(String message) {
+ super(message);
+ }
+ }
+
+ public static class NoAsymmetricEncryptionException extends Exception {
+ static final long serialVersionUID = 0xf812773343L;
+
+ public NoAsymmetricEncryptionException() {
+ super();
+ }
+ }
+
+ public static void initialize(Context context) {
+ if (mDatabase == null) {
+ mDatabase = new Database(context);
+ }
+ }
+
+ public static Database getDatabase() {
+ return mDatabase;
+ }
+
+ public static void setEditPassPhrase(String passPhrase) {
+ mEditPassPhrase = passPhrase;
+ }
+
+ public static String getEditPassPhrase() {
+ return mEditPassPhrase;
+ }
+
+ public static void setCachedPassPhrase(long keyId, String passPhrase) {
+ mPassPhraseCache.put(keyId, new CachedPassPhrase(new Date().getTime(), passPhrase));
+ }
+
+ public static String getCachedPassPhrase(long keyId) {
+ long realId = keyId;
+ if (realId != Id.key.symmetric) {
+ PGPSecretKeyRing keyRing = getSecretKeyRing(keyId);
+ if (keyRing == null) {
+ return null;
+ }
+ PGPSecretKey masterKey = PGPHelper.getMasterKey(keyRing);
+ if (masterKey == null) {
+ return null;
+ }
+ realId = masterKey.getKeyID();
+ }
+ CachedPassPhrase cpp = mPassPhraseCache.get(realId);
+ if (cpp == null) {
+ return null;
+ }
+ // set it again to reset the cache life cycle
+ setCachedPassPhrase(realId, cpp.passPhrase);
+ return cpp.passPhrase;
+ }
+
+ public static int cleanUpCache(int ttl, int initialDelay) {
+ int delay = initialDelay;
+ long realTtl = ttl * 1000;
+ long now = new Date().getTime();
+ Vector<Long> oldKeys = new Vector<Long>();
+ for (Map.Entry<Long, CachedPassPhrase> pair : mPassPhraseCache.entrySet()) {
+ long lived = now - pair.getValue().timestamp;
+ if (lived >= realTtl) {
+ oldKeys.add(pair.getKey());
+ } else {
+ // see, whether the remaining time for this cache entry improves our
+ // check delay
+ long nextCheck = realTtl - lived + 1000;
+ if (nextCheck < delay) {
+ delay = (int) nextCheck;
+ }
+ }
+ }
+
+ for (long keyId : oldKeys) {
+ mPassPhraseCache.remove(keyId);
+ }
+
+ return delay;
+ }
+
+ /**
+ * Creates new secret key. The returned PGPSecretKeyRing contains only one newly generated key
+ * when this key is the new masterkey. If a masterkey is supplied in the parameters
+ * PGPSecretKeyRing contains the masterkey and the new key as a subkey (certified by the
+ * masterkey).
+ *
+ * @param context
+ * @param algorithmChoice
+ * @param keySize
+ * @param passPhrase
+ * @param masterSecretKey
+ * @return
+ * @throws NoSuchAlgorithmException
+ * @throws PGPException
+ * @throws NoSuchProviderException
+ * @throws GeneralException
+ * @throws InvalidAlgorithmParameterException
+ */
+ public static PGPSecretKeyRing createKey(Context context, int algorithmChoice, int keySize,
+ String passPhrase, PGPSecretKey masterSecretKey) throws NoSuchAlgorithmException,
+ PGPException, NoSuchProviderException, GeneralException,
+ InvalidAlgorithmParameterException {
+
+ if (keySize < 512) {
+ throw new GeneralException(context.getString(R.string.error_keySizeMinimum512bit));
+ }
+
+ if (passPhrase == null) {
+ passPhrase = "";
+ }
+
+ int algorithm = 0;
+ KeyPairGenerator keyGen = null;
+
+ switch (algorithmChoice) {
+ case Id.choice.algorithm.dsa: {
+ keyGen = KeyPairGenerator.getInstance("DSA", BOUNCY_CASTLE_PROVIDER_NAME);
+ keyGen.initialize(keySize, new SecureRandom());
+ algorithm = PGPPublicKey.DSA;
+ break;
+ }
+
+ case Id.choice.algorithm.elgamal: {
+ if (masterSecretKey == null) {
+ throw new GeneralException(
+ context.getString(R.string.error_masterKeyMustNotBeElGamal));
+ }
+ keyGen = KeyPairGenerator.getInstance("ELGAMAL", BOUNCY_CASTLE_PROVIDER_NAME);
+ BigInteger p = Primes.getBestPrime(keySize);
+ BigInteger g = new BigInteger("2");
+
+ ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g);
+
+ keyGen.initialize(elParams);
+ algorithm = PGPPublicKey.ELGAMAL_ENCRYPT;
+ break;
+ }
+
+ case Id.choice.algorithm.rsa: {
+ keyGen = KeyPairGenerator.getInstance("RSA", BOUNCY_CASTLE_PROVIDER_NAME);
+ keyGen.initialize(keySize, new SecureRandom());
+
+ algorithm = PGPPublicKey.RSA_GENERAL;
+ break;
+ }
+
+ default: {
+ throw new GeneralException(context.getString(R.string.error_unknownAlgorithmChoice));
+ }
+ }
+
+ // build new key pair
+ PGPKeyPair keyPair = new JcaPGPKeyPair(algorithm, keyGen.generateKeyPair(), new Date());
+
+ // define hashing and signing algos
+ PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(
+ HashAlgorithmTags.SHA1);
+ PGPContentSignerBuilder certificationSignerBuilder = new JcaPGPContentSignerBuilder(keyPair
+ .getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1);
+
+ // Build key encrypter and decrypter based on passphrase
+ PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
+ PGPEncryptedData.CAST5, sha1Calc).setProvider(BOUNCY_CASTLE_PROVIDER_NAME).build(
+ passPhrase.toCharArray());
+ PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
+ BOUNCY_CASTLE_PROVIDER_NAME).build(passPhrase.toCharArray());
+
+ PGPKeyRingGenerator ringGen = null;
+ if (masterSecretKey == null) {
+
+ // build keyRing with only this one master key in it!
+ ringGen = new PGPKeyRingGenerator(PGPSignature.DEFAULT_CERTIFICATION, keyPair, "",
+ sha1Calc, null, null, certificationSignerBuilder, keyEncryptor);
+ } else {
+ PGPPublicKey masterPublicKey = masterSecretKey.getPublicKey();
+ PGPPrivateKey masterPrivateKey = masterSecretKey.extractPrivateKey(keyDecryptor);
+ PGPKeyPair masterKeyPair = new PGPKeyPair(masterPublicKey, masterPrivateKey);
+
+ // build keyRing with master key and new key as subkey (certified by masterkey)
+ ringGen = new PGPKeyRingGenerator(PGPSignature.DEFAULT_CERTIFICATION, masterKeyPair,
+ "", sha1Calc, null, null, certificationSignerBuilder, keyEncryptor);
+
+ ringGen.addSubKey(keyPair);
+ }
+
+ PGPSecretKeyRing secKeyRing = ringGen.generateSecretKeyRing();
+
+ return secKeyRing;
+ }
+
+ public static void buildSecretKey(Context context, ArrayList<String> userIds,
+ ArrayList<PGPSecretKey> keys, ArrayList<Integer> keysUsages, long masterKeyId,
+ String oldPassPhrase, String newPassPhrase, ProgressDialogUpdater progress)
+ throws PGPMain.GeneralException, NoSuchProviderException, PGPException,
+ NoSuchAlgorithmException, SignatureException, IOException, Database.GeneralException {
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_buildingKey, 0, 100);
+
+ if (oldPassPhrase == null || oldPassPhrase.equals("")) {
+ oldPassPhrase = "";
+ }
+
+ if (newPassPhrase == null || newPassPhrase.equals("")) {
+ newPassPhrase = "";
+ }
+
+ // TODO: What is with this code?
+ // Vector<String> userIds = new Vector<String>();
+ // Vector<PGPSecretKey> keys = new Vector<PGPSecretKey>();
+
+ // ViewGroup userIdEditors = userIdsView.getEditors();
+ // ViewGroup keyEditors = keysView.getEditors();
+ //
+ // boolean gotMainUserId = false;
+ // for (int i = 0; i < userIdEditors.getChildCount(); ++i) {
+ // UserIdEditor editor = (UserIdEditor) userIdEditors.getChildAt(i);
+ // String userId = null;
+ // try {
+ // userId = editor.getValue();
+ // } catch (UserIdEditor.NoNameException e) {
+ // throw new Apg.GeneralException(context.getString(R.string.error_userIdNeedsAName));
+ // } catch (UserIdEditor.NoEmailException e) {
+ // throw new Apg.GeneralException(
+ // context.getString(R.string.error_userIdNeedsAnEmailAddress));
+ // } catch (UserIdEditor.InvalidEmailException e) {
+ // throw new Apg.GeneralException("" + e);
+ // }
+ //
+ // if (userId.equals("")) {
+ // continue;
+ // }
+ //
+ // if (editor.isMainUserId()) {
+ // userIds.insertElementAt(userId, 0);
+ // gotMainUserId = true;
+ // } else {
+ // userIds.add(userId);
+ // }
+ // }
+
+ // if (userIds.size() == 0) {
+ // throw new Apg.GeneralException(context.getString(R.string.error_keyNeedsAUserId));
+ // }
+ //
+ // if (!gotMainUserId) {
+ // throw new Apg.GeneralException(
+ // context.getString(R.string.error_mainUserIdMustNotBeEmpty));
+ // }
+
+ // if (keyEditors.getChildCount() == 0) {
+ // throw new Apg.GeneralException(context.getString(R.string.error_keyNeedsMasterKey));
+ // }
+ //
+ // for (int i = 0; i < keyEditors.getChildCount(); ++i) {
+ // KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
+ // keys.add(editor.getValue());
+ // }
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_preparingMasterKey, 10, 100);
+
+ int usageId = keysUsages.get(0);
+ boolean canSign = (usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt);
+ boolean canEncrypt = (usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt);
+
+ String mainUserId = userIds.get(0);
+
+ PGPSecretKey masterKey = keys.get(0);
+ PGPPublicKey masterPublicKey = masterKey.getPublicKey();
+
+ // TODO: why was this done?:
+ // PGPPublicKey tmpKey = masterKey.getPublicKey();
+ // PGPPublicKey masterPublicKey = new PGPPublicKey(tmpKey.getAlgorithm(),
+ // tmpKey.getKey(new BouncyCastleProvider()), tmpKey.getCreationTime());
+
+ PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
+ BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassPhrase.toCharArray());
+ PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(keyDecryptor);
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_certifyingMasterKey, 20, 100);
+ for (int i = 0; i < userIds.size(); ++i) {
+ String userId = userIds.get(i);
+
+ PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
+ masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1)
+ .setProvider(BOUNCY_CASTLE_PROVIDER_NAME);
+ PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
+
+ sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey);
+
+ PGPSignature certification = sGen.generateCertification(userId, masterPublicKey);
+
+ masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification);
+ }
+
+ // TODO: cross-certify the master key with every sub key
+
+ PGPKeyPair masterKeyPair = new PGPKeyPair(masterPublicKey, masterPrivateKey);
+
+ PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator();
+ PGPSignatureSubpacketGenerator unhashedPacketsGen = new PGPSignatureSubpacketGenerator();
+
+ int keyFlags = KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA;
+ if (canEncrypt) {
+ keyFlags |= KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE;
+ }
+ hashedPacketsGen.setKeyFlags(true, keyFlags);
+
+ hashedPacketsGen.setPreferredSymmetricAlgorithms(true, PREFERRED_SYMMETRIC_ALGORITHMS);
+ hashedPacketsGen.setPreferredHashAlgorithms(true, PREFERRED_HASH_ALGORITHMS);
+ hashedPacketsGen.setPreferredCompressionAlgorithms(true, PREFERRED_COMPRESSION_ALGORITHMS);
+
+ // TODO: this doesn't work quite right yet
+ // if (keyEditor.getExpiryDate() != null) {
+ // GregorianCalendar creationDate = new GregorianCalendar();
+ // creationDate.setTime(getCreationDate(masterKey));
+ // GregorianCalendar expiryDate = keyEditor.getExpiryDate();
+ // long numDays = Utils.getNumDaysBetween(creationDate, expiryDate);
+ // if (numDays <= 0) {
+ // throw new GeneralException(
+ // context.getString(R.string.error_expiryMustComeAfterCreation));
+ // }
+ // hashedPacketsGen.setKeyExpirationTime(true, numDays * 86400);
+ // }
+
+ if (progress != null) {
+ progress.setProgress(R.string.progress_buildingMasterKeyRing, 30, 100);
+ }
+
+ // deprecated method:
+ // PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION,
+ // masterKeyPair, mainUserId, PGPEncryptedData.CAST5, newPassPhrase.toCharArray(),
+ // hashedPacketsGen.generate(), unhashedPacketsGen.generate(), new SecureRandom(),
+ // new BouncyCastleProvider().getName());
+
+ // define hashing and signing algos
+ PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(
+ HashAlgorithmTags.SHA1);
+ PGPContentSignerBuilder certificationSignerBuilder = new JcaPGPContentSignerBuilder(
+ masterKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1);
+
+ // Build key encrypter based on passphrase
+ PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
+ PGPEncryptedData.CAST5, sha1Calc).setProvider(BOUNCY_CASTLE_PROVIDER_NAME).build(
+ newPassPhrase.toCharArray());
+
+ PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION,
+ masterKeyPair, mainUserId, sha1Calc, hashedPacketsGen.generate(),
+ unhashedPacketsGen.generate(), certificationSignerBuilder, keyEncryptor);
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_addingSubKeys, 40, 100);
+ for (int i = 1; i < keys.size(); ++i) {
+ if (progress != null)
+ progress.setProgress(40 + 50 * (i - 1) / (keys.size() - 1), 100);
+ PGPSecretKey subKey = keys.get(i);
+ PGPPublicKey subPublicKey = subKey.getPublicKey();
+
+ PBESecretKeyDecryptor keyDecryptor2 = new JcePBESecretKeyDecryptorBuilder()
+ .setProvider(BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassPhrase.toCharArray());
+ PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(keyDecryptor2);
+
+ // deprecated method:
+ // PGPKeyPair subKeyPair = new PGPKeyPair(subPublicKey.getAlgorithm(),
+ // subPublicKey.getKey(new BouncyCastleProvider()), subPrivateKey.getKey(),
+ // subPublicKey.getCreationTime());
+
+ // TODO: now used without algorithm and creation time?!
+ PGPKeyPair subKeyPair = new PGPKeyPair(subPublicKey, subPrivateKey);
+
+ hashedPacketsGen = new PGPSignatureSubpacketGenerator();
+ unhashedPacketsGen = new PGPSignatureSubpacketGenerator();
+
+ keyFlags = 0;
+
+ usageId = keysUsages.get(i);
+ canSign = (usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt);
+ canEncrypt = (usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt);
+ if (canSign) {
+ keyFlags |= KeyFlags.SIGN_DATA;
+ }
+ if (canEncrypt) {
+ keyFlags |= KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE;
+ }
+ hashedPacketsGen.setKeyFlags(true, keyFlags);
+
+ // TODO: this doesn't work quite right yet
+ // if (keyEditor.getExpiryDate() != null) {
+ // GregorianCalendar creationDate = new GregorianCalendar();
+ // creationDate.setTime(getCreationDate(masterKey));
+ // GregorianCalendar expiryDate = keyEditor.getExpiryDate();
+ // long numDays = Utils.getNumDaysBetween(creationDate, expiryDate);
+ // if (numDays <= 0) {
+ // throw new GeneralException(
+ // context.getString(R.string.error_expiryMustComeAfterCreation));
+ // }
+ // hashedPacketsGen.setKeyExpirationTime(true, numDays * 86400);
+ // }
+
+ keyGen.addSubKey(subKeyPair, hashedPacketsGen.generate(), unhashedPacketsGen.generate());
+ }
+
+ PGPSecretKeyRing secretKeyRing = keyGen.generateSecretKeyRing();
+ PGPPublicKeyRing publicKeyRing = keyGen.generatePublicKeyRing();
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_savingKeyRing, 90, 100);
+ mDatabase.saveKeyRing(secretKeyRing);
+ mDatabase.saveKeyRing(publicKeyRing);
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_done, 100, 100);
+ }
+
+ public static int storeKeyRingInCache(PGPKeyRing keyring) {
+ int status = Integer.MIN_VALUE; // out of bounds value (Id.retrun_value.*)
+ try {
+ if (keyring instanceof PGPSecretKeyRing) {
+ PGPSecretKeyRing secretKeyRing = (PGPSecretKeyRing) keyring;
+ boolean save = true;
+ try {
+ PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
+ .setProvider(BOUNCY_CASTLE_PROVIDER_NAME).build(new char[] {});
+ PGPPrivateKey testKey = secretKeyRing.getSecretKey().extractPrivateKey(
+ keyDecryptor);
+ if (testKey == null) {
+ // this is bad, something is very wrong... likely a --export-secret-subkeys
+ // export
+ save = false;
+ status = Id.return_value.bad;
+ }
+ } catch (PGPException e) {
+ // all good if this fails, we likely didn't use the right password
+ }
+
+ if (save) {
+ status = mDatabase.saveKeyRing(secretKeyRing);
+ }
+ } else if (keyring instanceof PGPPublicKeyRing) {
+ PGPPublicKeyRing publicKeyRing = (PGPPublicKeyRing) keyring;
+ status = mDatabase.saveKeyRing(publicKeyRing);
+ }
+ } catch (IOException e) {
+ status = Id.return_value.error;
+ } catch (Database.GeneralException e) {
+ status = Id.return_value.error;
+ }
+
+ return status;
+ }
+
+ public static boolean uploadKeyRingToServer(HkpKeyServer server, PGPPublicKeyRing keyring) {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ArmoredOutputStream aos = new ArmoredOutputStream(bos);
+ try {
+ aos.write(keyring.getEncoded());
+ aos.close();
+
+ String armouredKey = bos.toString("UTF-8");
+ server.add(armouredKey);
+
+ return true;
+ } catch (IOException e) {
+ return false;
+ } catch (AddKeyException e) {
+ // TODO: tell the user?
+ return false;
+ } finally {
+ try {
+ bos.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ public static Bundle importKeyRings(Activity context, int type, InputData data,
+ ProgressDialogUpdater progress) throws GeneralException, FileNotFoundException,
+ PGPException, IOException {
+ Bundle returnData = new Bundle();
+
+ if (type == Id.type.secret_key) {
+ if (progress != null)
+ progress.setProgress(R.string.progress_importingSecretKeys, 0, 100);
+ } else {
+ if (progress != null)
+ progress.setProgress(R.string.progress_importingPublicKeys, 0, 100);
+ }
+
+ if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+ throw new GeneralException(context.getString(R.string.error_externalStorageNotReady));
+ }
+
+ PositionAwareInputStream progressIn = new PositionAwareInputStream(data.getInputStream());
+ // need to have access to the bufferedInput, so we can reuse it for the possible
+ // PGPObject chunks after the first one, e.g. files with several consecutive ASCII
+ // armour blocks
+ BufferedInputStream bufferedInput = new BufferedInputStream(progressIn);
+ int newKeys = 0;
+ int oldKeys = 0;
+ int badKeys = 0;
+ try {
+ PGPKeyRing keyring = PGPHelper.decodeKeyRing(bufferedInput);
+ while (keyring != null) {
+ int status = Integer.MIN_VALUE; // out of bounds value
+
+ // if this key is what we expect it to be, save it
+ if ((type == Id.type.secret_key && keyring instanceof PGPSecretKeyRing)
+ || (type == Id.type.public_key && keyring instanceof PGPPublicKeyRing)) {
+ status = storeKeyRingInCache(keyring);
+ }
+
+ if (status == Id.return_value.error) {
+ throw new GeneralException(context.getString(R.string.error_savingKeys));
+ }
+
+ // update the counts to display to the user at the end
+ if (status == Id.return_value.updated) {
+ ++oldKeys;
+ } else if (status == Id.return_value.ok) {
+ ++newKeys;
+ } else if (status == Id.return_value.bad) {
+ ++badKeys;
+ }
+
+ if (progress != null) {
+ progress.setProgress((int) (100 * progressIn.position() / data.getSize()), 100);
+ }
+ // TODO: needed?
+ // obj = objectFactory.nextObject();
+
+ keyring = PGPHelper.decodeKeyRing(bufferedInput);
+ }
+ } catch (EOFException e) {
+ // nothing to do, we are done
+ }
+
+ returnData.putInt("added", newKeys);
+ returnData.putInt("updated", oldKeys);
+ returnData.putInt("bad", badKeys);
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_done, 100, 100);
+
+ return returnData;
+ }
+
+ public static Bundle exportKeyRings(Activity context, Vector<Integer> keyRingIds,
+ OutputStream outStream, ProgressDialogUpdater progress) throws GeneralException,
+ FileNotFoundException, PGPException, IOException {
+ Bundle returnData = new Bundle();
+
+ if (keyRingIds.size() == 1) {
+ if (progress != null)
+ progress.setProgress(R.string.progress_exportingKey, 0, 100);
+ } else {
+ if (progress != null)
+ progress.setProgress(R.string.progress_exportingKeys, 0, 100);
+ }
+
+ if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+ throw new GeneralException(context.getString(R.string.error_externalStorageNotReady));
+ }
+ ArmoredOutputStream out = new ArmoredOutputStream(outStream);
+
+ int numKeys = 0;
+ for (int i = 0; i < keyRingIds.size(); ++i) {
+ if (progress != null)
+ progress.setProgress(i * 100 / keyRingIds.size(), 100);
+ Object obj = mDatabase.getKeyRing(keyRingIds.get(i));
+ PGPPublicKeyRing publicKeyRing;
+ PGPSecretKeyRing secretKeyRing;
+
+ if (obj instanceof PGPSecretKeyRing) {
+ secretKeyRing = (PGPSecretKeyRing) obj;
+ secretKeyRing.encode(out);
+ } else if (obj instanceof PGPPublicKeyRing) {
+ publicKeyRing = (PGPPublicKeyRing) obj;
+ publicKeyRing.encode(out);
+ } else {
+ continue;
+ }
+ ++numKeys;
+ }
+ out.close();
+ returnData.putInt("exported", numKeys);
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_done, 100, 100);
+
+ return returnData;
+ }
+
+ public static void deleteKey(int keyRingId) {
+ mDatabase.deleteKeyRing(keyRingId);
+ }
+
+ public static PGPKeyRing getKeyRing(int keyRingId) {
+ return (PGPKeyRing) mDatabase.getKeyRing(keyRingId);
+ }
+
+ public static PGPSecretKeyRing getSecretKeyRing(long keyId) {
+ byte[] data = mDatabase.getKeyRingDataFromKeyId(Id.database.type_secret, keyId);
+ if (data == null) {
+ return null;
+ }
+ return PGPConversionHelper.BytesToPGPSecretKeyRing(data);
+
+ // deprecated method:
+ // try {
+ // return new PGPSecretKeyRing(data);
+ // } catch (IOException e) {
+ // // no good way to handle this, return null
+ // // TODO: some info?
+ // } catch (PGPException e) {
+ // // no good way to handle this, return null
+ // // TODO: some info?
+ // }
+ // return null;
+ }
+
+ public static PGPPublicKeyRing getPublicKeyRing(long keyId) {
+ byte[] data = mDatabase.getKeyRingDataFromKeyId(Id.database.type_public, keyId);
+ if (data == null) {
+ return null;
+ }
+ return PGPConversionHelper.BytesToPGPPublicKeyRing(data);
+
+ // deprecated method:
+ // try {
+ // return new PGPPublicKeyRing(data);
+ // } catch (IOException e) {
+ // // no good way to handle this, return null
+ // // TODO: some info?
+ // }
+ // return null;
+ }
+
+ public static PGPSecretKey getSecretKey(long keyId) {
+ PGPSecretKeyRing keyRing = getSecretKeyRing(keyId);
+ if (keyRing == null) {
+ return null;
+ }
+ return keyRing.getSecretKey(keyId);
+ }
+
+ public static PGPPublicKey getPublicKey(long keyId) {
+ PGPPublicKeyRing keyRing = getPublicKeyRing(keyId);
+ if (keyRing == null) {
+ return null;
+ }
+
+ return keyRing.getPublicKey(keyId);
+ }
+
+ public static Vector<Integer> getKeyRingIds(int type) {
+ SQLiteDatabase db = mDatabase.db();
+ Vector<Integer> keyIds = new Vector<Integer>();
+ Cursor c = db.query(KeyRings.TABLE_NAME, new String[] { KeyRings._ID }, KeyRings.TYPE
+ + " = ?", new String[] { "" + type }, null, null, null);
+ if (c != null && c.moveToFirst()) {
+ do {
+ keyIds.add(c.getInt(0));
+ } while (c.moveToNext());
+ }
+
+ if (c != null) {
+ c.close();
+ }
+
+ return keyIds;
+ }
+
+ public static String getMainUserId(long keyId, int type) {
+ SQLiteDatabase db = mDatabase.db();
+ Cursor c = db.query(Keys.TABLE_NAME + " INNER JOIN " + KeyRings.TABLE_NAME + " ON ("
+ + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME + "."
+ + Keys.KEY_RING_ID + ") " + " INNER JOIN " + Keys.TABLE_NAME + " AS masterKey ON ("
+ + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + "masterKey."
+ + Keys.KEY_RING_ID + " AND " + "masterKey." + Keys.IS_MASTER_KEY + " = '1') "
+ + " INNER JOIN " + UserIds.TABLE_NAME + " ON (" + UserIds.TABLE_NAME + "."
+ + UserIds.KEY_ID + " = " + "masterKey." + Keys._ID + " AND " + UserIds.TABLE_NAME
+ + "." + UserIds.RANK + " = '0')", new String[] { UserIds.USER_ID }, Keys.TABLE_NAME
+ + "." + Keys.KEY_ID + " = ? AND " + KeyRings.TABLE_NAME + "." + KeyRings.TYPE
+ + " = ?", new String[] { "" + keyId, "" + type, }, null, null, null);
+ String userId = "";
+ if (c != null && c.moveToFirst()) {
+ do {
+ userId = c.getString(0);
+ } while (c.moveToNext());
+ }
+
+ if (c != null) {
+ c.close();
+ }
+
+ return userId;
+ }
+
+ public static void encrypt(Context context, InputData data, OutputStream outStream,
+ boolean armored, long encryptionKeyIds[], long signatureKeyId,
+ String signaturePassPhrase, ProgressDialogUpdater progress, int symmetricAlgorithm,
+ int hashAlgorithm, int compression, boolean forceV3Signature, String passPhrase)
+ throws IOException, GeneralException, PGPException, NoSuchProviderException,
+ NoSuchAlgorithmException, SignatureException {
+
+ if (encryptionKeyIds == null) {
+ encryptionKeyIds = new long[0];
+ }
+
+ ArmoredOutputStream armorOut = null;
+ OutputStream out = null;
+ OutputStream encryptOut = null;
+ if (armored) {
+ armorOut = new ArmoredOutputStream(outStream);
+ armorOut.setHeader("Version", getFullVersion(context));
+ out = armorOut;
+ } else {
+ out = outStream;
+ }
+ PGPSecretKey signingKey = null;
+ PGPSecretKeyRing signingKeyRing = null;
+ PGPPrivateKey signaturePrivateKey = null;
+
+ if (encryptionKeyIds.length == 0 && passPhrase == null) {
+ throw new GeneralException(
+ context.getString(R.string.error_noEncryptionKeysOrPassPhrase));
+ }
+
+ if (signatureKeyId != Id.key.none) {
+ signingKeyRing = getSecretKeyRing(signatureKeyId);
+ signingKey = PGPHelper.getSigningKey(signatureKeyId);
+ if (signingKey == null) {
+ throw new GeneralException(context.getString(R.string.error_signatureFailed));
+ }
+
+ if (signaturePassPhrase == null) {
+ throw new GeneralException(context.getString(R.string.error_noSignaturePassPhrase));
+ }
+ if (progress != null)
+ progress.setProgress(R.string.progress_extractingSignatureKey, 0, 100);
+ PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
+ BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassPhrase.toCharArray());
+ signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
+ if (signaturePrivateKey == null) {
+ throw new GeneralException(
+ context.getString(R.string.error_couldNotExtractPrivateKey));
+ }
+ }
+ if (progress != null)
+ progress.setProgress(R.string.progress_preparingStreams, 5, 100);
+
+ // encrypt and compress input file content
+ JcePGPDataEncryptorBuilder encryptorBuilder = new JcePGPDataEncryptorBuilder(
+ symmetricAlgorithm).setProvider(BOUNCY_CASTLE_PROVIDER_NAME)
+ .setWithIntegrityPacket(true);
+
+ PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(encryptorBuilder);
+
+ // deprecated method:
+ // PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(symmetricAlgorithm, true,
+ // new SecureRandom(), new BouncyCastleProvider());
+
+ if (encryptionKeyIds.length == 0) {
+ // symmetric encryption
+ Log.d(Constants.TAG, "encryptionKeyIds length is 0 -> symmetric encryption");
+
+ JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator = new JcePBEKeyEncryptionMethodGenerator(
+ passPhrase.toCharArray());
+ cPk.addMethod(symmetricEncryptionGenerator);
+
+ // deprecated method:
+ // cPk.addMethod(passPhrase.toCharArray());
+ }
+ for (int i = 0; i < encryptionKeyIds.length; ++i) {
+ PGPPublicKey key = PGPHelper.getEncryptPublicKey(encryptionKeyIds[i]);
+ if (key != null) {
+
+ JcePublicKeyKeyEncryptionMethodGenerator pubKeyEncryptionGenerator = new JcePublicKeyKeyEncryptionMethodGenerator(
+ key);
+ cPk.addMethod(pubKeyEncryptionGenerator);
+
+ // deprecated method:
+ // cPk.addMethod(key);
+ }
+ }
+ encryptOut = cPk.open(out, new byte[1 << 16]);
+
+ PGPSignatureGenerator signatureGenerator = null;
+ PGPV3SignatureGenerator signatureV3Generator = null;
+
+ if (signatureKeyId != Id.key.none) {
+ if (progress != null)
+ progress.setProgress(R.string.progress_preparingSignature, 10, 100);
+ if (forceV3Signature) {
+ signatureV3Generator = new PGPV3SignatureGenerator(signingKey.getPublicKey()
+ .getAlgorithm(), hashAlgorithm, new BouncyCastleProvider());
+ signatureV3Generator.initSign(PGPSignature.BINARY_DOCUMENT, signaturePrivateKey);
+ } else {
+ signatureGenerator = new PGPSignatureGenerator(signingKey.getPublicKey()
+ .getAlgorithm(), hashAlgorithm, new BouncyCastleProvider());
+ signatureGenerator.initSign(PGPSignature.BINARY_DOCUMENT, signaturePrivateKey);
+
+ String userId = PGPHelper.getMainUserId(PGPHelper.getMasterKey(signingKeyRing));
+ PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
+ spGen.setSignerUserID(false, userId);
+ signatureGenerator.setHashedSubpackets(spGen.generate());
+ }
+ }
+
+ PGPCompressedDataGenerator compressGen = null;
+ BCPGOutputStream bcpgOut = null;
+ if (compression == Id.choice.compression.none) {
+ bcpgOut = new BCPGOutputStream(encryptOut);
+ } else {
+ compressGen = new PGPCompressedDataGenerator(compression);
+ bcpgOut = new BCPGOutputStream(compressGen.open(encryptOut));
+ }
+ if (signatureKeyId != Id.key.none) {
+ if (forceV3Signature) {
+ signatureV3Generator.generateOnePassVersion(false).encode(bcpgOut);
+ } else {
+ signatureGenerator.generateOnePassVersion(false).encode(bcpgOut);
+ }
+ }
+
+ PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator();
+ // file name not needed, so empty string
+ OutputStream pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "", new Date(),
+ new byte[1 << 16]);
+ if (progress != null)
+ progress.setProgress(R.string.progress_encrypting, 20, 100);
+
+ long done = 0;
+ int n = 0;
+ byte[] buffer = new byte[1 << 16];
+ InputStream in = data.getInputStream();
+ while ((n = in.read(buffer)) > 0) {
+ pOut.write(buffer, 0, n);
+ if (signatureKeyId != Id.key.none) {
+ if (forceV3Signature) {
+ signatureV3Generator.update(buffer, 0, n);
+ } else {
+ signatureGenerator.update(buffer, 0, n);
+ }
+ }
+ done += n;
+ if (data.getSize() != 0) {
+ if (progress != null)
+ progress.setProgress((int) (20 + (95 - 20) * done / data.getSize()), 100);
+ }
+ }
+
+ literalGen.close();
+
+ if (signatureKeyId != Id.key.none) {
+ if (progress != null)
+ progress.setProgress(R.string.progress_generatingSignature, 95, 100);
+ if (forceV3Signature) {
+ signatureV3Generator.generate().encode(pOut);
+ } else {
+ signatureGenerator.generate().encode(pOut);
+ }
+ }
+ if (compressGen != null) {
+ compressGen.close();
+ }
+ encryptOut.close();
+ if (armored) {
+ armorOut.close();
+ }
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_done, 100, 100);
+ }
+
+ public static void signText(Context context, InputData data, OutputStream outStream,
+ long signatureKeyId, String signaturePassPhrase, int hashAlgorithm,
+ boolean forceV3Signature, ProgressDialogUpdater progress) throws GeneralException,
+ PGPException, IOException, NoSuchAlgorithmException, SignatureException {
+
+ ArmoredOutputStream armorOut = new ArmoredOutputStream(outStream);
+ armorOut.setHeader("Version", getFullVersion(context));
+
+ PGPSecretKey signingKey = null;
+ PGPSecretKeyRing signingKeyRing = null;
+ PGPPrivateKey signaturePrivateKey = null;
+
+ if (signatureKeyId == 0) {
+ throw new GeneralException(context.getString(R.string.error_noSignatureKey));
+ }
+
+ signingKeyRing = getSecretKeyRing(signatureKeyId);
+ signingKey = PGPHelper.getSigningKey(signatureKeyId);
+ if (signingKey == null) {
+ throw new GeneralException(context.getString(R.string.error_signatureFailed));
+ }
+
+ if (signaturePassPhrase == null) {
+ throw new GeneralException(context.getString(R.string.error_noSignaturePassPhrase));
+ }
+ PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
+ BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassPhrase.toCharArray());
+ signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
+ if (signaturePrivateKey == null) {
+ throw new GeneralException(context.getString(R.string.error_couldNotExtractPrivateKey));
+ }
+ if (progress != null)
+ progress.setProgress(R.string.progress_preparingStreams, 0, 100);
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_preparingSignature, 30, 100);
+
+ PGPSignatureGenerator signatureGenerator = null;
+ PGPV3SignatureGenerator signatureV3Generator = null;
+
+ if (forceV3Signature) {
+ signatureV3Generator = new PGPV3SignatureGenerator(signingKey.getPublicKey()
+ .getAlgorithm(), hashAlgorithm, new BouncyCastleProvider());
+ signatureV3Generator
+ .initSign(PGPSignature.CANONICAL_TEXT_DOCUMENT, signaturePrivateKey);
+ } else {
+ signatureGenerator = new PGPSignatureGenerator(
+ signingKey.getPublicKey().getAlgorithm(), hashAlgorithm,
+ new BouncyCastleProvider());
+ signatureGenerator.initSign(PGPSignature.CANONICAL_TEXT_DOCUMENT, signaturePrivateKey);
+
+ PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
+ String userId = PGPHelper.getMainUserId(PGPHelper.getMasterKey(signingKeyRing));
+ spGen.setSignerUserID(false, userId);
+ signatureGenerator.setHashedSubpackets(spGen.generate());
+ }
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_signing, 40, 100);
+
+ armorOut.beginClearText(hashAlgorithm);
+
+ InputStream inStream = data.getInputStream();
+ final BufferedReader reader = new BufferedReader(new InputStreamReader(inStream));
+
+ final byte[] newline = "\r\n".getBytes("UTF-8");
+
+ if (forceV3Signature) {
+ processLine(reader.readLine(), armorOut, signatureV3Generator);
+ } else {
+ processLine(reader.readLine(), armorOut, signatureGenerator);
+ }
+
+ while (true) {
+ final String line = reader.readLine();
+
+ if (line == null) {
+ armorOut.write(newline);
+ break;
+ }
+
+ armorOut.write(newline);
+ if (forceV3Signature) {
+ signatureV3Generator.update(newline);
+ processLine(line, armorOut, signatureV3Generator);
+ } else {
+ signatureGenerator.update(newline);
+ processLine(line, armorOut, signatureGenerator);
+ }
+ }
+
+ armorOut.endClearText();
+
+ BCPGOutputStream bOut = new BCPGOutputStream(armorOut);
+ if (forceV3Signature) {
+ signatureV3Generator.generate().encode(bOut);
+ } else {
+ signatureGenerator.generate().encode(bOut);
+ }
+ armorOut.close();
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_done, 100, 100);
+ }
+
+ public static void generateSignature(Context context, InputData data, OutputStream outStream,
+ boolean armored, boolean binary, long signatureKeyId, String signaturePassPhrase,
+ int hashAlgorithm, boolean forceV3Signature, ProgressDialogUpdater progress)
+ throws GeneralException, PGPException, IOException, NoSuchAlgorithmException,
+ SignatureException {
+
+ ArmoredOutputStream armorOut = null;
+ OutputStream out = null;
+ if (armored) {
+ armorOut = new ArmoredOutputStream(outStream);
+ armorOut.setHeader("Version", getFullVersion(context));
+ out = armorOut;
+ } else {
+ out = outStream;
+ }
+
+ PGPSecretKey signingKey = null;
+ PGPSecretKeyRing signingKeyRing = null;
+ PGPPrivateKey signaturePrivateKey = null;
+
+ if (signatureKeyId == 0) {
+ throw new GeneralException(context.getString(R.string.error_noSignatureKey));
+ }
+
+ signingKeyRing = getSecretKeyRing(signatureKeyId);
+ signingKey = PGPHelper.getSigningKey(signatureKeyId);
+ if (signingKey == null) {
+ throw new GeneralException(context.getString(R.string.error_signatureFailed));
+ }
+
+ if (signaturePassPhrase == null) {
+ throw new GeneralException(context.getString(R.string.error_noSignaturePassPhrase));
+ }
+ PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
+ BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassPhrase.toCharArray());
+ signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
+ if (signaturePrivateKey == null) {
+ throw new GeneralException(context.getString(R.string.error_couldNotExtractPrivateKey));
+ }
+ if (progress != null)
+ progress.setProgress(R.string.progress_preparingStreams, 0, 100);
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_preparingSignature, 30, 100);
+
+ PGPSignatureGenerator signatureGenerator = null;
+ PGPV3SignatureGenerator signatureV3Generator = null;
+
+ int type = PGPSignature.CANONICAL_TEXT_DOCUMENT;
+ if (binary) {
+ type = PGPSignature.BINARY_DOCUMENT;
+ }
+
+ if (forceV3Signature) {
+ signatureV3Generator = new PGPV3SignatureGenerator(signingKey.getPublicKey()
+ .getAlgorithm(), hashAlgorithm, new BouncyCastleProvider());
+ signatureV3Generator.initSign(type, signaturePrivateKey);
+ } else {
+ signatureGenerator = new PGPSignatureGenerator(
+ signingKey.getPublicKey().getAlgorithm(), hashAlgorithm,
+ new BouncyCastleProvider());
+ signatureGenerator.initSign(type, signaturePrivateKey);
+
+ PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
+ String userId = PGPHelper.getMainUserId(PGPHelper.getMasterKey(signingKeyRing));
+ spGen.setSignerUserID(false, userId);
+ signatureGenerator.setHashedSubpackets(spGen.generate());
+ }
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_signing, 40, 100);
+
+ InputStream inStream = data.getInputStream();
+ if (binary) {
+ byte[] buffer = new byte[1 << 16];
+ int n = 0;
+ while ((n = inStream.read(buffer)) > 0) {
+ if (forceV3Signature) {
+ signatureV3Generator.update(buffer, 0, n);
+ } else {
+ signatureGenerator.update(buffer, 0, n);
+ }
+ }
+ } else {
+ final BufferedReader reader = new BufferedReader(new InputStreamReader(inStream));
+ final byte[] newline = "\r\n".getBytes("UTF-8");
+
+ while (true) {
+ final String line = reader.readLine();
+
+ if (line == null) {
+ break;
+ }
+
+ if (forceV3Signature) {
+ processLine(line, null, signatureV3Generator);
+ signatureV3Generator.update(newline);
+ } else {
+ processLine(line, null, signatureGenerator);
+ signatureGenerator.update(newline);
+ }
+ }
+ }
+
+ BCPGOutputStream bOut = new BCPGOutputStream(out);
+ if (forceV3Signature) {
+ signatureV3Generator.generate().encode(bOut);
+ } else {
+ signatureGenerator.generate().encode(bOut);
+ }
+ out.close();
+ outStream.close();
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_done, 100, 100);
+ }
+
+ public static long getDecryptionKeyId(Context context, InputStream inputStream)
+ throws GeneralException, NoAsymmetricEncryptionException, IOException {
+ InputStream in = PGPUtil.getDecoderStream(inputStream);
+ PGPObjectFactory pgpF = new PGPObjectFactory(in);
+ PGPEncryptedDataList enc;
+ Object o = pgpF.nextObject();
+
+ // the first object might be a PGP marker packet.
+ if (o instanceof PGPEncryptedDataList) {
+ enc = (PGPEncryptedDataList) o;
+ } else {
+ enc = (PGPEncryptedDataList) pgpF.nextObject();
+ }
+
+ if (enc == null) {
+ throw new GeneralException(context.getString(R.string.error_invalidData));
+ }
+
+ // TODO: currently we always only look at the first known key
+ // find the secret key
+ PGPSecretKey secretKey = null;
+ Iterator<?> it = enc.getEncryptedDataObjects();
+ boolean gotAsymmetricEncryption = false;
+ while (it.hasNext()) {
+ Object obj = it.next();
+ if (obj instanceof PGPPublicKeyEncryptedData) {
+ gotAsymmetricEncryption = true;
+ PGPPublicKeyEncryptedData pbe = (PGPPublicKeyEncryptedData) obj;
+ secretKey = getSecretKey(pbe.getKeyID());
+ if (secretKey != null) {
+ break;
+ }
+ }
+ }
+
+ if (!gotAsymmetricEncryption) {
+ throw new NoAsymmetricEncryptionException();
+ }
+
+ if (secretKey == null) {
+ return Id.key.none;
+ }
+
+ return secretKey.getKeyID();
+ }
+
+ public static boolean hasSymmetricEncryption(Context context, InputStream inputStream)
+ throws GeneralException, IOException {
+ InputStream in = PGPUtil.getDecoderStream(inputStream);
+ PGPObjectFactory pgpF = new PGPObjectFactory(in);
+ PGPEncryptedDataList enc;
+ Object o = pgpF.nextObject();
+
+ // the first object might be a PGP marker packet.
+ if (o instanceof PGPEncryptedDataList) {
+ enc = (PGPEncryptedDataList) o;
+ } else {
+ enc = (PGPEncryptedDataList) pgpF.nextObject();
+ }
+
+ if (enc == null) {
+ throw new GeneralException(context.getString(R.string.error_invalidData));
+ }
+
+ Iterator<?> it = enc.getEncryptedDataObjects();
+ while (it.hasNext()) {
+ Object obj = it.next();
+ if (obj instanceof PGPPBEEncryptedData) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static Bundle decrypt(Context context, InputData data, OutputStream outStream,
+ String passPhrase, ProgressDialogUpdater progress, boolean assumeSymmetric)
+ throws IOException, GeneralException, PGPException, SignatureException {
+ if (passPhrase == null) {
+ passPhrase = "";
+ }
+ Bundle returnData = new Bundle();
+ InputStream in = PGPUtil.getDecoderStream(data.getInputStream());
+ PGPObjectFactory pgpF = new PGPObjectFactory(in);
+ PGPEncryptedDataList enc;
+ Object o = pgpF.nextObject();
+ long signatureKeyId = 0;
+
+ int currentProgress = 0;
+ if (progress != null)
+ progress.setProgress(R.string.progress_readingData, currentProgress, 100);
+
+ if (o instanceof PGPEncryptedDataList) {
+ enc = (PGPEncryptedDataList) o;
+ } else {
+ enc = (PGPEncryptedDataList) pgpF.nextObject();
+ }
+
+ if (enc == null) {
+ throw new GeneralException(context.getString(R.string.error_invalidData));
+ }
+
+ InputStream clear = null;
+ PGPEncryptedData encryptedData = null;
+
+ currentProgress += 5;
+
+ // TODO: currently we always only look at the first known key or symmetric encryption,
+ // there might be more...
+ if (assumeSymmetric) {
+ PGPPBEEncryptedData pbe = null;
+ Iterator<?> it = enc.getEncryptedDataObjects();
+ // find secret key
+ while (it.hasNext()) {
+ Object obj = it.next();
+ if (obj instanceof PGPPBEEncryptedData) {
+ pbe = (PGPPBEEncryptedData) obj;
+ break;
+ }
+ }
+
+ if (pbe == null) {
+ throw new GeneralException(
+ context.getString(R.string.error_noSymmetricEncryptionPacket));
+ }
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_preparingStreams, currentProgress, 100);
+ clear = pbe.getDataStream(passPhrase.toCharArray(), new BouncyCastleProvider());
+ encryptedData = pbe;
+ currentProgress += 5;
+ } else {
+ if (progress != null)
+ progress.setProgress(R.string.progress_findingKey, currentProgress, 100);
+ PGPPublicKeyEncryptedData pbe = null;
+ PGPSecretKey secretKey = null;
+ Iterator<?> it = enc.getEncryptedDataObjects();
+ // find secret key
+ while (it.hasNext()) {
+ Object obj = it.next();
+ if (obj instanceof PGPPublicKeyEncryptedData) {
+ PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj;
+ secretKey = getSecretKey(encData.getKeyID());
+ if (secretKey != null) {
+ pbe = encData;
+ break;
+ }
+ }
+ }
+
+ if (secretKey == null) {
+ throw new GeneralException(context.getString(R.string.error_noSecretKeyFound));
+ }
+
+ currentProgress += 5;
+ if (progress != null)
+ progress.setProgress(R.string.progress_extractingKey, currentProgress, 100);
+ PGPPrivateKey privateKey = null;
+ try {
+ PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
+ .setProvider(BOUNCY_CASTLE_PROVIDER_NAME).build(passPhrase.toCharArray());
+ privateKey = secretKey.extractPrivateKey(keyDecryptor);
+ } catch (PGPException e) {
+ throw new PGPException(context.getString(R.string.error_wrongPassPhrase));
+ }
+ if (privateKey == null) {
+ throw new GeneralException(
+ context.getString(R.string.error_couldNotExtractPrivateKey));
+ }
+ currentProgress += 5;
+ if (progress != null)
+ progress.setProgress(R.string.progress_preparingStreams, currentProgress, 100);
+ clear = pbe.getDataStream(privateKey, new BouncyCastleProvider());
+ encryptedData = pbe;
+ currentProgress += 5;
+ }
+
+ PGPObjectFactory plainFact = new PGPObjectFactory(clear);
+ Object dataChunk = plainFact.nextObject();
+ PGPOnePassSignature signature = null;
+ PGPPublicKey signatureKey = null;
+ int signatureIndex = -1;
+
+ if (dataChunk instanceof PGPCompressedData) {
+ if (progress != null)
+ progress.setProgress(R.string.progress_decompressingData, currentProgress, 100);
+ PGPObjectFactory fact = new PGPObjectFactory(
+ ((PGPCompressedData) dataChunk).getDataStream());
+ dataChunk = fact.nextObject();
+ plainFact = fact;
+ currentProgress += 10;
+ }
+
+ if (dataChunk instanceof PGPOnePassSignatureList) {
+ if (progress != null)
+ progress.setProgress(R.string.progress_processingSignature, currentProgress, 100);
+ returnData.putBoolean(ApgService.EXTRA_SIGNATURE, true);
+ PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk;
+ for (int i = 0; i < sigList.size(); ++i) {
+ signature = sigList.get(i);
+ signatureKey = getPublicKey(signature.getKeyID());
+ if (signatureKeyId == 0) {
+ signatureKeyId = signature.getKeyID();
+ }
+ if (signatureKey == null) {
+ signature = null;
+ } else {
+ signatureIndex = i;
+ signatureKeyId = signature.getKeyID();
+ String userId = null;
+ PGPPublicKeyRing sigKeyRing = getPublicKeyRing(signatureKeyId);
+ if (sigKeyRing != null) {
+ userId = PGPHelper.getMainUserId(PGPHelper.getMasterKey(sigKeyRing));
+ }
+ returnData.putString(ApgService.EXTRA_SIGNATURE_USER_ID, userId);
+ break;
+ }
+ }
+
+ returnData.putLong(ApgService.EXTRA_SIGNATURE_KEY_ID, signatureKeyId);
+
+ if (signature != null) {
+ signature.initVerify(signatureKey, new BouncyCastleProvider());
+ } else {
+ returnData.putBoolean(ApgService.EXTRA_SIGNATURE_UNKNOWN, true);
+ }
+
+ dataChunk = plainFact.nextObject();
+ currentProgress += 10;
+ }
+
+ if (dataChunk instanceof PGPSignatureList) {
+ dataChunk = plainFact.nextObject();
+ }
+
+ if (dataChunk instanceof PGPLiteralData) {
+ if (progress != null)
+ progress.setProgress(R.string.progress_decrypting, currentProgress, 100);
+ PGPLiteralData literalData = (PGPLiteralData) dataChunk;
+ OutputStream out = outStream;
+
+ byte[] buffer = new byte[1 << 16];
+ InputStream dataIn = literalData.getInputStream();
+
+ int startProgress = currentProgress;
+ int endProgress = 100;
+ if (signature != null) {
+ endProgress = 90;
+ } else if (encryptedData.isIntegrityProtected()) {
+ endProgress = 95;
+ }
+ int n = 0;
+ int done = 0;
+ long startPos = data.getStreamPosition();
+ while ((n = dataIn.read(buffer)) > 0) {
+ out.write(buffer, 0, n);
+ done += n;
+ if (signature != null) {
+ try {
+ signature.update(buffer, 0, n);
+ } catch (SignatureException e) {
+ returnData.putBoolean(ApgService.EXTRA_SIGNATURE_SUCCESS, false);
+ signature = null;
+ }
+ }
+ // unknown size, but try to at least have a moving, slowing down progress bar
+ currentProgress = startProgress + (endProgress - startProgress) * done
+ / (done + 100000);
+ if (data.getSize() - startPos == 0) {
+ currentProgress = endProgress;
+ } else {
+ currentProgress = (int) (startProgress + (endProgress - startProgress)
+ * (data.getStreamPosition() - startPos) / (data.getSize() - startPos));
+ }
+ if (progress != null)
+ progress.setProgress(currentProgress, 100);
+ }
+
+ if (signature != null) {
+ if (progress != null)
+ progress.setProgress(R.string.progress_verifyingSignature, 90, 100);
+ PGPSignatureList signatureList = (PGPSignatureList) plainFact.nextObject();
+ PGPSignature messageSignature = signatureList.get(signatureIndex);
+ if (signature.verify(messageSignature)) {
+ returnData.putBoolean(ApgService.EXTRA_SIGNATURE_SUCCESS, true);
+ } else {
+ returnData.putBoolean(ApgService.EXTRA_SIGNATURE_SUCCESS, false);
+ }
+ }
+ }
+
+ // TODO: add integrity somewhere
+ if (encryptedData.isIntegrityProtected()) {
+ if (progress != null)
+ progress.setProgress(R.string.progress_verifyingIntegrity, 95, 100);
+ if (encryptedData.verify()) {
+ // passed
+ } else {
+ // failed
+ }
+ } else {
+ // no integrity check
+ }
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_done, 100, 100);
+ return returnData;
+ }
+
+ public static Bundle verifyText(Context context, InputData data, OutputStream outStream,
+ ProgressDialogUpdater progress) throws IOException, GeneralException, PGPException,
+ SignatureException {
+ Bundle returnData = new Bundle();
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ArmoredInputStream aIn = new ArmoredInputStream(data.getInputStream());
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_done, 0, 100);
+
+ // mostly taken from ClearSignedFileProcessor
+ ByteArrayOutputStream lineOut = new ByteArrayOutputStream();
+ int lookAhead = readInputLine(lineOut, aIn);
+ byte[] lineSep = getLineSeparator();
+
+ byte[] line = lineOut.toByteArray();
+ out.write(line, 0, getLengthWithoutSeparator(line));
+ out.write(lineSep);
+
+ while (lookAhead != -1 && aIn.isClearText()) {
+ lookAhead = readInputLine(lineOut, lookAhead, aIn);
+ line = lineOut.toByteArray();
+ out.write(line, 0, getLengthWithoutSeparator(line));
+ out.write(lineSep);
+ }
+
+ out.close();
+
+ byte[] clearText = out.toByteArray();
+ outStream.write(clearText);
+
+ returnData.putBoolean(ApgService.EXTRA_SIGNATURE, true);
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_processingSignature, 60, 100);
+ PGPObjectFactory pgpFact = new PGPObjectFactory(aIn);
+
+ PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject();
+ if (sigList == null) {
+ throw new GeneralException(context.getString(R.string.error_corruptData));
+ }
+ PGPSignature signature = null;
+ long signatureKeyId = 0;
+ PGPPublicKey signatureKey = null;
+ for (int i = 0; i < sigList.size(); ++i) {
+ signature = sigList.get(i);
+ signatureKey = getPublicKey(signature.getKeyID());
+ if (signatureKeyId == 0) {
+ signatureKeyId = signature.getKeyID();
+ }
+ if (signatureKey == null) {
+ // TODO: reimplement!
+ // Bundle pauseData = new Bundle();
+ // pauseData.putInt(Constants.extras.STATUS, Id.message.unknown_signature_key);
+ // pauseData.putLong(Constants.extras.KEY_ID, signatureKeyId);
+ // Message msg = new Message();
+ // msg.setData(pauseData);
+ // context.sendMessage(msg);
+ // // pause here
+ // context.getRunningThread().pause();
+ // // see whether the key was found in the meantime
+ // signatureKey = getPublicKey(signature.getKeyID());
+ }
+
+ if (signatureKey == null) {
+ signature = null;
+ } else {
+ signatureKeyId = signature.getKeyID();
+ String userId = null;
+ PGPPublicKeyRing sigKeyRing = getPublicKeyRing(signatureKeyId);
+ if (sigKeyRing != null) {
+ userId = PGPHelper.getMainUserId(PGPHelper.getMasterKey(sigKeyRing));
+ }
+ returnData.putString(ApgService.EXTRA_SIGNATURE_USER_ID, userId);
+ break;
+ }
+ }
+
+ returnData.putLong(ApgService.EXTRA_SIGNATURE_KEY_ID, signatureKeyId);
+
+ if (signature == null) {
+ returnData.putBoolean(ApgService.EXTRA_SIGNATURE_UNKNOWN, true);
+ if (progress != null)
+ progress.setProgress(R.string.progress_done, 100, 100);
+ return returnData;
+ }
+
+ signature.initVerify(signatureKey, new BouncyCastleProvider());
+
+ InputStream sigIn = new BufferedInputStream(new ByteArrayInputStream(clearText));
+
+ lookAhead = readInputLine(lineOut, sigIn);
+
+ processLine(signature, lineOut.toByteArray());
+
+ if (lookAhead != -1) {
+ do {
+ lookAhead = readInputLine(lineOut, lookAhead, sigIn);
+
+ signature.update((byte) '\r');
+ signature.update((byte) '\n');
+
+ processLine(signature, lineOut.toByteArray());
+ } while (lookAhead != -1);
+ }
+
+ returnData.putBoolean(ApgService.EXTRA_SIGNATURE_SUCCESS, signature.verify());
+
+ if (progress != null)
+ progress.setProgress(R.string.progress_done, 100, 100);
+ return returnData;
+ }
+
+ public static int getStreamContent(Context context, InputStream inStream) throws IOException {
+ InputStream in = PGPUtil.getDecoderStream(inStream);
+ PGPObjectFactory pgpF = new PGPObjectFactory(in);
+ Object object = pgpF.nextObject();
+ while (object != null) {
+ if (object instanceof PGPPublicKeyRing || object instanceof PGPSecretKeyRing) {
+ return Id.content.keys;
+ } else if (object instanceof PGPEncryptedDataList) {
+ return Id.content.encrypted_data;
+ }
+ object = pgpF.nextObject();
+ }
+
+ return Id.content.unknown;
+ }
+
+ private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput,
+ final PGPSignatureGenerator pSignatureGenerator) throws IOException, SignatureException {
+
+ if (pLine == null) {
+ return;
+ }
+
+ final char[] chars = pLine.toCharArray();
+ int len = chars.length;
+
+ while (len > 0) {
+ if (!Character.isWhitespace(chars[len - 1])) {
+ break;
+ }
+ len--;
+ }
+
+ final byte[] data = pLine.substring(0, len).getBytes("UTF-8");
+
+ if (pArmoredOutput != null) {
+ pArmoredOutput.write(data);
+ }
+ pSignatureGenerator.update(data);
+ }
+
+ private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput,
+ final PGPV3SignatureGenerator pSignatureGenerator) throws IOException,
+ SignatureException {
+
+ if (pLine == null) {
+ return;
+ }
+
+ final char[] chars = pLine.toCharArray();
+ int len = chars.length;
+
+ while (len > 0) {
+ if (!Character.isWhitespace(chars[len - 1])) {
+ break;
+ }
+ len--;
+ }
+
+ final byte[] data = pLine.substring(0, len).getBytes("UTF-8");
+
+ if (pArmoredOutput != null) {
+ pArmoredOutput.write(data);
+ }
+ pSignatureGenerator.update(data);
+ }
+
+ // taken from ClearSignedFileProcessor in BC
+ private static void processLine(PGPSignature sig, byte[] line) throws SignatureException,
+ IOException {
+ int length = getLengthWithoutWhiteSpace(line);
+ if (length > 0) {
+ sig.update(line, 0, length);
+ }
+ }
+
+ private static int readInputLine(ByteArrayOutputStream bOut, InputStream fIn)
+ throws IOException {
+ bOut.reset();
+
+ int lookAhead = -1;
+ int ch;
+
+ while ((ch = fIn.read()) >= 0) {
+ bOut.write(ch);
+ if (ch == '\r' || ch == '\n') {
+ lookAhead = readPassedEOL(bOut, ch, fIn);
+ break;
+ }
+ }
+
+ return lookAhead;
+ }
+
+ private static int readInputLine(ByteArrayOutputStream bOut, int lookAhead, InputStream fIn)
+ throws IOException {
+ bOut.reset();
+
+ int ch = lookAhead;
+
+ do {
+ bOut.write(ch);
+ if (ch == '\r' || ch == '\n') {
+ lookAhead = readPassedEOL(bOut, ch, fIn);
+ break;
+ }
+ } while ((ch = fIn.read()) >= 0);
+
+ if (ch < 0) {
+ lookAhead = -1;
+ }
+
+ return lookAhead;
+ }
+
+ private static int readPassedEOL(ByteArrayOutputStream bOut, int lastCh, InputStream fIn)
+ throws IOException {
+ int lookAhead = fIn.read();
+
+ if (lastCh == '\r' && lookAhead == '\n') {
+ bOut.write(lookAhead);
+ lookAhead = fIn.read();
+ }
+
+ return lookAhead;
+ }
+
+ private static int getLengthWithoutSeparator(byte[] line) {
+ int end = line.length - 1;
+
+ while (end >= 0 && isLineEnding(line[end])) {
+ end--;
+ }
+
+ return end + 1;
+ }
+
+ private static boolean isLineEnding(byte b) {
+ return b == '\r' || b == '\n';
+ }
+
+ private static int getLengthWithoutWhiteSpace(byte[] line) {
+ int end = line.length - 1;
+
+ while (end >= 0 && isWhiteSpace(line[end])) {
+ end--;
+ }
+
+ return end + 1;
+ }
+
+ private static boolean isWhiteSpace(byte b) {
+ return b == '\r' || b == '\n' || b == '\t' || b == ' ';
+ }
+
+ private static byte[] getLineSeparator() {
+ String nl = System.getProperty("line.separator");
+ byte[] nlBytes = new byte[nl.length()];
+
+ for (int i = 0; i != nlBytes.length; i++) {
+ nlBytes[i] = (byte) nl.charAt(i);
+ }
+
+ return nlBytes;
+ }
+
+ public static boolean isReleaseVersion(Context context) {
+ try {
+ PackageInfo pi = context.getPackageManager().getPackageInfo(Constants.PACKAGE_NAME, 0);
+ if (pi.versionCode % 100 == 99) {
+ return true;
+ } else {
+ return false;
+ }
+ } catch (NameNotFoundException e) {
+ // impossible!
+ return false;
+ }
+ }
+
+ public static String getVersion(Context context) {
+ if (VERSION != null) {
+ return VERSION;
+ }
+ try {
+ PackageInfo pi = context.getPackageManager().getPackageInfo(Constants.PACKAGE_NAME, 0);
+ VERSION = pi.versionName;
+ return VERSION;
+ } catch (NameNotFoundException e) {
+ // impossible!
+ return "0.0.0";
+ }
+ }
+
+ public static String getFullVersion(Context context) {
+ return "APG v" + getVersion(context);
+ }
+
+ public static String generateRandomString(int length) {
+ SecureRandom random = new SecureRandom();
+ /*
+ * try { random = SecureRandom.getInstance("SHA1PRNG", new BouncyCastleProvider()); } catch
+ * (NoSuchAlgorithmException e) { // TODO: need to handle this case somehow return null; }
+ */
+ byte bytes[] = new byte[length];
+ random.nextBytes(bytes);
+ String result = "";
+ for (int i = 0; i < length; ++i) {
+ int v = (bytes[i] + 256) % 64;
+ if (v < 10) {
+ result += (char) ('0' + v);
+ } else if (v < 36) {
+ result += (char) ('A' + v - 10);
+ } else if (v < 62) {
+ result += (char) ('a' + v - 36);
+ } else if (v == 62) {
+ result += '_';
+ } else if (v == 63) {
+ result += '.';
+ }
+ }
+ return result;
+ }
+
+ public static long getLengthOfStream(InputStream in) throws IOException {
+ long size = 0;
+ long n = 0;
+ byte dummy[] = new byte[0x10000];
+ while ((n = in.read(dummy)) > 0) {
+ size += n;
+ }
+ return size;
+ }
+
+ public static void deleteFileSecurely(Context context, File file, ProgressDialogUpdater progress)
+ throws FileNotFoundException, IOException {
+ long length = file.length();
+ SecureRandom random = new SecureRandom();
+ RandomAccessFile raf = new RandomAccessFile(file, "rws");
+ raf.seek(0);
+ raf.getFilePointer();
+ byte[] data = new byte[1 << 16];
+ int pos = 0;
+ String msg = context.getString(R.string.progress_deletingSecurely, file.getName());
+ while (pos < length) {
+ if (progress != null)
+ progress.setProgress(msg, (int) (100 * pos / length), 100);
+ random.nextBytes(data);
+ raf.write(data);
+ pos += data.length;
+ }
+ raf.close();
+ file.delete();
+ }
+}
diff --git a/org_apg/src/org/thialfihar/android/apg/passphrase/AskForPassphrase.java b/org_apg/src/org/thialfihar/android/apg/passphrase/AskForPassphrase.java
index 5711a16a8..4e7bdd70f 100644
--- a/org_apg/src/org/thialfihar/android/apg/passphrase/AskForPassphrase.java
+++ b/org_apg/src/org/thialfihar/android/apg/passphrase/AskForPassphrase.java
@@ -23,6 +23,7 @@ import org.spongycastle.openpgp.PGPSecretKey;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.R;
import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import android.app.Activity;
import android.app.AlertDialog;
@@ -55,7 +56,7 @@ public class AskForPassphrase {
secretKey = null;
alert.setMessage(context.getString(R.string.passPhraseForSymmetricEncryption));
} else {
- secretKey = PGPHelper.getMasterKey(PGPHelper.getSecretKeyRing(secretKeyId));
+ secretKey = PGPHelper.getMasterKey(PGPMain.getSecretKeyRing(secretKeyId));
if (secretKey == null) {
alert.setTitle(R.string.title_keyNotFound);
alert.setMessage(context.getString(R.string.keyNotFound, secretKeyId));
@@ -111,7 +112,7 @@ public class AskForPassphrase {
}
// cache again
- PGPHelper.setCachedPassPhrase(keyId, passPhrase);
+ PGPMain.setCachedPassPhrase(keyId, passPhrase);
// return by callback
cb.passPhraseCallback(keyId, passPhrase);
}
@@ -133,7 +134,7 @@ public class AskForPassphrase {
Log.d("APG", "Key has no passphrase!");
// cache null
- PGPHelper.setCachedPassPhrase(secretKey.getKeyID(), null);
+ PGPMain.setCachedPassPhrase(secretKey.getKeyID(), null);
// return by callback
cb.passPhraseCallback(secretKey.getKeyID(), null);
diff --git a/org_apg/src/org/thialfihar/android/apg/passphrase/PassphraseCacheService.java b/org_apg/src/org/thialfihar/android/apg/passphrase/PassphraseCacheService.java
index 9325268fa..c7758cb4f 100644
--- a/org_apg/src/org/thialfihar/android/apg/passphrase/PassphraseCacheService.java
+++ b/org_apg/src/org/thialfihar/android/apg/passphrase/PassphraseCacheService.java
@@ -14,7 +14,7 @@
package org.thialfihar.android.apg.passphrase;
-import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.helper.Preferences;
import android.app.Service;
@@ -47,7 +47,7 @@ public class PassphraseCacheService extends Service {
delay = 60000;
}
- delay = PGPHelper.cleanUpCache(mPassPhraseCacheTtl, delay);
+ delay = PGPMain.cleanUpCache(mPassPhraseCacheTtl, delay);
// don't check too often, even if we were close
if (delay < 5000) {
delay = 5000;
diff --git a/org_apg/src/org/thialfihar/android/apg/service/ApgService.java b/org_apg/src/org/thialfihar/android/apg/service/ApgService.java
index 43b13ba77..7f5ee1272 100644
--- a/org_apg/src/org/thialfihar/android/apg/service/ApgService.java
+++ b/org_apg/src/org/thialfihar/android/apg/service/ApgService.java
@@ -33,9 +33,9 @@ import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.ProgressDialogUpdater;
import org.thialfihar.android.apg.R;
import org.thialfihar.android.apg.helper.FileHelper;
-import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.helper.Preferences;
-import org.thialfihar.android.apg.helper.PGPHelper.GeneralException;
+import org.thialfihar.android.apg.helper.PGPMain.GeneralException;
import org.thialfihar.android.apg.helper.PGPConversionHelper;
import org.thialfihar.android.apg.provider.DataProvider;
import org.thialfihar.android.apg.util.InputData;
@@ -197,9 +197,9 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
long masterKeyId = data.getLong(MASTER_KEY_ID);
/* Operation */
- PGPHelper.buildSecretKey(this, userIds, keys, keysUsages, masterKeyId,
+ PGPMain.buildSecretKey(this, userIds, keys, keysUsages, masterKeyId,
oldPassPhrase, newPassPhrase, this);
- PGPHelper.setCachedPassPhrase(masterKeyId, newPassPhrase);
+ PGPMain.setCachedPassPhrase(masterKeyId, newPassPhrase);
/* Output */
sendMessageToHandler(ApgHandler.MESSAGE_OKAY);
@@ -223,7 +223,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
}
/* Operation */
- PGPSecretKeyRing newKeyRing = PGPHelper.createKey(this, algorithm, keysize,
+ PGPSecretKeyRing newKeyRing = PGPMain.createKey(this, algorithm, keysize,
passphrase, masterKey);
/* Output */
@@ -244,10 +244,10 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
String passphrase = data.getString(SYMMETRIC_PASSPHRASE);
/* Operation */
- PGPSecretKeyRing masterKeyRing = PGPHelper.createKey(this, Id.choice.algorithm.rsa,
+ PGPSecretKeyRing masterKeyRing = PGPMain.createKey(this, Id.choice.algorithm.rsa,
2048, passphrase, null);
- PGPSecretKeyRing subKeyRing = PGPHelper.createKey(this, Id.choice.algorithm.rsa,
+ PGPSecretKeyRing subKeyRing = PGPMain.createKey(this, Id.choice.algorithm.rsa,
2048, passphrase, masterKeyRing.getSecretKey());
/* Output */
@@ -288,20 +288,20 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
if (generateSignature) {
Log.d(Constants.TAG, "generate signature...");
- PGPHelper.generateSignature(this, inputData, outStream, useAsciiArmour, false,
- secretKeyId, PGPHelper.getCachedPassPhrase(secretKeyId), Preferences
+ PGPMain.generateSignature(this, inputData, outStream, useAsciiArmour, false,
+ secretKeyId, PGPMain.getCachedPassPhrase(secretKeyId), Preferences
.getPreferences(this).getDefaultHashAlgorithm(), Preferences
.getPreferences(this).getForceV3Signatures(), this);
} else if (signOnly) {
Log.d(Constants.TAG, "sign only...");
- PGPHelper.signText(this, inputData, outStream, secretKeyId, PGPHelper
+ PGPMain.signText(this, inputData, outStream, secretKeyId, PGPMain
.getCachedPassPhrase(secretKeyId), Preferences.getPreferences(this)
.getDefaultHashAlgorithm(), Preferences.getPreferences(this)
.getForceV3Signatures(), this);
} else {
Log.d(Constants.TAG, "encrypt...");
- PGPHelper.encrypt(this, inputData, outStream, useAsciiArmour, encryptionKeyIds,
- signatureKeyId, PGPHelper.getCachedPassPhrase(signatureKeyId), this,
+ PGPMain.encrypt(this, inputData, outStream, useAsciiArmour, encryptionKeyIds,
+ signatureKeyId, PGPMain.getCachedPassPhrase(signatureKeyId), this,
Preferences.getPreferences(this).getDefaultEncryptionAlgorithm(),
Preferences.getPreferences(this).getDefaultHashAlgorithm(),
compressionId, Preferences.getPreferences(this).getForceV3Signatures(),
@@ -373,20 +373,20 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
if (generateSignature) {
Log.d(Constants.TAG, "generate signature...");
- PGPHelper.generateSignature(this, inputData, outStream, useAsciiArmour, true,
- secretKeyId, PGPHelper.getCachedPassPhrase(secretKeyId), Preferences
+ PGPMain.generateSignature(this, inputData, outStream, useAsciiArmour, true,
+ secretKeyId, PGPMain.getCachedPassPhrase(secretKeyId), Preferences
.getPreferences(this).getDefaultHashAlgorithm(), Preferences
.getPreferences(this).getForceV3Signatures(), this);
} else if (signOnly) {
Log.d(Constants.TAG, "sign only...");
- PGPHelper.signText(this, inputData, outStream, secretKeyId, PGPHelper
+ PGPMain.signText(this, inputData, outStream, secretKeyId, PGPMain
.getCachedPassPhrase(secretKeyId), Preferences.getPreferences(this)
.getDefaultHashAlgorithm(), Preferences.getPreferences(this)
.getForceV3Signatures(), this);
} else {
Log.d(Constants.TAG, "encrypt...");
- PGPHelper.encrypt(this, inputData, outStream, useAsciiArmour, encryptionKeyIds,
- signatureKeyId, PGPHelper.getCachedPassPhrase(signatureKeyId), this,
+ PGPMain.encrypt(this, inputData, outStream, useAsciiArmour, encryptionKeyIds,
+ signatureKeyId, PGPMain.getCachedPassPhrase(signatureKeyId), this,
Preferences.getPreferences(this).getDefaultEncryptionAlgorithm(),
Preferences.getPreferences(this).getDefaultHashAlgorithm(),
compressionId, Preferences.getPreferences(this).getForceV3Signatures(),
@@ -420,16 +420,16 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
/* Operation */
// InputStream
InputStream in = getContentResolver().openInputStream(providerUri);
- long inLength = PGPHelper.getLengthOfStream(in);
+ long inLength = PGPMain.getLengthOfStream(in);
InputData inputData = new InputData(in, inLength);
// OutputStream
String streamFilename = null;
try {
while (true) {
- streamFilename = PGPHelper.generateRandomString(32);
+ streamFilename = PGPMain.generateRandomString(32);
if (streamFilename == null) {
- throw new PGPHelper.GeneralException(
+ throw new PGPMain.GeneralException(
"couldn't generate random file name");
}
openFileInput(streamFilename).close();
@@ -440,18 +440,18 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
FileOutputStream outStream = openFileOutput(streamFilename, Context.MODE_PRIVATE);
if (generateSignature) {
- PGPHelper.generateSignature(this, inputData, outStream, useAsciiArmour, true,
- secretKeyId, PGPHelper.getCachedPassPhrase(secretKeyId), Preferences
+ PGPMain.generateSignature(this, inputData, outStream, useAsciiArmour, true,
+ secretKeyId, PGPMain.getCachedPassPhrase(secretKeyId), Preferences
.getPreferences(this).getDefaultHashAlgorithm(), Preferences
.getPreferences(this).getForceV3Signatures(), this);
} else if (signOnly) {
- PGPHelper.signText(this, inputData, outStream, secretKeyId, PGPHelper
+ PGPMain.signText(this, inputData, outStream, secretKeyId, PGPMain
.getCachedPassPhrase(secretKeyId), Preferences.getPreferences(this)
.getDefaultHashAlgorithm(), Preferences.getPreferences(this)
.getForceV3Signatures(), this);
} else {
- PGPHelper.encrypt(this, inputData, outStream, useAsciiArmour, encryptionKeyIds,
- signatureKeyId, PGPHelper.getCachedPassPhrase(signatureKeyId), this,
+ PGPMain.encrypt(this, inputData, outStream, useAsciiArmour, encryptionKeyIds,
+ signatureKeyId, PGPMain.getCachedPassPhrase(signatureKeyId), this,
Preferences.getPreferences(this).getDefaultEncryptionAlgorithm(),
Preferences.getPreferences(this).getDefaultHashAlgorithm(),
compressionId, Preferences.getPreferences(this).getForceV3Signatures(),
@@ -480,12 +480,12 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
/* Operation */
try {
- PGPHelper.deleteFileSecurely(this, new File(deleteFile), this);
+ PGPMain.deleteFileSecurely(this, new File(deleteFile), this);
} catch (FileNotFoundException e) {
- throw new PGPHelper.GeneralException(getString(R.string.error_fileNotFound,
+ throw new PGPMain.GeneralException(getString(R.string.error_fileNotFound,
deleteFile));
} catch (IOException e) {
- throw new PGPHelper.GeneralException(getString(R.string.error_fileDeleteFailed,
+ throw new PGPMain.GeneralException(getString(R.string.error_fileDeleteFailed,
deleteFile));
}
@@ -518,10 +518,10 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
// verifyText and decrypt returning additional resultData values for the
// verification of signatures
if (signedOnly) {
- resultData = PGPHelper.verifyText(this, inputData, outStream, this);
+ resultData = PGPMain.verifyText(this, inputData, outStream, this);
} else {
- resultData = PGPHelper.decrypt(this, inputData, outStream,
- PGPHelper.getCachedPassPhrase(secretKeyId), this,
+ resultData = PGPMain.decrypt(this, inputData, outStream,
+ PGPMain.getCachedPassPhrase(secretKeyId), this,
assumeSymmetricEncryption);
}
@@ -577,10 +577,10 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
// verifyText and decrypt returning additional output values for the
// verification of signatures
if (signedOnly) {
- resultData = PGPHelper.verifyText(this, inputData, outStream, this);
+ resultData = PGPMain.verifyText(this, inputData, outStream, this);
} else {
- resultData = PGPHelper.decrypt(this, inputData, outStream,
- PGPHelper.getCachedPassPhrase(secretKeyId), this,
+ resultData = PGPMain.decrypt(this, inputData, outStream,
+ PGPMain.getCachedPassPhrase(secretKeyId), this,
assumeSymmetricEncryption);
}
@@ -604,16 +604,16 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
/* Operation */
// InputStream
InputStream in = getContentResolver().openInputStream(providerUri);
- long inLength = PGPHelper.getLengthOfStream(in);
+ long inLength = PGPMain.getLengthOfStream(in);
InputData inputData = new InputData(in, inLength);
// OutputStream
String streamFilename = null;
try {
while (true) {
- streamFilename = PGPHelper.generateRandomString(32);
+ streamFilename = PGPMain.generateRandomString(32);
if (streamFilename == null) {
- throw new PGPHelper.GeneralException(
+ throw new PGPMain.GeneralException(
"couldn't generate random file name");
}
openFileInput(streamFilename).close();
@@ -628,10 +628,10 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
// verifyText and decrypt returning additional output values for the
// verification of signatures
if (signedOnly) {
- resultData = PGPHelper.verifyText(this, inputData, outStream, this);
+ resultData = PGPMain.verifyText(this, inputData, outStream, this);
} else {
- resultData = PGPHelper.decrypt(this, inputData, outStream,
- PGPHelper.getCachedPassPhrase(secretKeyId), this,
+ resultData = PGPMain.decrypt(this, inputData, outStream,
+ PGPMain.getCachedPassPhrase(secretKeyId), this,
assumeSymmetricEncryption);
}
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/BaseActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/BaseActivity.java
index 81d53a29d..542f65d3c 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/BaseActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/BaseActivity.java
@@ -25,7 +25,7 @@ import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.ProgressDialogUpdater;
import org.thialfihar.android.apg.deprecated.PausableThread;
-import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.helper.Preferences;
import org.thialfihar.android.apg.passphrase.AskForPassphrase;
import org.thialfihar.android.apg.passphrase.PassphraseCacheService;
@@ -79,7 +79,7 @@ public class BaseActivity extends SherlockFragmentActivity implements Runnable,
// not needed later:
mPreferences = Preferences.getPreferences(this);
- PGPHelper.initialize(this);
+ PGPMain.initialize(this);
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
File dir = new File(Constants.path.APP_DIR);
@@ -378,7 +378,7 @@ public class BaseActivity extends SherlockFragmentActivity implements Runnable,
public void passPhraseCallback(long keyId, String passPhrase) {
// TODO: Not needed anymore, now implemented in AskForSecretKeyPass
- PGPHelper.setCachedPassPhrase(keyId, passPhrase);
+ PGPMain.setCachedPassPhrase(keyId, passPhrase);
}
public void sendMessage(Message msg) {
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java
index 71835840e..b65aabd71 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java
@@ -21,6 +21,7 @@ import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.helper.FileHelper;
import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.service.ApgHandler;
import org.thialfihar.android.apg.service.ApgService;
import org.thialfihar.android.apg.ui.dialog.DeleteFileDialogFragment;
@@ -299,7 +300,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
}
if (textData != null) {
Log.d(Constants.TAG, "textData null, matching text ...");
- Matcher matcher = PGPHelper.PGP_MESSAGE.matcher(textData);
+ Matcher matcher = PGPMain.PGP_MESSAGE.matcher(textData);
if (matcher.matches()) {
Log.d(Constants.TAG, "PGP_MESSAGE matched");
textData = matcher.group(1);
@@ -307,7 +308,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
textData = textData.replaceAll("\\xa0", " ");
mMessage.setText(textData);
} else {
- matcher = PGPHelper.PGP_SIGNED_MESSAGE.matcher(textData);
+ matcher = PGPMain.PGP_SIGNED_MESSAGE.matcher(textData);
if (matcher.matches()) {
Log.d(Constants.TAG, "PGP_SIGNED_MESSAGE matched");
textData = matcher.group(1);
@@ -350,14 +351,14 @@ public class DecryptActivity extends SherlockFragmentActivity {
mData = extras.getByteArray(EXTRA_DATA);
String data = extras.getString(EXTRA_TEXT);
if (data != null) {
- Matcher matcher = PGPHelper.PGP_MESSAGE.matcher(data);
+ Matcher matcher = PGPMain.PGP_MESSAGE.matcher(data);
if (matcher.matches()) {
data = matcher.group(1);
// replace non breakable spaces
data = data.replaceAll("\\xa0", " ");
mMessage.setText(data);
} else {
- matcher = PGPHelper.PGP_SIGNED_MESSAGE.matcher(data);
+ matcher = PGPMain.PGP_SIGNED_MESSAGE.matcher(data);
if (matcher.matches()) {
data = matcher.group(1);
// replace non breakable spaces
@@ -381,9 +382,9 @@ public class DecryptActivity extends SherlockFragmentActivity {
String data = "";
if (clipboardText != null) {
- Matcher matcher = PGPHelper.PGP_MESSAGE.matcher(clipboardText);
+ Matcher matcher = PGPMain.PGP_MESSAGE.matcher(clipboardText);
if (!matcher.matches()) {
- matcher = PGPHelper.PGP_SIGNED_MESSAGE.matcher(clipboardText);
+ matcher = PGPMain.PGP_SIGNED_MESSAGE.matcher(clipboardText);
}
if (matcher.matches()) {
data = matcher.group(1);
@@ -399,7 +400,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
if (mSignatureKeyId == 0) {
return;
}
- PGPPublicKeyRing key = PGPHelper.getPublicKeyRing(mSignatureKeyId);
+ PGPPublicKeyRing key = PGPMain.getPublicKeyRing(mSignatureKeyId);
if (key != null) {
Intent intent = new Intent(DecryptActivity.this, KeyServerQueryActivity.class);
intent.setAction(KeyServerQueryActivity.ACTION_LOOK_UP_KEY_ID);
@@ -506,7 +507,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
if (mDecryptTarget == Id.target.message) {
String messageData = mMessage.getText().toString();
- Matcher matcher = PGPHelper.PGP_SIGNED_MESSAGE.matcher(messageData);
+ Matcher matcher = PGPMain.PGP_SIGNED_MESSAGE.matcher(messageData);
if (matcher.matches()) {
mSignedOnly = true;
decryptStart();
@@ -523,7 +524,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
// if we need a symmetric passphrase or a passphrase to use a sekret key ask for it
if (getSecretKeyId() == Id.key.symmetric
- || PGPHelper.getCachedPassPhrase(getSecretKeyId()) == null) {
+ || PGPMain.getCachedPassPhrase(getSecretKeyId()) == null) {
// showDialog(Id.dialog.pass_phrase);
showPassphraseDialog();
} else {
@@ -563,7 +564,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
messenger, mSecretKeyId);
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
- } catch (PGPHelper.GeneralException e) {
+ } catch (PGPMain.GeneralException e) {
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
// send message to handler to start encryption directly
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
@@ -609,15 +610,15 @@ public class DecryptActivity extends SherlockFragmentActivity {
try {
try {
- setSecretKeyId(PGPHelper.getDecryptionKeyId(this, inStream));
+ setSecretKeyId(PGPMain.getDecryptionKeyId(this, inStream));
if (getSecretKeyId() == Id.key.none) {
- throw new PGPHelper.GeneralException(getString(R.string.error_noSecretKeyFound));
+ throw new PGPMain.GeneralException(getString(R.string.error_noSecretKeyFound));
}
mAssumeSymmetricEncryption = false;
- } catch (PGPHelper.NoAsymmetricEncryptionException e) {
+ } catch (PGPMain.NoAsymmetricEncryptionException e) {
setSecretKeyId(Id.key.symmetric);
- if (!PGPHelper.hasSymmetricEncryption(this, inStream)) {
- throw new PGPHelper.GeneralException(
+ if (!PGPMain.hasSymmetricEncryption(this, inStream)) {
+ throw new PGPMain.GeneralException(
getString(R.string.error_noKnownEncryptionFound));
}
mAssumeSymmetricEncryption = true;
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java
index f31d39381..855be57c5 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java
@@ -22,6 +22,7 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.helper.OtherHelper;
import org.thialfihar.android.apg.helper.PGPConversionHelper;
import org.thialfihar.android.apg.service.ApgHandler;
@@ -256,7 +257,7 @@ public class EditKeyActivity extends SherlockFragmentActivity {
} else if (ACTION_EDIT_KEY.equals(mIntent.getAction())) {
mActionBar.setTitle(R.string.title_editKey);
- mCurrentPassPhrase = PGPHelper.getEditPassPhrase();
+ mCurrentPassPhrase = PGPMain.getEditPassPhrase();
if (mCurrentPassPhrase == null) {
mCurrentPassPhrase = "";
}
@@ -274,7 +275,7 @@ public class EditKeyActivity extends SherlockFragmentActivity {
if (keyId != 0) {
PGPSecretKey masterKey = null;
- mKeyRing = PGPHelper.getSecretKeyRing(keyId);
+ mKeyRing = PGPMain.getSecretKeyRing(keyId);
if (mKeyRing != null) {
masterKey = PGPHelper.getMasterKey(mKeyRing);
for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(
@@ -420,7 +421,7 @@ public class EditKeyActivity extends SherlockFragmentActivity {
try {
if (!isPassphraseSet()) {
- throw new PGPHelper.GeneralException(this.getString(R.string.setAPassPhrase));
+ throw new PGPMain.GeneralException(this.getString(R.string.setAPassPhrase));
}
// Send all information needed to service to edit key in other thread
@@ -464,7 +465,7 @@ public class EditKeyActivity extends SherlockFragmentActivity {
// start service with intent
startService(intent);
- } catch (PGPHelper.GeneralException e) {
+ } catch (PGPMain.GeneralException e) {
Toast.makeText(this, getString(R.string.errorMessage, e.getMessage()),
Toast.LENGTH_SHORT).show();
}
@@ -476,7 +477,7 @@ public class EditKeyActivity extends SherlockFragmentActivity {
* @param userIdsView
* @return
*/
- private Vector<String> getUserIds(SectionView userIdsView) throws PGPHelper.GeneralException {
+ private Vector<String> getUserIds(SectionView userIdsView) throws PGPMain.GeneralException {
Vector<String> userIds = new Vector<String>();
ViewGroup userIdEditors = userIdsView.getEditors();
@@ -488,13 +489,13 @@ public class EditKeyActivity extends SherlockFragmentActivity {
try {
userId = editor.getValue();
} catch (UserIdEditor.NoNameException e) {
- throw new PGPHelper.GeneralException(
+ throw new PGPMain.GeneralException(
this.getString(R.string.error_userIdNeedsAName));
} catch (UserIdEditor.NoEmailException e) {
- throw new PGPHelper.GeneralException(
+ throw new PGPMain.GeneralException(
this.getString(R.string.error_userIdNeedsAnEmailAddress));
} catch (UserIdEditor.InvalidEmailException e) {
- throw new PGPHelper.GeneralException(e.getMessage());
+ throw new PGPMain.GeneralException(e.getMessage());
}
if (userId.equals("")) {
@@ -510,11 +511,11 @@ public class EditKeyActivity extends SherlockFragmentActivity {
}
if (userIds.size() == 0) {
- throw new PGPHelper.GeneralException(getString(R.string.error_keyNeedsAUserId));
+ throw new PGPMain.GeneralException(getString(R.string.error_keyNeedsAUserId));
}
if (!gotMainUserId) {
- throw new PGPHelper.GeneralException(getString(R.string.error_mainUserIdMustNotBeEmpty));
+ throw new PGPMain.GeneralException(getString(R.string.error_mainUserIdMustNotBeEmpty));
}
return userIds;
@@ -526,13 +527,13 @@ public class EditKeyActivity extends SherlockFragmentActivity {
* @param keysView
* @return
*/
- private Vector<PGPSecretKey> getKeys(SectionView keysView) throws PGPHelper.GeneralException {
+ private Vector<PGPSecretKey> getKeys(SectionView keysView) throws PGPMain.GeneralException {
Vector<PGPSecretKey> keys = new Vector<PGPSecretKey>();
ViewGroup keyEditors = keysView.getEditors();
if (keyEditors.getChildCount() == 0) {
- throw new PGPHelper.GeneralException(getString(R.string.error_keyNeedsMasterKey));
+ throw new PGPMain.GeneralException(getString(R.string.error_keyNeedsMasterKey));
}
for (int i = 0; i < keyEditors.getChildCount(); ++i) {
@@ -549,13 +550,13 @@ public class EditKeyActivity extends SherlockFragmentActivity {
* @param keysView
* @return
*/
- private Vector<Integer> getKeysUsages(SectionView keysView) throws PGPHelper.GeneralException {
+ private Vector<Integer> getKeysUsages(SectionView keysView) throws PGPMain.GeneralException {
Vector<Integer> getKeysUsages = new Vector<Integer>();
ViewGroup keyEditors = keysView.getEditors();
if (keyEditors.getChildCount() == 0) {
- throw new PGPHelper.GeneralException(getString(R.string.error_keyNeedsMasterKey));
+ throw new PGPMain.GeneralException(getString(R.string.error_keyNeedsMasterKey));
}
for (int i = 0; i < keyEditors.getChildCount(); ++i) {
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java
index c01a1efb6..b0013f588 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java
@@ -25,6 +25,7 @@ import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.helper.FileHelper;
import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.helper.Preferences;
import org.thialfihar.android.apg.service.ApgHandler;
import org.thialfihar.android.apg.service.ApgService;
@@ -390,7 +391,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
long signatureKeyId = extras.getLong(EXTRA_SIGNATURE_KEY_ID);
long encryptionKeyIds[] = extras.getLongArray(EXTRA_ENCRYPTION_KEY_IDS);
if (signatureKeyId != 0) {
- PGPSecretKeyRing keyRing = PGPHelper.getSecretKeyRing(signatureKeyId);
+ PGPSecretKeyRing keyRing = PGPMain.getSecretKeyRing(signatureKeyId);
PGPSecretKey masterKey = null;
if (keyRing != null) {
masterKey = PGPHelper.getMasterKey(keyRing);
@@ -406,7 +407,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
if (encryptionKeyIds != null) {
Vector<Long> goodIds = new Vector<Long>();
for (int i = 0; i < encryptionKeyIds.length; ++i) {
- PGPPublicKeyRing keyRing = PGPHelper.getPublicKeyRing(encryptionKeyIds[i]);
+ PGPPublicKeyRing keyRing = PGPMain.getPublicKeyRing(encryptionKeyIds[i]);
PGPPublicKey masterKey = null;
if (keyRing == null) {
continue;
@@ -669,7 +670,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
return;
}
- if (getSecretKeyId() != 0 && PGPHelper.getCachedPassPhrase(getSecretKeyId()) == null) {
+ if (getSecretKeyId() != 0 && PGPMain.getCachedPassPhrase(getSecretKeyId()) == null) {
showPassphraseDialog();
return;
@@ -710,7 +711,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
messenger, mSecretKeyId);
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
- } catch (PGPHelper.GeneralException e) {
+ } catch (PGPMain.GeneralException e) {
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
// send message to handler to start encryption directly
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
@@ -935,7 +936,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
} else {
String uid = getResources().getString(R.string.unknownUserId);
String uidExtra = "";
- PGPSecretKeyRing keyRing = PGPHelper.getSecretKeyRing(getSecretKeyId());
+ PGPSecretKeyRing keyRing = PGPMain.getSecretKeyRing(getSecretKeyId());
if (keyRing != null) {
PGPSecretKey key = PGPHelper.getMasterKey(keyRing);
if (key != null) {
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/ImportFromQRCodeActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/ImportFromQRCodeActivity.java
index 9ab992d60..854427b02 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/ImportFromQRCodeActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/ImportFromQRCodeActivity.java
@@ -24,6 +24,7 @@ import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.util.HkpKeyServer;
import org.thialfihar.android.apg.util.KeyServer.QueryException;
import org.thialfihar.android.apg.R;
@@ -83,7 +84,7 @@ public class ImportFromQRCodeActivity extends BaseActivity {
.getPublicKey().getFingerprint());
if (expectedFingerprint.equals(actualFingerprint)) {
// store the signed key in our local cache
- int retval = PGPHelper.storeKeyRingInCache(publicKeyRing);
+ int retval = PGPMain.storeKeyRingInCache(publicKeyRing);
if (retval != Id.return_value.ok
&& retval != Id.return_value.updated) {
status.putString(EXTRA_ERROR,
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/KeyListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/KeyListActivity.java
index 2ad64f91e..9c378cba1 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/KeyListActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/KeyListActivity.java
@@ -22,6 +22,7 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.provider.KeyRings;
import org.thialfihar.android.apg.provider.Keys;
import org.thialfihar.android.apg.provider.UserIds;
@@ -269,7 +270,7 @@ public class KeyListActivity extends BaseActivity {
mSelectedItem = -1;
// TODO: better way to do this?
String userId = "<unknown>";
- Object keyRing = PGPHelper.getKeyRing(keyRingId);
+ Object keyRing = PGPMain.getKeyRing(keyRingId);
if (keyRing != null) {
if (keyRing instanceof PGPPublicKeyRing) {
userId = PGPHelper.getMainUserIdSafe(this,
@@ -344,12 +345,12 @@ public class KeyListActivity extends BaseActivity {
}
if (mTask == Id.task.import_keys) {
- data = PGPHelper.importKeyRings(this, mKeyType, new InputData(importInputStream,
+ data = PGPMain.importKeyRings(this, mKeyType, new InputData(importInputStream,
size), this);
} else {
Vector<Integer> keyRingIds = new Vector<Integer>();
if (mSelectedItem == -1) {
- keyRingIds = PGPHelper
+ keyRingIds = PGPMain
.getKeyRingIds(mKeyType == Id.type.public_key ? Id.database.type_public
: Id.database.type_secret);
} else {
@@ -357,7 +358,7 @@ public class KeyListActivity extends BaseActivity {
keyRingIds.add(keyRingId);
mSelectedItem = -1;
}
- data = PGPHelper.exportKeyRings(this, keyRingIds, exportOutputStream, this);
+ data = PGPMain.exportKeyRings(this, keyRingIds, exportOutputStream, this);
}
} catch (FileNotFoundException e) {
error = getString(R.string.error_fileNotFound);
@@ -365,7 +366,7 @@ public class KeyListActivity extends BaseActivity {
error = "" + e;
} catch (PGPException e) {
error = "" + e;
- } catch (PGPHelper.GeneralException e) {
+ } catch (PGPMain.GeneralException e) {
error = "" + e;
}
@@ -386,7 +387,7 @@ public class KeyListActivity extends BaseActivity {
}
protected void deleteKey(int keyRingId) {
- PGPHelper.deleteKey(keyRingId);
+ PGPMain.deleteKey(keyRingId);
refreshList();
}
@@ -527,7 +528,7 @@ public class KeyListActivity extends BaseActivity {
mSearchString = searchString;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mDatabase = PGPHelper.getDatabase().db();
+ mDatabase = PGPMain.getDatabase().db();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "("
+ KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME + "."
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/KeyServerExportActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/KeyServerExportActivity.java
index cf14492b6..a15468bed 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/KeyServerExportActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/KeyServerExportActivity.java
@@ -21,7 +21,7 @@ import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.R;
-import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.util.HkpKeyServer;
import com.actionbarsherlock.view.MenuItem;
@@ -110,9 +110,9 @@ public class KeyServerExportActivity extends BaseActivity {
int keyRingId = getIntent().getIntExtra(EXTRA_KEY_ID, -1);
- PGPKeyRing keyring = PGPHelper.getKeyRing(keyRingId);
+ PGPKeyRing keyring = PGPMain.getKeyRing(keyRingId);
if (keyring != null && keyring instanceof PGPPublicKeyRing) {
- boolean uploaded = PGPHelper.uploadKeyRingToServer(server, (PGPPublicKeyRing) keyring);
+ boolean uploaded = PGPMain.uploadKeyRingToServer(server, (PGPPublicKeyRing) keyring);
if (!uploaded) {
error = "Unable to export key to selected server";
}
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/KeyServerQueryActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/KeyServerQueryActivity.java
index ec140e8d2..1cb7ecaca 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/KeyServerQueryActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/KeyServerQueryActivity.java
@@ -21,6 +21,7 @@ import org.thialfihar.android.apg.R;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.util.HkpKeyServer;
import org.thialfihar.android.apg.util.KeyServer.InsufficientQuery;
import org.thialfihar.android.apg.util.KeyServer.KeyInfo;
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/MailListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/MailListActivity.java
index 3b32265a8..85d9d6ce5 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/MailListActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/MailListActivity.java
@@ -20,7 +20,7 @@ import java.util.Vector;
import java.util.regex.Matcher;
import org.thialfihar.android.apg.R;
-import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.helper.Preferences;
import android.app.ListActivity;
@@ -121,11 +121,11 @@ public class MailListActivity extends ListActivity {
String data = messageCursor.getString(bodyIndex);
data = Html.fromHtml(data).toString();
boolean signedOnly = false;
- Matcher matcher = PGPHelper.PGP_MESSAGE.matcher(data);
+ Matcher matcher = PGPMain.PGP_MESSAGE.matcher(data);
if (matcher.matches()) {
data = matcher.group(1);
} else {
- matcher = PGPHelper.PGP_SIGNED_MESSAGE.matcher(data);
+ matcher = PGPMain.PGP_SIGNED_MESSAGE.matcher(data);
if (matcher.matches()) {
data = matcher.group(1);
signedOnly = true;
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/MainActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/MainActivity.java
index 465daf5c9..db30b0671 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/MainActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/MainActivity.java
@@ -22,7 +22,7 @@ import java.security.Security;
import org.spongycastle.jce.provider.BouncyCastleProvider;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.R;
-import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockActivity;
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/PreferencesActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/PreferencesActivity.java
index b56fb676c..84beee428 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/PreferencesActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/PreferencesActivity.java
@@ -20,7 +20,7 @@ import org.spongycastle.bcpg.HashAlgorithmTags;
import org.spongycastle.openpgp.PGPEncryptedData;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
-import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.helper.Preferences;
import org.thialfihar.android.apg.passphrase.PassphraseCacheService;
import org.thialfihar.android.apg.ui.widget.IntegerListPreference;
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/PreferencesKeyServerActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/PreferencesKeyServerActivity.java
index 9e8b638aa..ee193cdd5 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/PreferencesKeyServerActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/PreferencesKeyServerActivity.java
@@ -20,7 +20,7 @@ import java.util.Vector;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.R;
-import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.ui.widget.Editor;
import org.thialfihar.android.apg.ui.widget.KeyServerEditor;
import org.thialfihar.android.apg.ui.widget.Editor.EditorListener;
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/PublicKeyListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/PublicKeyListActivity.java
index 30205fe7b..601f467aa 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/PublicKeyListActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/PublicKeyListActivity.java
@@ -21,6 +21,7 @@ import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.R;
import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
@@ -115,7 +116,7 @@ public class PublicKeyListActivity extends KeyListActivity {
mSelectedItem = groupPosition;
final int keyRingId = mListAdapter.getKeyRingId(groupPosition);
long keyId = 0;
- Object keyRing = PGPHelper.getKeyRing(keyRingId);
+ Object keyRing = PGPMain.getKeyRing(keyRingId);
if (keyRing != null && keyRing instanceof PGPPublicKeyRing) {
keyId = PGPHelper.getMasterKey((PGPPublicKeyRing) keyRing).getKeyID();
}
@@ -148,7 +149,7 @@ public class PublicKeyListActivity extends KeyListActivity {
mSelectedItem = groupPosition;
final int keyRingId = mListAdapter.getKeyRingId(groupPosition);
long keyId = 0;
- Object keyRing = PGPHelper.getKeyRing(keyRingId);
+ Object keyRing = PGPMain.getKeyRing(keyRingId);
if (keyRing != null && keyRing instanceof PGPPublicKeyRing) {
keyId = PGPHelper.getMasterKey((PGPPublicKeyRing) keyRing).getKeyID();
}
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/SecretKeyListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/SecretKeyListActivity.java
index 18b051571..60c6a6ef6 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/SecretKeyListActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/SecretKeyListActivity.java
@@ -20,6 +20,7 @@ import org.thialfihar.android.apg.R;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.passphrase.AskForPassphrase;
import com.actionbarsherlock.view.Menu;
@@ -146,11 +147,11 @@ public class SecretKeyListActivity extends KeyListActivity implements OnChildCli
public void checkPassPhraseAndEdit() {
long keyId = ((KeyListAdapter) mList.getExpandableListAdapter()).getGroupId(mSelectedItem);
- String passPhrase = PGPHelper.getCachedPassPhrase(keyId);
+ String passPhrase = PGPMain.getCachedPassPhrase(keyId);
if (passPhrase == null) {
showDialog(Id.dialog.pass_phrase);
} else {
- PGPHelper.setEditPassPhrase(passPhrase);
+ PGPMain.setEditPassPhrase(passPhrase);
editKey();
}
}
@@ -158,12 +159,12 @@ public class SecretKeyListActivity extends KeyListActivity implements OnChildCli
@Override
public void passPhraseCallback(long keyId, String passPhrase) {
super.passPhraseCallback(keyId, passPhrase);
- PGPHelper.setEditPassPhrase(passPhrase);
+ PGPMain.setEditPassPhrase(passPhrase);
editKey();
}
private void createKey() {
- PGPHelper.setEditPassPhrase("");
+ PGPMain.setEditPassPhrase("");
Intent intent = new Intent(EditKeyActivity.ACTION_CREATE_KEY);
startActivityForResult(intent, Id.message.create_key);
}
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListActivity.java
index 903631ffd..fb7e5a0dd 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListActivity.java
@@ -21,7 +21,7 @@ import java.util.Vector;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.R;
import org.thialfihar.android.apg.Id;
-import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.ui.widget.SelectPublicKeyListAdapter;
import com.actionbarsherlock.app.ActionBar;
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/SelectSecretKeyListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/SelectSecretKeyListActivity.java
index dafe9a4c2..865fab789 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/SelectSecretKeyListActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/SelectSecretKeyListActivity.java
@@ -19,7 +19,7 @@ package org.thialfihar.android.apg.ui;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.R;
import org.thialfihar.android.apg.Id;
-import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.ui.widget.SelectSecretKeyListAdapter;
import com.actionbarsherlock.app.ActionBar;
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java
index 5781410c5..d4985fdb5 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java
@@ -35,7 +35,7 @@ import org.spongycastle.openpgp.PGPUtil;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.R;
-import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.util.HkpKeyServer;
import com.actionbarsherlock.view.MenuItem;
@@ -143,7 +143,7 @@ public class SignKeyActivity extends BaseActivity {
* handles the UI bits of the signing process on the UI thread
*/
private void initiateSigning() {
- PGPPublicKeyRing pubring = PGPHelper.getPublicKeyRing(pubKeyId);
+ PGPPublicKeyRing pubring = PGPMain.getPublicKeyRing(pubKeyId);
if (pubring != null) {
// if we have already signed this key, dont bother doing it again
boolean alreadySigned = false;
@@ -162,7 +162,7 @@ public class SignKeyActivity extends BaseActivity {
/*
* get the user's passphrase for this key (if required)
*/
- String passphrase = PGPHelper.getCachedPassPhrase(masterKeyId);
+ String passphrase = PGPMain.getCachedPassPhrase(masterKeyId);
if (passphrase == null) {
showDialog(Id.dialog.pass_phrase);
return; // bail out; need to wait until the user has entered the passphrase
@@ -212,16 +212,16 @@ public class SignKeyActivity extends BaseActivity {
Message msg = new Message();
try {
- String passphrase = PGPHelper.getCachedPassPhrase(masterKeyId);
+ String passphrase = PGPMain.getCachedPassPhrase(masterKeyId);
if (passphrase == null || passphrase.length() <= 0) {
status.putString(EXTRA_ERROR, "Unable to obtain passphrase");
} else {
- PGPPublicKeyRing pubring = PGPHelper.getPublicKeyRing(pubKeyId);
+ PGPPublicKeyRing pubring = PGPMain.getPublicKeyRing(pubKeyId);
/*
* sign the incoming key
*/
- PGPSecretKey secretKey = PGPHelper.getSecretKey(masterKeyId);
+ PGPSecretKey secretKey = PGPMain.getSecretKey(masterKeyId);
PGPPrivateKey signingKey = secretKey.extractPrivateKey(passphrase.toCharArray(),
BouncyCastleProvider.PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(secretKey.getPublicKey()
@@ -247,11 +247,11 @@ public class SignKeyActivity extends BaseActivity {
* upload the newly signed key to the key server
*/
- PGPHelper.uploadKeyRingToServer(server, pubring);
+ PGPMain.uploadKeyRingToServer(server, pubring);
}
// store the signed key in our local cache
- int retval = PGPHelper.storeKeyRingInCache(pubring);
+ int retval = PGPMain.storeKeyRingInCache(pubring);
if (retval != Id.return_value.ok && retval != Id.return_value.updated) {
status.putString(EXTRA_ERROR, "Failed to store signed key in local cache");
}
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/dialog/FileDialogFragment.java b/org_apg/src/org/thialfihar/android/apg/ui/dialog/FileDialogFragment.java
index 531cddfcf..2a83febc2 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/dialog/FileDialogFragment.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/dialog/FileDialogFragment.java
@@ -19,7 +19,6 @@ package org.thialfihar.android.apg.ui.dialog;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.R;
import org.thialfihar.android.apg.helper.FileHelper;
-import org.thialfihar.android.apg.helper.OtherHelper;
import android.app.Activity;
import android.app.AlertDialog;
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/dialog/PassphraseDialogFragment.java b/org_apg/src/org/thialfihar/android/apg/ui/dialog/PassphraseDialogFragment.java
index ce08c6c86..21dcc1b09 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/dialog/PassphraseDialogFragment.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/dialog/PassphraseDialogFragment.java
@@ -22,7 +22,8 @@ import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.thialfihar.android.apg.helper.PGPHelper;
-import org.thialfihar.android.apg.helper.PGPHelper.GeneralException;
+import org.thialfihar.android.apg.helper.PGPMain;
+import org.thialfihar.android.apg.helper.PGPMain.GeneralException;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.R;
@@ -68,7 +69,7 @@ public class PassphraseDialogFragment extends DialogFragment {
// check if secret key has a passphrase
if (!(secretKeyId == Id.key.symmetric || secretKeyId == Id.key.none)) {
if (!hasPassphrase(secretKeyId)) {
- throw new PGPHelper.GeneralException("No passphrase! No passphrase dialog needed!");
+ throw new PGPMain.GeneralException("No passphrase! No passphrase dialog needed!");
}
}
@@ -91,7 +92,8 @@ public class PassphraseDialogFragment extends DialogFragment {
private static boolean hasPassphrase(long secretKeyId) {
// check if the key has no passphrase
try {
- PGPSecretKey secretKey = PGPHelper.getMasterKey(PGPHelper.getSecretKeyRing(secretKeyId));
+ PGPSecretKey secretKey = PGPHelper.getMasterKey(PGPMain
+ .getSecretKeyRing(secretKeyId));
Log.d(Constants.TAG, "Check if key has no passphrase...");
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
@@ -101,7 +103,7 @@ public class PassphraseDialogFragment extends DialogFragment {
Log.d(Constants.TAG, "Key has no passphrase! Caches empty passphrase!");
// cache empty passphrase
- PGPHelper.setCachedPassPhrase(secretKey.getKeyID(), "");
+ PGPMain.setCachedPassPhrase(secretKey.getKeyID(), "");
return false;
}
@@ -132,7 +134,7 @@ public class PassphraseDialogFragment extends DialogFragment {
secretKey = null;
alert.setMessage(getString(R.string.passPhraseForSymmetricEncryption));
} else {
- secretKey = PGPHelper.getMasterKey(PGPHelper.getSecretKeyRing(secretKeyId));
+ secretKey = PGPHelper.getMasterKey(PGPMain.getSecretKeyRing(secretKeyId));
if (secretKey == null) {
alert.setTitle(R.string.title_keyNotFound);
alert.setMessage(getString(R.string.keyNotFound, secretKeyId));
@@ -189,7 +191,7 @@ public class PassphraseDialogFragment extends DialogFragment {
// cache the new passphrase
Log.d(Constants.TAG, "Everything okay! Caching entered passphrase");
- PGPHelper.setCachedPassPhrase(keyId, passPhrase);
+ PGPMain.setCachedPassPhrase(keyId, passPhrase);
sendMessageToHandler(MESSAGE_OKAY);
}
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/widget/KeyEditor.java b/org_apg/src/org/thialfihar/android/apg/ui/widget/KeyEditor.java
index 87d715fd9..6efe17c6d 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/widget/KeyEditor.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/widget/KeyEditor.java
@@ -20,6 +20,7 @@ import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPSecretKey;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.util.Choice;
import org.thialfihar.android.apg.R;
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/widget/SectionView.java b/org_apg/src/org/thialfihar/android/apg/ui/widget/SectionView.java
index 22a2ecb5b..4bedd1ede 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/widget/SectionView.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/widget/SectionView.java
@@ -19,7 +19,7 @@ package org.thialfihar.android.apg.ui.widget;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.thialfihar.android.apg.Id;
-import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.helper.PGPConversionHelper;
import org.thialfihar.android.apg.service.ApgHandler;
import org.thialfihar.android.apg.service.ApgService;
@@ -259,7 +259,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
String passPhrase;
if (mEditors.getChildCount() > 0) {
PGPSecretKey masterKey = ((KeyEditor) mEditors.getChildAt(0)).getValue();
- passPhrase = PGPHelper.getCachedPassPhrase(masterKey.getKeyID());
+ passPhrase = PGPMain.getCachedPassPhrase(masterKey.getKeyID());
data.putByteArray(ApgService.MASTER_KEY,
PGPConversionHelper.PGPSecretKeyToBytes(masterKey));
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectPublicKeyListAdapter.java b/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectPublicKeyListAdapter.java
index 240d6a078..ee78e8f88 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectPublicKeyListAdapter.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectPublicKeyListAdapter.java
@@ -21,6 +21,7 @@ import java.util.Date;
import org.thialfihar.android.apg.R;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.provider.KeyRings;
import org.thialfihar.android.apg.provider.Keys;
import org.thialfihar.android.apg.provider.UserIds;
@@ -53,7 +54,7 @@ public class SelectPublicKeyListAdapter extends BaseAdapter {
mActivity = activity;
mParent = parent;
- mDatabase = PGPHelper.getDatabase().db();
+ mDatabase = PGPMain.getDatabase().db();
mInflater = (LayoutInflater) parent.getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
long now = new Date().getTime() / 1000;
diff --git a/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectSecretKeyListAdapter.java b/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectSecretKeyListAdapter.java
index fc8c4e8b0..2caa593ff 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectSecretKeyListAdapter.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectSecretKeyListAdapter.java
@@ -19,6 +19,7 @@ import java.util.Date;
import org.thialfihar.android.apg.R;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.provider.KeyRings;
import org.thialfihar.android.apg.provider.Keys;
import org.thialfihar.android.apg.provider.UserIds;
@@ -48,7 +49,7 @@ public class SelectSecretKeyListAdapter extends BaseAdapter {
mActivity = activity;
mParent = parent;
- mDatabase = PGPHelper.getDatabase().db();
+ mDatabase = PGPMain.getDatabase().db();
mInflater = (LayoutInflater) parent.getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
long now = new Date().getTime() / 1000;
diff --git a/org_apg/src/org/thialfihar/android/apg/util/HkpKeyServer.java b/org_apg/src/org/thialfihar/android/apg/util/HkpKeyServer.java
index 38f3e2dc3..bdef7b59e 100644
--- a/org_apg/src/org/thialfihar/android/apg/util/HkpKeyServer.java
+++ b/org_apg/src/org/thialfihar/android/apg/util/HkpKeyServer.java
@@ -45,6 +45,7 @@ import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.helper.PGPMain;
import android.text.Html;
@@ -223,7 +224,7 @@ public class HkpKeyServer extends KeyServer {
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
String data = readAll(is, EntityUtils.getContentCharSet(entity));
- Matcher matcher = PGPHelper.PGP_PUBLIC_KEY.matcher(data);
+ Matcher matcher = PGPMain.PGP_PUBLIC_KEY.matcher(data);
if (matcher.find()) {
return matcher.group(1);
}