aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain
diff options
context:
space:
mode:
authorVincent Breitmoser <valodim@mugenguild.com>2014-05-23 16:44:50 +0200
committerVincent Breitmoser <valodim@mugenguild.com>2014-05-23 16:44:50 +0200
commit10ad7be46bd44956116c5ac363ea970bcd8082d6 (patch)
treea1c959bd4dccb7121e934013e93e64f5ce87e5d5 /OpenKeychain
parentcd0aba9d43403877df2130a54bde8ab51c8030d7 (diff)
downloadopen-keychain-10ad7be46bd44956116c5ac363ea970bcd8082d6.tar.gz
open-keychain-10ad7be46bd44956116c5ac363ea970bcd8082d6.tar.bz2
open-keychain-10ad7be46bd44956116c5ac363ea970bcd8082d6.zip
wrapped-key-ring: UncachedKeyRing wraps only one ring of dynamic type
Diffstat (limited to 'OpenKeychain')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java49
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java19
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java12
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java56
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java36
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedPublicKey.java26
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java15
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java14
8 files changed, 126 insertions, 101 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java
index 04b86e295..2d8a97809 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java
@@ -21,15 +21,10 @@ import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
-import org.spongycastle.bcpg.SignatureSubpacketTags;
-import org.spongycastle.openpgp.PGPKeyRing;
-import org.spongycastle.openpgp.PGPPublicKey;
-import org.spongycastle.openpgp.PGPSecretKeyRing;
-import org.spongycastle.openpgp.PGPSignature;
-import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.util.IterableIterator;
+import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
+import org.sufficientlysecure.keychain.pgp.UncachedPublicKey;
import org.sufficientlysecure.keychain.util.Log;
import java.io.IOException;
@@ -233,10 +228,12 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
* Constructor based on key object, used for import from NFC, QR Codes, files
*/
@SuppressWarnings("unchecked")
- public ImportKeysListEntry(Context context, PGPKeyRing pgpKeyRing) {
+ public ImportKeysListEntry(Context context, UncachedKeyRing ring) {
+ // TODO less bouncy castle objects!
+
// save actual key object into entry, used to import it later
try {
- this.mBytes = pgpKeyRing.getEncoded();
+ this.mBytes = ring.getEncoded();
} catch (IOException e) {
Log.e(Constants.TAG, "IOException on pgpKeyRing.getEncoded()", e);
}
@@ -244,42 +241,20 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
// selected is default
this.mSelected = true;
- if (pgpKeyRing instanceof PGPSecretKeyRing) {
- secretKey = true;
- } else {
- secretKey = false;
- }
- PGPPublicKey key = pgpKeyRing.getPublicKey();
+ secretKey = ring.isSecret();
+ UncachedPublicKey key = ring.getPublicKey();
+
+ mPrimaryUserId = key.getPrimaryUserId();
- userIds = new ArrayList<String>();
- for (String userId : new IterableIterator<String>(key.getUserIDs())) {
- userIds.add(userId);
- for (PGPSignature sig : new IterableIterator<PGPSignature>(key.getSignaturesForID(userId))) {
- if (sig.getHashedSubPackets() != null
- && sig.getHashedSubPackets().hasSubpacket(SignatureSubpacketTags.PRIMARY_USER_ID)) {
- try {
- // make sure it's actually valid
- sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider(
- Constants.BOUNCY_CASTLE_PROVIDER_NAME), key);
- if (sig.verifyCertification(userId, key)) {
- mPrimaryUserId = userId;
- }
- } catch (Exception e) {
- // nothing bad happens, the key is just not considered the primary key id
- }
- }
-
- }
- }
// if there was no user id flagged as primary, use the first one
if (mPrimaryUserId == null) {
mPrimaryUserId = userIds.get(0);
}
- this.keyId = key.getKeyID();
+ this.keyId = key.getKeyId();
this.keyIdHex = PgpKeyHelper.convertKeyIdToHex(keyId);
- this.revoked = key.isRevoked();
+ this.revoked = key.maybeRevoked();
this.fingerprintHex = PgpKeyHelper.convertFingerprintToHex(key.getFingerprint());
this.bitStrength = key.getBitStrength();
final int algorithm = key.getAlgorithm();
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 a55765542..e858012f5 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java
@@ -165,7 +165,8 @@ public class PgpImportExport {
}
newPubRing = PGPPublicKeyRing.insertPublicKey(newPubRing, key);
}
- status = storeKeyRingInCache(new UncachedKeyRing(newPubRing ,secretKeyRing));
+ status = storeKeyRingInCache(new UncachedKeyRing(newPubRing),
+ new UncachedKeyRing(secretKeyRing));
} else {
status = storeKeyRingInCache(new UncachedKeyRing((PGPPublicKeyRing) keyring));
}
@@ -278,15 +279,23 @@ public class PgpImportExport {
return returnData;
}
+ public int storeKeyRingInCache(UncachedKeyRing ring) {
+ return storeKeyRingInCache(ring, null);
+ }
+
@SuppressWarnings("unchecked")
- public int storeKeyRingInCache(UncachedKeyRing keyring) {
+ public int storeKeyRingInCache(UncachedKeyRing ring, UncachedKeyRing secretRing) {
int status;
try {
- PGPSecretKeyRing secretKeyRing = keyring.getSecretRing();
- PGPPublicKeyRing publicKeyRing = keyring.getPublicRing();
+ // TODO make sure these are correctly typed!
+ PGPPublicKeyRing publicKeyRing = (PGPPublicKeyRing) ring.getRing();
+ PGPSecretKeyRing secretKeyRing = null;
+ if(secretRing != null) {
+ secretKeyRing = (PGPSecretKeyRing) secretRing.getRing();
+ }
// see what type we have. we can either have a secret + public keyring, or just public
if (secretKeyRing != null) {
- mProviderHelper.saveKeyRing(publicKeyRing, secretKeyRing);
+ mProviderHelper.saveKeyRing(ring, secretRing);
status = RETURN_OK;
} else {
mProviderHelper.saveKeyRing(publicKeyRing);
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 b9634c34a..5e7134dc6 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
@@ -331,15 +331,14 @@ public class PgpKeyOperation {
}
PGPSecretKeyRing secretKeyRing = keyGen.generateSecretKeyRing();
- PGPPublicKeyRing publicKeyRing = keyGen.generatePublicKeyRing();
- return new UncachedKeyRing(publicKeyRing, secretKeyRing);
+ return new UncachedKeyRing(secretKeyRing);
}
- public UncachedKeyRing buildSecretKey(WrappedSecretKeyRing wmKR,
- WrappedPublicKeyRing wpKR,
- SaveKeyringParcel saveParcel)
+ public Pair<UncachedKeyRing, UncachedKeyRing> buildSecretKey(WrappedSecretKeyRing wmKR,
+ WrappedPublicKeyRing wpKR,
+ SaveKeyringParcel saveParcel)
throws PgpGeneralMsgIdException, PGPException, SignatureException, IOException {
PGPSecretKeyRing mKR = wmKR.getRing();
@@ -664,7 +663,8 @@ public class PgpKeyOperation {
*/
- return new UncachedKeyRing(pKR, mKR);
+ return new Pair<UncachedKeyRing,UncachedKeyRing>(new UncachedKeyRing(pKR),
+ new UncachedKeyRing(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 58601c49a..06f890fb4 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java
@@ -1,40 +1,51 @@
package org.sufficientlysecure.keychain.pgp;
+import org.spongycastle.openpgp.PGPKeyRing;
import org.spongycastle.openpgp.PGPObjectFactory;
import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPUtil;
+import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
+import org.sufficientlysecure.keychain.util.Log;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.List;
+import java.util.Vector;
public class UncachedKeyRing {
- final PGPPublicKeyRing mPublicRing;
- final PGPSecretKeyRing mSecretRing;
+ final PGPKeyRing mRing;
+ final boolean mIsSecret;
- UncachedKeyRing(PGPPublicKeyRing publicRing, PGPSecretKeyRing secretRing) {
- mPublicRing = publicRing;
- mSecretRing = secretRing;
+ UncachedKeyRing(PGPKeyRing ring) {
+ mRing = ring;
+ mIsSecret = ring instanceof PGPSecretKeyRing;
}
- UncachedKeyRing(PGPPublicKeyRing publicRing) {
- this(publicRing, null);
+ /* TODO don't use this */
+ @Deprecated
+ public PGPKeyRing getRing() {
+ return mRing;
}
- public PGPPublicKeyRing getPublicRing() {
- return mPublicRing;
+ public UncachedPublicKey getPublicKey() {
+ return new UncachedPublicKey(mRing.getPublicKey());
}
- public PGPSecretKeyRing getSecretRing() {
- return mSecretRing;
+ public boolean isSecret() {
+ return mIsSecret;
+ }
+
+ public byte[] getEncoded() throws IOException {
+ return mRing.getEncoded();
}
public byte[] getFingerprint() {
- return mPublicRing.getPublicKey().getFingerprint();
+ return mRing.getPublicKey().getFingerprint();
}
public static UncachedKeyRing decodePubkeyFromData(byte[] data)
@@ -57,4 +68,25 @@ public class UncachedKeyRing {
}
}
+ public static List<UncachedKeyRing> fromStream(InputStream stream)
+ throws PgpGeneralException, IOException {
+
+ PGPObjectFactory objectFactory = new PGPObjectFactory(PGPUtil.getDecoderStream(stream));
+
+ List<UncachedKeyRing> result = new Vector<UncachedKeyRing>();
+
+ // go through all objects in this block
+ Object obj;
+ while ((obj = objectFactory.nextObject()) != null) {
+ Log.d(Constants.TAG, "Found class: " + obj.getClass());
+
+ if (obj instanceof PGPKeyRing) {
+ result.add(new UncachedKeyRing((PGPKeyRing) obj));
+ } else {
+ Log.e(Constants.TAG, "Object not recognized as PGPKeyRing!");
+ }
+ }
+ return result;
+ }
+
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java
index bc37f6201..7f6fae4a6 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java
@@ -1,14 +1,19 @@
package org.sufficientlysecure.keychain.pgp;
+import org.spongycastle.bcpg.SignatureSubpacketTags;
import org.spongycastle.bcpg.sig.KeyFlags;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
+import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
+import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.util.IterableIterator;
+import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
+import java.util.List;
public class UncachedPublicKey {
protected final PGPPublicKey mPublicKey;
@@ -22,7 +27,8 @@ public class UncachedPublicKey {
return mPublicKey.getKeyID();
}
- public boolean isRevoked() {
+ /** The revocation signature is NOT checked here, so this may be false! */
+ public boolean maybeRevoked() {
return mPublicKey.isRevoked();
}
@@ -60,6 +66,34 @@ public class UncachedPublicKey {
return mPublicKey.getAlgorithm();
}
+ public int getBitStrength() {
+ return mPublicKey.getBitStrength();
+ }
+
+ public String getPrimaryUserId() {
+ List<String> userIds = new ArrayList<String>();
+ for (String userId : new IterableIterator<String>(mPublicKey.getUserIDs())) {
+ userIds.add(userId);
+ for (PGPSignature sig : new IterableIterator<PGPSignature>(mPublicKey.getSignaturesForID(userId))) {
+ if (sig.getHashedSubPackets() != null
+ && sig.getHashedSubPackets().hasSubpacket(SignatureSubpacketTags.PRIMARY_USER_ID)) {
+ try {
+ // make sure it's actually valid
+ sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider(
+ Constants.BOUNCY_CASTLE_PROVIDER_NAME), mPublicKey);
+ if (sig.verifyCertification(userId, mPublicKey)) {
+ return userId;
+ }
+ } catch (Exception e) {
+ // nothing bad happens, the key is just not considered the primary key id
+ }
+ }
+
+ }
+ }
+ return null;
+ }
+
public boolean isElGamalEncrypt() {
return getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedPublicKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedPublicKey.java
index 72352a451..32c6910be 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedPublicKey.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedPublicKey.java
@@ -33,30 +33,4 @@ public class WrappedPublicKey extends UncachedPublicKey {
return new JcePublicKeyKeyEncryptionMethodGenerator(mPublicKey);
}
- public void initSignature(PGPSignature sig) throws PGPException {
- JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
- new JcaPGPContentVerifierBuilderProvider()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
- sig.init(contentVerifierBuilderProvider, mPublicKey);
- }
-
- public void initSignature(PGPOnePassSignature sig) throws PGPException {
- JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
- new JcaPGPContentVerifierBuilderProvider()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
- sig.init(contentVerifierBuilderProvider, mPublicKey);
- }
-
- /** Verify a signature for this pubkey, after it has been initialized by the signer using
- * initSignature(). This method should probably move into a wrapped PGPSignature class
- * at some point.
- */
- public boolean verifySignature(PGPSignature sig, String uid) throws PGPException {
- try {
- return sig.verifyCertification(uid, mPublicKey);
- } catch (SignatureException e) {
- throw new PGPException("Error!", e);
- }
- }
-
}
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 4df86ee9b..67d11f9f0 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
@@ -449,24 +449,23 @@ public class ProviderHelper {
}
- public void saveKeyRing(UncachedKeyRing wrappedRing) throws IOException {
- PGPPublicKeyRing pubRing = wrappedRing.getPublicRing();
- PGPSecretKeyRing secRing = wrappedRing.getSecretRing();
- saveKeyRing(pubRing, secRing);
+ public void saveKeyRing(UncachedKeyRing ring) throws IOException {
+ PGPPublicKeyRing pubRing = (PGPPublicKeyRing) ring.getRing();
+ saveKeyRing(pubRing);
}
/**
* Saves (or updates) a pair of public and secret KeyRings in the database
*/
- public void saveKeyRing(PGPPublicKeyRing pubRing, PGPSecretKeyRing privRing) throws IOException {
- long masterKeyId = pubRing.getPublicKey().getKeyID();
+ public void saveKeyRing(UncachedKeyRing pubRing, UncachedKeyRing secRing) throws IOException {
+ long masterKeyId = pubRing.getPublicKey().getKeyId();
// delete secret keyring (so it isn't unnecessarily saved by public-saveKeyRing below)
mContentResolver.delete(KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId)), null, null);
// save public keyring
- saveKeyRing(pubRing);
- saveKeyRing(privRing);
+ saveKeyRing((PGPPublicKeyRing) pubRing.getRing());
+ saveKeyRing((PGPSecretKeyRing) secRing.getRing());
}
/**
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 b866bdf7f..250e1cdda 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
@@ -524,19 +524,21 @@ public class KeychainIntentService extends IntentService
setProgress(R.string.progress_done, 100, 100);
} else {
PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 90, 100));
- UncachedKeyRing pair;
try {
WrappedSecretKeyRing privkey = providerHelper.getWrappedSecretKeyRing(masterKeyId);
WrappedPublicKeyRing pubkey = providerHelper.getWrappedPublicKeyRing(masterKeyId);
- pair = keyOperations.buildSecretKey(privkey, pubkey, saveParcel); // edit existing
+ PgpKeyOperation.Pair<UncachedKeyRing,UncachedKeyRing> pair =
+ keyOperations.buildSecretKey(privkey, pubkey, saveParcel); // edit existing
+ setProgress(R.string.progress_saving_key_ring, 90, 100);
+ providerHelper.saveKeyRing(pair.first, pair.second);
} catch (ProviderHelper.NotFoundException e) {
- pair = keyOperations.buildNewSecretKey(saveParcel); //new Keyring
+ UncachedKeyRing ring = keyOperations.buildNewSecretKey(saveParcel); //new Keyring
+ // save the pair
+ setProgress(R.string.progress_saving_key_ring, 90, 100);
+ providerHelper.saveKeyRing(ring);
}
- setProgress(R.string.progress_saving_key_ring, 90, 100);
- // save the pair
- providerHelper.saveKeyRing(pair);
setProgress(R.string.progress_done, 100, 100);
}
PassphraseCacheService.addCachedPassphrase(this, masterKeyId, newPassphrase);