aboutsummaryrefslogtreecommitdiffstats
path: root/org_apg
diff options
context:
space:
mode:
authorDominik <dominik@dominikschuermann.de>2012-04-25 17:28:35 +0200
committerDominik <dominik@dominikschuermann.de>2012-06-13 19:28:23 +0300
commit340e0289ef677bec7b7d5df2d414e361dd687519 (patch)
tree432a1426adf569a497e7e1b75886b9abbbfe35c1 /org_apg
parentf06fcd989b2eb1416eea521c88944ff0c1482347 (diff)
downloadopen-keychain-340e0289ef677bec7b7d5df2d414e361dd687519.tar.gz
open-keychain-340e0289ef677bec7b7d5df2d414e361dd687519.tar.bz2
open-keychain-340e0289ef677bec7b7d5df2d414e361dd687519.zip
reworking createKey
Diffstat (limited to 'org_apg')
-rw-r--r--org_apg/src/org/thialfihar/android/apg/Apg.java109
-rw-r--r--org_apg/src/org/thialfihar/android/apg/Id.java33
-rw-r--r--org_apg/src/org/thialfihar/android/apg/service/ApgService.java8
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java34
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/widget/SectionView.java19
-rw-r--r--org_apg/src/org/thialfihar/android/apg/util/Utils.java18
6 files changed, 151 insertions, 70 deletions
diff --git a/org_apg/src/org/thialfihar/android/apg/Apg.java b/org_apg/src/org/thialfihar/android/apg/Apg.java
index 9d8264dd4..d702f6883 100644
--- a/org_apg/src/org/thialfihar/android/apg/Apg.java
+++ b/org_apg/src/org/thialfihar/android/apg/Apg.java
@@ -53,6 +53,16 @@ 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.return_value;
import org.thialfihar.android.apg.KeyServer.AddKeyException;
import org.thialfihar.android.apg.provider.DataProvider;
import org.thialfihar.android.apg.provider.Database;
@@ -94,6 +104,7 @@ 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;
@@ -111,6 +122,12 @@ import java.util.Vector;
import java.util.regex.Pattern;
public class Apg {
+
+ static {
+ // register spongy castle provider
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
public static final String PACKAGE_NAME = "org.thialfihar.android.apg";
private static final String INTENT_PREFIX = "org.thialfihar.android.apg.intent.";
@@ -296,8 +313,26 @@ public class Apg {
return delay;
}
- public static PGPSecretKey createKey(Context context, int algorithmChoice, int keySize,
- String passPhrase, PGPSecretKey masterKey) throws NoSuchAlgorithmException,
+ /**
+ * 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 {
@@ -305,8 +340,6 @@ public class Apg {
throw new GeneralException(context.getString(R.string.error_keySizeMinimum512bit));
}
- Security.addProvider(new BouncyCastleProvider());
-
if (passPhrase == null) {
passPhrase = "";
}
@@ -316,18 +349,18 @@ public class Apg {
switch (algorithmChoice) {
case Id.choice.algorithm.dsa: {
- keyGen = KeyPairGenerator.getInstance("DSA", new BouncyCastleProvider());
+ keyGen = KeyPairGenerator.getInstance("DSA", "SC");
keyGen.initialize(keySize, new SecureRandom());
algorithm = PGPPublicKey.DSA;
break;
}
case Id.choice.algorithm.elgamal: {
- if (masterKey == null) {
+ if (masterSecretKey == null) {
throw new GeneralException(
context.getString(R.string.error_masterKeyMustNotBeElGamal));
}
- keyGen = KeyPairGenerator.getInstance("ELGAMAL", new BouncyCastleProvider());
+ keyGen = KeyPairGenerator.getInstance("ELGAMAL", "SC");
BigInteger p = Primes.getBestPrime(keySize);
BigInteger g = new BigInteger("2");
@@ -339,7 +372,7 @@ public class Apg {
}
case Id.choice.algorithm.rsa: {
- keyGen = KeyPairGenerator.getInstance("RSA", new BouncyCastleProvider());
+ keyGen = KeyPairGenerator.getInstance("RSA", "SC");
keyGen.initialize(keySize, new SecureRandom());
algorithm = PGPPublicKey.RSA_GENERAL;
@@ -351,38 +384,45 @@ public class Apg {
}
}
- PGPKeyPair keyPair = new PGPKeyPair(algorithm, keyGen.generateKeyPair(), new Date());
+ // build new key pair
+ PGPKeyPair keyPair = new JcaPGPKeyPair(algorithm, keyGen.generateKeyPair(), new Date());
- PGPSecretKey secretKey = null;
- if (masterKey == null) {
- // enough for now, as we assemble the key again later anyway
- secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, keyPair, "",
- PGPEncryptedData.CAST5, passPhrase.toCharArray(), null, null,
- new SecureRandom(), new BouncyCastleProvider().getName());
+ // define hashing and signing algos
+ PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(
+ HashAlgorithmTags.SHA1);
+ PGPContentSignerBuilder certificationSignerBuilder = new JcaPGPContentSignerBuilder(keyPair
+ .getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1);
- } else {
- PGPPublicKey tmpKey = masterKey.getPublicKey();
- PGPPublicKey masterPublicKey = new PGPPublicKey(tmpKey.getAlgorithm(),
- tmpKey.getKey(new BouncyCastleProvider()), tmpKey.getCreationTime());
- PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(passPhrase.toCharArray(),
- new BouncyCastleProvider());
+ // 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());
+
+ PGPSecretKeyRing secKeyRing = null;
+ if (masterSecretKey == null) {
+ // build keyRing with only this one master key in it!
+ PGPKeyRingGenerator ringGen = new PGPKeyRingGenerator(
+ PGPSignature.DEFAULT_CERTIFICATION, keyPair, "", sha1Calc, null, null,
+ certificationSignerBuilder, keyEncryptor);
+
+ secKeyRing = ringGen.generateSecretKeyRing();
+ } 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)
PGPKeyRingGenerator ringGen = new PGPKeyRingGenerator(
- PGPSignature.POSITIVE_CERTIFICATION, masterKeyPair, "", PGPEncryptedData.CAST5,
- passPhrase.toCharArray(), null, null, new SecureRandom(),
- new BouncyCastleProvider().getName());
+ PGPSignature.DEFAULT_CERTIFICATION, masterKeyPair, "", sha1Calc, null, null,
+ certificationSignerBuilder, keyEncryptor);
+
ringGen.addSubKey(keyPair);
- PGPSecretKeyRing secKeyRing = ringGen.generateSecretKeyRing();
- Iterator<PGPSecretKey> it = secKeyRing.getSecretKeys();
- // first one is the master key
- it.next();
- secretKey = it.next();
+ secKeyRing = ringGen.generateSecretKeyRing();
}
- Log.d(Constants.TAG, "new secretkey: " + secretKey.toString());
-
- return secretKey;
+ return secKeyRing;
}
public static void buildSecretKey(Context context, ArrayList<String> userIds,
@@ -394,8 +434,6 @@ public class Apg {
if (progress != null)
progress.setProgress(R.string.progress_buildingKey, 0, 100);
- Security.addProvider(new BouncyCastleProvider());
-
if (oldPassPhrase == null || oldPassPhrase.equals("")) {
oldPassPhrase = "";
}
@@ -1239,7 +1277,6 @@ public class Apg {
int hashAlgorithm, int compression, boolean forceV3Signature, String passPhrase)
throws IOException, GeneralException, PGPException, NoSuchProviderException,
NoSuchAlgorithmException, SignatureException {
- Security.addProvider(new BouncyCastleProvider());
if (encryptionKeyIds == null) {
encryptionKeyIds = new long[0];
@@ -1394,7 +1431,6 @@ public class Apg {
long signatureKeyId, String signaturePassPhrase, int hashAlgorithm,
boolean forceV3Signature, ProgressDialogUpdater progress) throws GeneralException,
PGPException, IOException, NoSuchAlgorithmException, SignatureException {
- Security.addProvider(new BouncyCastleProvider());
ArmoredOutputStream armorOut = new ArmoredOutputStream(outStream);
armorOut.setHeader("Version", getFullVersion(context));
@@ -1500,7 +1536,6 @@ public class Apg {
int hashAlgorithm, boolean forceV3Signature, ProgressDialogUpdater progress)
throws GeneralException, PGPException, IOException, NoSuchAlgorithmException,
SignatureException {
- Security.addProvider(new BouncyCastleProvider());
ArmoredOutputStream armorOut = null;
OutputStream out = null;
diff --git a/org_apg/src/org/thialfihar/android/apg/Id.java b/org_apg/src/org/thialfihar/android/apg/Id.java
index 138a9535d..d4d23b80e 100644
--- a/org_apg/src/org/thialfihar/android/apg/Id.java
+++ b/org_apg/src/org/thialfihar/android/apg/Id.java
@@ -83,18 +83,31 @@ public final class Id {
// public static final int query_done = 0x21070010;
// public static final int unknown_signature_key = 0x21070011;
// }
-
+
+ // use only lower 16 bits due to compatibility lib
public static final class request {
- public static final int public_keys = 0x21070001;
- public static final int secret_keys = 0x21070002;
- public static final int filename = 0x21070003;
- public static final int output_filename = 0x21070004;
- public static final int key_server_preference = 0x21070005;
- public static final int look_up_key_id = 0x21070006;
- public static final int export_to_server = 0x21070007;
- public static final int import_from_qr_code = 0x21070008;
- public static final int sign_key = 0x21070009;
+ public static final int public_keys = 0x00007001;
+ public static final int secret_keys = 0x00007002;
+ public static final int filename = 0x00007003;
+ public static final int output_filename = 0x00007004;
+ public static final int key_server_preference = 0x00007005;
+ public static final int look_up_key_id = 0x00007006;
+ public static final int export_to_server = 0x00007007;
+ public static final int import_from_qr_code = 0x00007008;
+ public static final int sign_key = 0x00007009;
}
+
+// public static final class request {
+// public static final int public_keys = 0x21070001;
+// public static final int secret_keys = 0x21070002;
+// public static final int filename = 0x21070003;
+// public static final int output_filename = 0x21070004;
+// public static final int key_server_preference = 0x21070005;
+// public static final int look_up_key_id = 0x21070006;
+// public static final int export_to_server = 0x21070007;
+// public static final int import_from_qr_code = 0x21070008;
+// public static final int sign_key = 0x21070009;
+// }
public static final class dialog {
public static final int pass_phrase = 0x21070001;
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 6a27ba45d..b7b2b24bc 100644
--- a/org_apg/src/org/thialfihar/android/apg/service/ApgService.java
+++ b/org_apg/src/org/thialfihar/android/apg/service/ApgService.java
@@ -19,6 +19,7 @@ package org.thialfihar.android.apg.service;
import java.util.ArrayList;
import org.spongycastle.openpgp.PGPSecretKey;
+import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.thialfihar.android.apg.Apg;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.ProgressDialogUpdater;
@@ -147,12 +148,13 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
}
// Operation
- PGPSecretKey newKey = Apg
- .createKey(this, algorithm, keysize, passphrase, masterKey);
+ PGPSecretKeyRing newKeyRing = Apg.createKey(this, algorithm, keysize, passphrase,
+ masterKey);
// Output
Bundle resultData = new Bundle();
- resultData.putByteArray(ApgHandler.NEW_KEY, Utils.PGPSecretKeyToBytes(newKey));
+ resultData.putByteArray(ApgHandler.NEW_KEY,
+ Utils.PGPSecretKeyRingToBytes(newKeyRing));
sendMessageToHandler(ApgHandler.MESSAGE_OKAY, null, resultData);
} catch (Exception e) {
sendErrorToHandler(e);
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 339d743b6..dc102ce12 100644
--- a/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java
+++ b/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java
@@ -169,23 +169,23 @@ public class EditKeyActivity extends SherlockFragmentActivity { // extends BaseA
.getBoolean(Apg.EXTRA_GENERATE_DEFAULT_KEYS);
if (generateDefaultKeys) {
- // generate a RSA 2048 key for encryption and signing!
- try {
- PGPSecretKey masterKey = Apg.createKey(this, Id.choice.algorithm.rsa,
- 2048, mCurrentPassPhrase, null);
-
- // add new masterKey to keys array, which is then added to view
- keys.add(masterKey);
- keysUsages.add(Id.choice.usage.sign_only);
-
- PGPSecretKey subKey = Apg.createKey(this, Id.choice.algorithm.rsa,
- 2048, mCurrentPassPhrase, masterKey);
-
- keys.add(subKey);
- keysUsages.add(Id.choice.usage.encrypt_only);
- } catch (Exception e) {
- Log.e(Constants.TAG, "Creating initial key failed: +" + e);
- }
+// // generate a RSA 2048 key for encryption and signing!
+// try {
+// PGPSecretKey masterKey = Apg.createKey(this, Id.choice.algorithm.rsa,
+// 2048, mCurrentPassPhrase, null);
+//
+// // add new masterKey to keys array, which is then added to view
+// keys.add(masterKey);
+// keysUsages.add(Id.choice.usage.sign_only);
+//
+// PGPSecretKey subKey = Apg.createKey(this, Id.choice.algorithm.rsa,
+// 2048, mCurrentPassPhrase, masterKey);
+//
+// keys.add(subKey);
+// keysUsages.add(Id.choice.usage.encrypt_only);
+// } catch (Exception e) {
+// Log.e(Constants.TAG, "Creating initial key failed: +" + e);
+// }
}
}
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 895e2b5a6..7efdf0b3d 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
@@ -17,6 +17,7 @@
package org.thialfihar.android.apg.ui.widget;
import org.spongycastle.openpgp.PGPSecretKey;
+import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.thialfihar.android.apg.Apg;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.service.ApgHandler;
@@ -48,6 +49,7 @@ import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
+import java.util.Iterator;
import java.util.Vector;
public class SectionView extends LinearLayout implements OnClickListener, EditorListener {
@@ -282,14 +284,27 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
if (message.arg1 == ApgHandler.MESSAGE_OKAY) {
// get new key from data bundle returned from service
Bundle data = message.getData();
- PGPSecretKey newKey = Utils.BytesToPGPSecretKey(data
+ PGPSecretKeyRing newKeyRing = Utils.BytesToPGPSecretKeyRing(data
.getByteArray(ApgHandler.NEW_KEY));
+ boolean isMasterKey = (mEditors.getChildCount() == 0);
+
+ // take only the key from this ring
+ PGPSecretKey newKey = null;
+ Iterator<PGPSecretKey> it = newKeyRing.getSecretKeys();
+
+ if (isMasterKey) {
+ newKey = it.next();
+ } else {
+ // first one is the master key
+ it.next();
+ newKey = it.next();
+ }
+
// add view with new key
KeyEditor view = (KeyEditor) mInflater.inflate(R.layout.edit_key_key_item,
mEditors, false);
view.setEditorListener(SectionView.this);
- boolean isMasterKey = (mEditors.getChildCount() == 0);
view.setValue(newKey, isMasterKey, -1);
mEditors.addView(view);
SectionView.this.updateEditorsVisible();
diff --git a/org_apg/src/org/thialfihar/android/apg/util/Utils.java b/org_apg/src/org/thialfihar/android/apg/util/Utils.java
index 13bfb7b91..394d95954 100644
--- a/org_apg/src/org/thialfihar/android/apg/util/Utils.java
+++ b/org_apg/src/org/thialfihar/android/apg/util/Utils.java
@@ -110,7 +110,7 @@ public class Utils {
* @param keysBytes
* @return
*/
- public static ArrayList<PGPSecretKey> BytesToPGPSecretKeyList(byte[] keysBytes) {
+ public static PGPSecretKeyRing BytesToPGPSecretKeyRing(byte[] keysBytes) {
PGPObjectFactory factory = new PGPObjectFactory(keysBytes);
PGPSecretKeyRing keyRing = null;
try {
@@ -120,6 +120,12 @@ public class Utils {
} catch (IOException e) {
e.printStackTrace();
}
+
+ return keyRing;
+ }
+
+ public static ArrayList<PGPSecretKey> BytesToPGPSecretKeyList(byte[] keysBytes) {
+ PGPSecretKeyRing keyRing = BytesToPGPSecretKeyRing(keysBytes);
ArrayList<PGPSecretKey> keys = new ArrayList<PGPSecretKey>();
Iterator<PGPSecretKey> itr = keyRing.getSecretKeys();
@@ -146,4 +152,14 @@ public class Utils {
}
}
+ public static byte[] PGPSecretKeyRingToBytes(PGPSecretKeyRing keyRing) {
+ try {
+ return keyRing.getEncoded();
+ } catch (IOException e) {
+ Log.e(Constants.TAG, "Encoding failed: ", e);
+
+ return null;
+ }
+ }
+
}