aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain
diff options
context:
space:
mode:
authorVincent Breitmoser <valodim@mugenguild.com>2014-05-03 22:29:09 +0200
committerVincent Breitmoser <valodim@mugenguild.com>2014-05-03 22:29:09 +0200
commitf524fa692c8ab9bd737f7b03a5104ff2b2867669 (patch)
treedc97ee0979d5b647dc3bfe8ab8dea09e413241e0 /OpenKeychain
parent32baf425151b32bca7ce8db97b732bce44238c81 (diff)
downloadopen-keychain-f524fa692c8ab9bd737f7b03a5104ff2b2867669.tar.gz
open-keychain-f524fa692c8ab9bd737f7b03a5104ff2b2867669.tar.bz2
open-keychain-f524fa692c8ab9bd737f7b03a5104ff2b2867669.zip
wrapped-key-ring: more refactoring - no more pgp imports in KeychainIntentService!
Diffstat (limited to 'OpenKeychain')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedKeyRing.java28
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedPublicKey.java13
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedPublicKeyRing.java86
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedSecretKeyRing.java35
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java32
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java54
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java52
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java35
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedSecretKeyRing.java19
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java20
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java79
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java22
-rw-r--r--OpenKeychain/src/main/res/values/strings.xml1
14 files changed, 209 insertions, 269 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedKeyRing.java
index 9e5671a97..334f676c4 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedKeyRing.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedKeyRing.java
@@ -1,44 +1,26 @@
package org.sufficientlysecure.keychain.pgp;
-import org.spongycastle.openpgp.PGPSignature;
-
public abstract class CachedKeyRing {
private final long mMasterKeyId;
- private final int mKeySize;
- private final boolean mIsRevoked;
private final boolean mCanCertify;
- private final long mCreation;
- private final long mExpiry;
- private final int mAlgorithm;
private final byte[] mFingerprint;
private final String mUserId;
private final int mVerified;
private final boolean mHasSecret;
- protected CachedKeyRing(long masterKeyId, int keySize, boolean isRevoked,
- boolean canCertify, long creation, long expiry, int algorithm,
+ protected CachedKeyRing(long masterKeyId, boolean canCertify,
byte[] fingerprint, String userId, int verified, boolean hasSecret)
{
mMasterKeyId = masterKeyId;
- mKeySize = keySize;
- mIsRevoked = isRevoked;
mCanCertify = canCertify;
- mCreation = creation;
- mExpiry = expiry;
- mAlgorithm = algorithm;
mFingerprint = fingerprint;
mUserId = userId;
mVerified = verified;
mHasSecret = hasSecret;
}
- public boolean isRevoked() {
- return mIsRevoked;
- }
-
public byte[] getFingerprint() {
-
return mFingerprint;
}
@@ -54,4 +36,12 @@ public abstract class CachedKeyRing {
return mVerified;
}
+ public boolean canCertify() {
+ return mCanCertify;
+ }
+
+ public boolean hasSecret() {
+ return mHasSecret;
+ }
+
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedPublicKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedPublicKey.java
index 08b9d5a0c..2862b21c5 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedPublicKey.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedPublicKey.java
@@ -31,6 +31,10 @@ public class CachedPublicKey {
return mKey.getKeyID();
}
+ public boolean isRevoked() {
+ return mKey.isRevoked();
+ }
+
public Date getCreationTime() {
return mKey.getCreationTime();
}
@@ -48,6 +52,15 @@ public class CachedPublicKey {
return calendar.getTime();
}
+ public boolean isExpired() {
+ Date creationDate = mKey.getCreationTime();
+ Date expiryDate = mKey.getValidSeconds() > 0
+ ? new Date(creationDate.getTime() + mKey.getValidSeconds() * 1000) : null;
+
+ Date now = new Date();
+ return creationDate.after(now) || (expiryDate != null && expiryDate.before(now));
+ }
+
public boolean isMasterKey() {
return mKey.isMasterKey();
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedPublicKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedPublicKeyRing.java
index 3a45b4ff9..8970d18ec 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedPublicKeyRing.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedPublicKeyRing.java
@@ -2,7 +2,6 @@ package org.sufficientlysecure.keychain.pgp;
import org.spongycastle.bcpg.ArmoredOutputStream;
import org.spongycastle.bcpg.SignatureSubpacketTags;
-import org.spongycastle.bcpg.sig.KeyFlags;
import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPPublicKeyRing;
@@ -17,7 +16,6 @@ import org.sufficientlysecure.keychain.util.IterableIterator;
import java.io.IOException;
import java.security.SignatureException;
import java.util.Arrays;
-import java.util.Date;
import java.util.Iterator;
public class CachedPublicKeyRing extends CachedKeyRing {
@@ -30,8 +28,7 @@ public class CachedPublicKeyRing extends CachedKeyRing {
byte[] fingerprint, String userId, int verified, boolean hasSecret,
byte[] pubkey)
{
- super(masterKeyId, keySize, isRevoked, canCertify, creation, expiry,
- algorithm, fingerprint, userId, verified, hasSecret);
+ super(masterKeyId, canCertify, fingerprint, userId, verified, hasSecret);
mPubKey = pubkey;
}
@@ -55,24 +52,46 @@ public class CachedPublicKeyRing extends CachedKeyRing {
return new CachedPublicKey(this, getRing().getPublicKey(id));
}
+ public CachedPublicKey getFirstSignSubkey() throws PgpGeneralException {
+ // only return master key if no other signing key is available
+ CachedPublicKey masterKey = null;
+ for (PGPPublicKey k : new IterableIterator<PGPPublicKey>(getRing().getPublicKeys())) {
+ CachedPublicKey key = new CachedPublicKey(this, k);
+ if (key.isRevoked() || key.canSign() || key.isExpired()) {
+ continue;
+ }
+ if (key.isMasterKey()) {
+ masterKey = key;
+ } else {
+ return key;
+ }
+ }
+ if(masterKey == null) {
+ // TODO proper exception
+ throw new PgpGeneralException("key not found");
+ }
+ return masterKey;
+ }
+
public CachedPublicKey getFirstEncryptSubkey() throws PgpGeneralException {
// only return master key if no other encryption key is available
- PGPPublicKey masterKey = null;
- for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(getRing().getPublicKeys())) {
- if (key.isRevoked() || !isEncryptionKey(key) || isExpired(key)) {
+ CachedPublicKey masterKey = null;
+ for (PGPPublicKey k : new IterableIterator<PGPPublicKey>(getRing().getPublicKeys())) {
+ CachedPublicKey key = new CachedPublicKey(this, k);
+ if (key.isRevoked() || key.canEncrypt() || key.isExpired()) {
continue;
}
if (key.isMasterKey()) {
masterKey = key;
} else {
- return new CachedPublicKey(this, key);
+ return key;
}
}
if(masterKey == null) {
// TODO proper exception
throw new PgpGeneralException("key not found");
}
- return new CachedPublicKey(this, masterKey);
+ return masterKey;
}
public boolean verifySubkeyBinding(CachedPublicKey cachedSubkey) {
@@ -132,55 +151,6 @@ public class CachedPublicKeyRing extends CachedKeyRing {
}
- static boolean isEncryptionKey(PGPPublicKey key) {
- if (!key.isEncryptionKey()) {
- return false;
- }
-
- if (key.getVersion() <= 3) {
- // this must be true now
- return key.isEncryptionKey();
- }
-
- // special cases
- if (key.getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT) {
- return true;
- }
-
- if (key.getAlgorithm() == PGPPublicKey.RSA_ENCRYPT) {
- return true;
- }
-
- for (PGPSignature sig : new IterableIterator<PGPSignature>(key.getSignatures())) {
- if (key.isMasterKey() && sig.getKeyID() != key.getKeyID()) {
- continue;
- }
- PGPSignatureSubpacketVector hashed = sig.getHashedSubPackets();
-
- if (hashed != null
- && (hashed.getKeyFlags() & (KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE)) != 0) {
- return true;
- }
-
- PGPSignatureSubpacketVector unhashed = sig.getUnhashedSubPackets();
-
- if (unhashed != null
- && (unhashed.getKeyFlags() & (KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE)) != 0) {
- return true;
- }
- }
- return false;
- }
-
- static boolean isExpired(PGPPublicKey key) {
- Date creationDate = key.getCreationTime();
- Date expiryDate = key.getValidSeconds() > 0
- ? new Date(creationDate.getTime() + key.getValidSeconds() * 1000) : null;
-
- Date now = new Date();
- return creationDate.after(now) || (expiryDate != null && expiryDate.before(now));
- }
-
static boolean verifyPrimaryKeyBinding(PGPSignatureSubpacketVector pkts,
PGPPublicKey masterPublicKey,
PGPPublicKey signingPublicKey) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedSecretKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedSecretKeyRing.java
index 097f530fd..590a02b95 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedSecretKeyRing.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CachedSecretKeyRing.java
@@ -9,9 +9,14 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
+import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
+import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
+import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.util.IterableIterator;
+import java.io.IOException;
+import java.security.NoSuchProviderException;
import java.util.Iterator;
public class CachedSecretKeyRing extends CachedKeyRing {
@@ -23,12 +28,15 @@ public class CachedSecretKeyRing extends CachedKeyRing {
byte[] fingerprint, String userId, int verified, boolean hasSecret,
byte[] blob)
{
- super(masterKeyId, keySize, isRevoked, canCertify, creation, expiry,
- algorithm, fingerprint, userId, verified, hasSecret);
+ super(masterKeyId, canCertify, fingerprint, userId, verified, hasSecret);
mRing = (PGPSecretKeyRing) PgpConversionHelper.BytesToPGPKeyRing(blob);
}
+ PGPSecretKeyRing getRing() {
+ return mRing;
+ }
+
public CachedSecretKey getSubKey() {
return new CachedSecretKey(this, mRing.getSecretKey());
}
@@ -110,4 +118,27 @@ public class CachedSecretKeyRing extends CachedKeyRing {
return false;
}
+ public UncachedSecretKeyRing changeSecretKeyPassphrase(String oldPassphrase,
+ String newPassphrase)
+ throws IOException, PGPException, NoSuchProviderException {
+
+ if (oldPassphrase == null) {
+ oldPassphrase = "";
+ }
+ if (newPassphrase == null) {
+ newPassphrase = "";
+ }
+
+ PGPSecretKeyRing newKeyRing = PGPSecretKeyRing.copyWithNewPassword(
+ mRing,
+ new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder()
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build()).setProvider(
+ Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassphrase.toCharArray()),
+ new JcePBESecretKeyEncryptorBuilder(mRing.getSecretKey()
+ .getKeyEncryptionAlgorithm()).build(newPassphrase.toCharArray()));
+
+ return new UncachedSecretKeyRing(newKeyRing);
+
+ }
+
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java
index 86fba979c..2199047cd 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java
@@ -165,36 +165,4 @@ public class PgpConversionHelper {
return os.toByteArray();
}
- /**
- * Convert from PGPSecretKey to byte[]
- *
- * @param key
- * @return
- */
- public static byte[] PGPSecretKeyToBytes(PGPSecretKey key) {
- try {
- return key.getEncoded();
- } catch (IOException e) {
- Log.e(Constants.TAG, "Encoding failed", e);
-
- return null;
- }
- }
-
- /**
- * Convert from PGPSecretKeyRing to byte[]
- *
- * @param keyRing
- * @return
- */
- public static byte[] PGPSecretKeyRingToBytes(PGPSecretKeyRing keyRing) {
- try {
- return keyRing.getEncoded();
- } catch (IOException e) {
- Log.e(Constants.TAG, "Encoding failed", e);
-
- return null;
- }
- }
-
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
index 6de958d8d..a7e1bd603 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
@@ -277,7 +277,7 @@ public class PgpImportExport {
@SuppressWarnings("unchecked")
public int storeKeyRingInCache(UncachedKeyRing keyring) {
- int status = RETURN_ERROR;
+ int status;
try {
PGPSecretKeyRing secretKeyRing = keyring.getSecretRing();
PGPPublicKeyRing publicKeyRing = keyring.getPublicRing();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java
index 5e78a5764..e888d594e 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java
@@ -81,18 +81,6 @@ public class PgpKeyHelper {
return getExpiryDate(key.getPublicKey());
}
- @Deprecated
- public static boolean isExpired(PGPPublicKey key) {
- Date creationDate = getCreationDate(key);
- Date expiryDate = getExpiryDate(key);
- Date now = new Date();
- if (now.compareTo(creationDate) >= 0
- && (expiryDate == null || now.compareTo(expiryDate) <= 0)) {
- return false;
- }
- return true;
- }
-
@SuppressWarnings("unchecked")
@Deprecated
public static PGPSecretKey getKeyNum(PGPSecretKeyRing keyRing, long num) {
@@ -110,48 +98,6 @@ public class PgpKeyHelper {
return null;
}
- @SuppressWarnings("unchecked")
- @Deprecated
- private static Vector<PGPSecretKey> getSigningKeys(PGPSecretKeyRing keyRing) {
- Vector<PGPSecretKey> signingKeys = new Vector<PGPSecretKey>();
-
- for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(keyRing.getSecretKeys())) {
- if (isSigningKey(key)) {
- signingKeys.add(key);
- }
- }
-
- return signingKeys;
- }
-
- @Deprecated
- private static Vector<PGPSecretKey> getUsableSigningKeys(PGPSecretKeyRing keyRing) {
- Vector<PGPSecretKey> usableKeys = new Vector<PGPSecretKey>();
- Vector<PGPSecretKey> signingKeys = getSigningKeys(keyRing);
- PGPSecretKey masterKey = null;
- for (int i = 0; i < signingKeys.size(); ++i) {
- PGPSecretKey key = signingKeys.get(i);
- if (key.isMasterKey()) {
- masterKey = key;
- } else {
- usableKeys.add(key);
- }
- }
- if (masterKey != null) {
- usableKeys.add(masterKey);
- }
- return usableKeys;
- }
-
- @Deprecated
- public static PGPSecretKey getFirstSigningSubkey(PGPSecretKeyRing keyRing) {
- Vector<PGPSecretKey> signingKeys = getUsableSigningKeys(keyRing);
- if (signingKeys.size() == 0) {
- return null;
- }
- return signingKeys.get(0);
- }
-
public static int getKeyUsage(PGPSecretKey key) {
return getKeyUsage(key.getPublicKey());
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
index 2033a91e7..7251709e0 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
@@ -35,7 +35,6 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureGenerator;
import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
-import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
import org.spongycastle.openpgp.PGPUtil;
import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.spongycastle.openpgp.operator.PBESecretKeyEncryptor;
@@ -48,10 +47,8 @@ import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
-import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Primes;
import java.io.IOException;
@@ -66,7 +63,6 @@ import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
-import java.util.List;
import java.util.TimeZone;
/**
@@ -124,7 +120,7 @@ public class PgpKeyOperation {
*/
// TODO: key flags?
- public PGPSecretKey createKey(int algorithmChoice, int keySize, String passphrase,
+ public byte[] createKey(int algorithmChoice, int keySize, String passphrase,
boolean isMasterKey)
throws NoSuchAlgorithmException, PGPException, NoSuchProviderException,
PgpGeneralMsgIdException, InvalidAlgorithmParameterException {
@@ -188,35 +184,15 @@ public class PgpKeyOperation {
PGPEncryptedData.CAST5, sha1Calc)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
- return new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(),
- sha1Calc, isMasterKey, keyEncryptor);
- }
-
- public PGPSecretKeyRing changeSecretKeyPassphrase(PGPSecretKeyRing keyRing, String oldPassphrase,
- String newPassphrase)
- throws IOException, PGPException, NoSuchProviderException {
-
- updateProgress(R.string.progress_building_key, 0, 100);
- if (oldPassphrase == null) {
- oldPassphrase = "";
- }
- if (newPassphrase == null) {
- newPassphrase = "";
+ try {
+ return new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(),
+ sha1Calc, isMasterKey, keyEncryptor).getEncoded();
+ } catch(IOException e) {
+ throw new PgpGeneralMsgIdException(R.string.error_encoding);
}
-
- PGPSecretKeyRing newKeyRing = PGPSecretKeyRing.copyWithNewPassword(
- keyRing,
- new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build()).setProvider(
- Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(oldPassphrase.toCharArray()),
- new JcePBESecretKeyEncryptorBuilder(keyRing.getSecretKey()
- .getKeyEncryptionAlgorithm()).build(newPassphrase.toCharArray()));
-
- return newKeyRing;
-
}
- public Pair<PGPSecretKeyRing, PGPPublicKeyRing> buildNewSecretKey(
+ public UncachedKeyRing buildNewSecretKey(
SaveKeyringParcel saveParcel)
throws PgpGeneralMsgIdException, PGPException, SignatureException, IOException {
@@ -357,17 +333,19 @@ public class PgpKeyOperation {
PGPSecretKeyRing secretKeyRing = keyGen.generateSecretKeyRing();
PGPPublicKeyRing publicKeyRing = keyGen.generatePublicKeyRing();
- return new Pair<PGPSecretKeyRing, PGPPublicKeyRing>(secretKeyRing, publicKeyRing);
+ return new UncachedKeyRing(publicKeyRing, secretKeyRing);
}
- public Pair<PGPSecretKeyRing, PGPPublicKeyRing> buildSecretKey(PGPSecretKeyRing mKR,
- PGPPublicKeyRing pKR,
+ public UncachedKeyRing buildSecretKey(CachedSecretKeyRing wmKR,
+ CachedPublicKeyRing wpKR,
SaveKeyringParcel saveParcel)
throws PgpGeneralMsgIdException, PGPException, SignatureException, IOException {
+ PGPSecretKeyRing mKR = wmKR.getRing();
+ PGPPublicKeyRing pKR = wpKR.getRing();
+
updateProgress(R.string.progress_building_key, 0, 100);
- PGPSecretKey masterKey = saveParcel.keys.get(0);
if (saveParcel.oldPassphrase == null) {
saveParcel.oldPassphrase = "";
@@ -404,7 +382,7 @@ public class PgpKeyOperation {
}
}
- masterKey = mKR.getSecretKey();
+ PGPSecretKey masterKey = mKR.getSecretKey();
PGPPublicKey masterPublicKey = masterKey.getPublicKey();
int usageId = saveParcel.keysUsages.get(0);
@@ -686,7 +664,7 @@ public class PgpKeyOperation {
*/
- return new Pair<PGPSecretKeyRing, PGPPublicKeyRing>(mKR, pKR);
+ return new UncachedKeyRing(pKR, mKR);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java
index 86a2ed48d..58601c49a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java
@@ -1,7 +1,15 @@
package org.sufficientlysecure.keychain.pgp;
+import org.spongycastle.openpgp.PGPObjectFactory;
import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKeyRing;
+import org.spongycastle.openpgp.PGPUtil;
+import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
public class UncachedKeyRing {
@@ -9,8 +17,6 @@ public class UncachedKeyRing {
final PGPSecretKeyRing mSecretRing;
UncachedKeyRing(PGPPublicKeyRing publicRing, PGPSecretKeyRing secretRing) {
- // this one must not be false!
- assert(publicRing != null);
mPublicRing = publicRing;
mSecretRing = secretRing;
}
@@ -26,4 +32,29 @@ public class UncachedKeyRing {
public PGPSecretKeyRing getSecretRing() {
return mSecretRing;
}
+
+ public byte[] getFingerprint() {
+ return mPublicRing.getPublicKey().getFingerprint();
+ }
+
+ public static UncachedKeyRing decodePubkeyFromData(byte[] data)
+ throws PgpGeneralException, IOException {
+ BufferedInputStream bufferedInput =
+ new BufferedInputStream(new ByteArrayInputStream(data));
+ if (bufferedInput.available() > 0) {
+ InputStream in = PGPUtil.getDecoderStream(bufferedInput);
+ PGPObjectFactory objectFactory = new PGPObjectFactory(in);
+
+ // get first object in block
+ Object obj;
+ if ((obj = objectFactory.nextObject()) != null && obj instanceof PGPPublicKeyRing) {
+ return new UncachedKeyRing((PGPPublicKeyRing) obj);
+ } else {
+ throw new PgpGeneralException("Object not recognized as PGPPublicKeyRing!");
+ }
+ } else {
+ throw new PgpGeneralException("Object not recognized as PGPPublicKeyRing!");
+ }
+ }
+
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedSecretKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedSecretKeyRing.java
new file mode 100644
index 000000000..bda9ebbcf
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedSecretKeyRing.java
@@ -0,0 +1,19 @@
+package org.sufficientlysecure.keychain.pgp;
+
+import org.spongycastle.openpgp.PGPSecretKeyRing;
+
+public class UncachedSecretKeyRing {
+
+ final PGPSecretKeyRing mSecretRing;
+
+ UncachedSecretKeyRing(PGPSecretKeyRing secretRing) {
+ mSecretRing = secretRing;
+ }
+
+ // Breaking the pattern here, for key import!
+ // TODO reduce this from public to default visibility!
+ public PGPSecretKeyRing getSecretKeyRing() {
+ return mSecretRing;
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
index 0fe989e84..b135f8920 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
@@ -43,6 +43,8 @@ import org.sufficientlysecure.keychain.pgp.CachedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
+import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
+import org.sufficientlysecure.keychain.pgp.UncachedSecretKeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
@@ -488,8 +490,18 @@ public class ProviderHelper {
* Saves a PGPSecretKeyRing in the DB. This will only work if a corresponding public keyring
* is already in the database!
*/
+ public void saveKeyRing(UncachedSecretKeyRing wrappedRing) throws IOException {
+ // TODO split up getters
+ PGPSecretKeyRing keyRing = wrappedRing.getSecretKeyRing();
+ saveKeyRing(keyRing);
+ }
+
+ /**
+ * Saves a PGPSecretKeyRing in the DB. This will only work if a corresponding public keyring
+ * is already in the database!
+ */
public void saveKeyRing(PGPSecretKeyRing keyRing) throws IOException {
- long masterKeyId = keyRing.getPublicKey().getKeyID();
+ long masterKeyId = keyRing.getSecretKey().getKeyID();
{
Uri uri = Keys.buildKeysUri(Long.toString(masterKeyId));
@@ -526,6 +538,12 @@ public class ProviderHelper {
}
+ public void saveKeyRing(UncachedKeyRing wrappedRing) throws IOException {
+ PGPPublicKeyRing pubRing = wrappedRing.getPublicRing();
+ PGPSecretKeyRing secRing = wrappedRing.getSecretRing();
+ saveKeyRing(pubRing, secRing);
+ }
+
/**
* Saves (or updates) a pair of public and secret KeyRings in the database
*/
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
index d02906c4f..972362f5f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
@@ -27,12 +27,6 @@ import android.os.Messenger;
import android.os.RemoteException;
import org.spongycastle.bcpg.sig.KeyFlags;
-import org.spongycastle.openpgp.PGPKeyRing;
-import org.spongycastle.openpgp.PGPObjectFactory;
-import org.spongycastle.openpgp.PGPPublicKeyRing;
-import org.spongycastle.openpgp.PGPSecretKey;
-import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.spongycastle.openpgp.PGPUtil;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.FileHelper;
@@ -41,7 +35,6 @@ import org.sufficientlysecure.keychain.helper.Preferences;
import org.sufficientlysecure.keychain.pgp.CachedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.CachedSecretKey;
import org.sufficientlysecure.keychain.pgp.CachedSecretKeyRing;
-import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
@@ -51,6 +44,7 @@ import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt;
import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
+import org.sufficientlysecure.keychain.pgp.UncachedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
@@ -63,7 +57,6 @@ import org.sufficientlysecure.keychain.util.KeychainServiceListener;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ProgressScaler;
-import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -516,19 +509,19 @@ public class KeychainIntentService extends IntentService
/* Operation */
ProviderHelper providerHelper = new ProviderHelper(this);
if (!canSign) {
- PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 50, 100));
- PGPSecretKeyRing keyRing = providerHelper.getPGPSecretKeyRing(masterKeyId);
- keyRing = keyOperations.changeSecretKeyPassphrase(keyRing,
- oldPassphrase, newPassphrase);
+ setProgress(R.string.progress_building_key, 0, 100);
+ CachedSecretKeyRing keyRing = providerHelper.getCachedSecretKeyRing(masterKeyId);
+ UncachedSecretKeyRing newKeyRing =
+ keyRing.changeSecretKeyPassphrase(oldPassphrase, newPassphrase);
setProgress(R.string.progress_saving_key_ring, 50, 100);
- providerHelper.saveKeyRing(keyRing);
+ providerHelper.saveKeyRing(newKeyRing);
setProgress(R.string.progress_done, 100, 100);
} else {
PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 90, 100));
- PgpKeyOperation.Pair<PGPSecretKeyRing, PGPPublicKeyRing> pair;
+ UncachedKeyRing pair;
try {
- PGPSecretKeyRing privkey = providerHelper.getPGPSecretKeyRing(masterKeyId);
- PGPPublicKeyRing pubkey = providerHelper.getPGPPublicKeyRing(masterKeyId);
+ CachedSecretKeyRing privkey = providerHelper.getCachedSecretKeyRing(masterKeyId);
+ CachedPublicKeyRing pubkey = providerHelper.getCachedPublicKeyRing(masterKeyId);
pair = keyOperations.buildSecretKey(privkey, pubkey, saveParcel); // edit existing
} catch (ProviderHelper.NotFoundException e) {
@@ -537,7 +530,7 @@ public class KeychainIntentService extends IntentService
setProgress(R.string.progress_saving_key_ring, 90, 100);
// save the pair
- providerHelper.saveKeyRing(pair.second, pair.first);
+ providerHelper.saveKeyRing(pair);
setProgress(R.string.progress_done, 100, 100);
}
PassphraseCacheService.addCachedPassphrase(this, masterKeyId, newPassphrase);
@@ -557,13 +550,11 @@ public class KeychainIntentService extends IntentService
/* Operation */
PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 100, 100));
- PGPSecretKey newKey = keyOperations.createKey(algorithm, keysize,
- passphrase, masterKey);
+ byte[] newKey = keyOperations.createKey(algorithm, keysize, passphrase, masterKey);
/* Output */
Bundle resultData = new Bundle();
- resultData.putByteArray(RESULT_NEW_KEY,
- PgpConversionHelper.PGPSecretKeyToBytes(newKey));
+ resultData.putByteArray(RESULT_NEW_KEY, newKey);
OtherHelper.logDebugBundle(resultData, "resultData");
@@ -576,7 +567,6 @@ public class KeychainIntentService extends IntentService
try {
/* Input */
String passphrase = data.getString(GENERATE_KEY_SYMMETRIC_PASSPHRASE);
- ArrayList<PGPSecretKey> newKeys = new ArrayList<PGPSecretKey>();
ArrayList<Integer> keyUsageList = new ArrayList<Integer>();
/* Operation */
@@ -589,23 +579,27 @@ public class KeychainIntentService extends IntentService
keysTotal);
PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 100, 100));
- PGPSecretKey masterKey = keyOperations.createKey(Constants.choice.algorithm.rsa,
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+ byte[] buf;
+
+ buf = keyOperations.createKey(Constants.choice.algorithm.rsa,
4096, passphrase, true);
- newKeys.add(masterKey);
+ os.write(buf);
keyUsageList.add(KeyFlags.CERTIFY_OTHER);
keysCreated++;
setProgress(keysCreated, keysTotal);
- PGPSecretKey subKey = keyOperations.createKey(Constants.choice.algorithm.rsa,
+ buf = keyOperations.createKey(Constants.choice.algorithm.rsa,
4096, passphrase, false);
- newKeys.add(subKey);
+ os.write(buf);
keyUsageList.add(KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE);
keysCreated++;
setProgress(keysCreated, keysTotal);
- subKey = keyOperations.createKey(Constants.choice.algorithm.rsa,
+ buf = keyOperations.createKey(Constants.choice.algorithm.rsa,
4096, passphrase, false);
- newKeys.add(subKey);
+ os.write(buf);
keyUsageList.add(KeyFlags.SIGN_DATA);
keysCreated++;
setProgress(keysCreated, keysTotal);
@@ -614,10 +608,8 @@ public class KeychainIntentService extends IntentService
// for sign
/* Output */
-
Bundle resultData = new Bundle();
- resultData.putByteArray(RESULT_NEW_KEY,
- PgpConversionHelper.PGPSecretKeyArrayListToBytes(newKeys));
+ resultData.putByteArray(RESULT_NEW_KEY, os.toByteArray());
resultData.putIntegerArrayList(RESULT_KEY_USAGES, keyUsageList);
OtherHelper.logDebugBundle(resultData, "resultData");
@@ -755,30 +747,13 @@ public class KeychainIntentService extends IntentService
}
// create PGPKeyRing object based on downloaded armored key
- PGPKeyRing downloadedKey = null;
- BufferedInputStream bufferedInput =
- new BufferedInputStream(new ByteArrayInputStream(downloadedKeyBytes));
- if (bufferedInput.available() > 0) {
- InputStream in = PGPUtil.getDecoderStream(bufferedInput);
- PGPObjectFactory objectFactory = new PGPObjectFactory(in);
-
- // get first object in block
- Object obj;
- if ((obj = objectFactory.nextObject()) != null) {
- Log.d(Constants.TAG, "Found class: " + obj.getClass());
-
- if (obj instanceof PGPKeyRing) {
- downloadedKey = (PGPKeyRing) obj;
- } else {
- throw new PgpGeneralException("Object not recognized as PGPKeyRing!");
- }
- }
- }
+ UncachedKeyRing downloadedKey =
+ UncachedKeyRing.decodePubkeyFromData(downloadedKeyBytes);
// verify downloaded key by comparing fingerprints
if (entry.getFingerPrintHex() != null) {
String downloadedKeyFp = PgpKeyHelper.convertFingerprintToHex(
- downloadedKey.getPublicKey().getFingerprint());
+ downloadedKey.getFingerprint());
if (downloadedKeyFp.equals(entry.getFingerPrintHex())) {
Log.d(Constants.TAG, "fingerprint of downloaded key is the same as " +
"the requested fingerprint!");
@@ -790,7 +765,7 @@ public class KeychainIntentService extends IntentService
// save key bytes in entry object for doing the
// actual import afterwards
- entry.setBytes(downloadedKey.getEncoded());
+ entry.setBytes(downloadedKeyBytes);
}
Intent importIntent = new Intent(this, KeychainIntentService.class);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
index d1a5dca07..51a229677 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
@@ -34,7 +34,12 @@ import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.pgp.CachedPublicKey;
+import org.sufficientlysecure.keychain.pgp.CachedPublicKeyRing;
+import org.sufficientlysecure.keychain.pgp.CachedSecretKey;
+import org.sufficientlysecure.keychain.pgp.CachedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
+import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.util.Log;
@@ -144,18 +149,14 @@ public class EncryptAsymmetricFragment extends Fragment {
*/
private void preselectKeys(long preselectedSignatureKeyId, long[] preselectedEncryptionKeyIds,
ProviderHelper providerHelper) {
+ // TODO all of this works under the assumption that the first suitable subkey is always used!
+ // not sure if we need to distinguish between different subkeys here?
if (preselectedSignatureKeyId != 0) {
- // TODO: don't use bouncy castle objects!
try {
- PGPSecretKeyRing keyRing = providerHelper.getPGPSecretKeyRingWithKeyId(
- preselectedSignatureKeyId);
-
- PGPSecretKey masterKey = keyRing.getSecretKey();
- if (masterKey != null) {
- PGPSecretKey signKey = PgpKeyHelper.getFirstSigningSubkey(keyRing);
- if (signKey != null) {
- setSignatureKeyId(masterKey.getKeyID());
- }
+ CachedPublicKeyRing keyring =
+ providerHelper.getCachedPublicKeyRing(preselectedSignatureKeyId);
+ if(keyring.hasSecret()) {
+ setSignatureKeyId(keyring.getMasterKeyId());
}
} catch (ProviderHelper.NotFoundException e) {
Log.e(Constants.TAG, "key not found!", e);
@@ -165,7 +166,6 @@ public class EncryptAsymmetricFragment extends Fragment {
if (preselectedEncryptionKeyIds != null) {
Vector<Long> goodIds = new Vector<Long>();
for (int i = 0; i < preselectedEncryptionKeyIds.length; ++i) {
- // TODO One query per selected key?! wtf
try {
long id = providerHelper.getMasterKeyId(
KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(
diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml
index 330bc349d..72a1b38cc 100644
--- a/OpenKeychain/src/main/res/values/strings.xml
+++ b/OpenKeychain/src/main/res/values/strings.xml
@@ -500,5 +500,6 @@
<string name="title_view_cert">View Certificate Details</string>
<string name="unknown_algorithm">unknown</string>
<string name="can_sign_not">cannot sign</string>
+ <string name="error_encoding">Encoding error</string>
</resources>