aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp
diff options
context:
space:
mode:
authorVincent Breitmoser <valodim@mugenguild.com>2015-06-01 00:05:55 +0200
committerVincent Breitmoser <valodim@mugenguild.com>2015-06-01 00:52:18 +0200
commitdbfa55f6b963ff8c5a975c45a2805838eb1781f7 (patch)
treee666a868b791894d71fd78c193ae836ccb047cd9 /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp
parent403f74f55830dcc5eaa027ccebb888a1122992d1 (diff)
downloadopen-keychain-dbfa55f6b963ff8c5a975c45a2805838eb1781f7.tar.gz
open-keychain-dbfa55f6b963ff8c5a975c45a2805838eb1781f7.tar.bz2
open-keychain-dbfa55f6b963ff8c5a975c45a2805838eb1781f7.zip
introduce CachingDataDecryptorFactory towards cached session keys
this commit introduces the CachingDataDecryptorFactory, which wraps a DataDecryptorFactory but supports caching of decrypted session keys. this change also gets rid of runtimeexception based control flow in PgpDecryptVerify.
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java23
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java38
2 files changed, 33 insertions, 28 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java
index 17d342341..31a3925da 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java
@@ -21,23 +21,18 @@ package org.sufficientlysecure.keychain.pgp;
import org.spongycastle.bcpg.S2K;
import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPPrivateKey;
-import org.spongycastle.openpgp.PGPPublicKey;
-import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureGenerator;
import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
-import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
-import org.spongycastle.openpgp.PGPUserAttributeSubpacketVector;
import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.spongycastle.openpgp.operator.PGPContentSignerBuilder;
-import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
+import org.spongycastle.openpgp.operator.jcajce.CachingDataDecryptorFactory;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyConverter;
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
import org.spongycastle.openpgp.operator.jcajce.NfcSyncPGPContentSignerBuilder;
-import org.spongycastle.openpgp.operator.jcajce.NfcSyncPublicKeyDataDecryptorFactoryBuilder;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
@@ -51,7 +46,6 @@ import java.security.interfaces.RSAPrivateCrtKey;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
@@ -270,19 +264,20 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
}
}
- public PublicKeyDataDecryptorFactory getDecryptorFactory(CryptoInputParcel cryptoInput) {
+ public CachingDataDecryptorFactory getCachingDecryptorFactory(CryptoInputParcel cryptoInput) {
if (mPrivateKeyState == PRIVATE_KEY_STATE_LOCKED) {
throw new PrivateKeyNotUnlockedException();
}
if (mPrivateKeyState == PRIVATE_KEY_STATE_DIVERT_TO_CARD) {
- return new NfcSyncPublicKeyDataDecryptorFactoryBuilder()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
- cryptoInput.getCryptoData()
- );
+ return new CachingDataDecryptorFactory(
+ Constants.BOUNCY_CASTLE_PROVIDER_NAME,
+ cryptoInput.getCryptoData());
} else {
- return new JcePublicKeyDataDecryptorFactoryBuilder()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(mPrivateKey);
+ return new CachingDataDecryptorFactory(
+ new JcePublicKeyDataDecryptorFactoryBuilder()
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(mPrivateKey),
+ cryptoInput.getCryptoData());
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
index 4382c9fae..235b0a671 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
@@ -24,6 +24,7 @@ import android.webkit.MimeTypeMap;
import org.openintents.openpgp.OpenPgpMetadata;
import org.openintents.openpgp.OpenPgpSignatureResult;
import org.spongycastle.bcpg.ArmoredInputStream;
+import org.spongycastle.bcpg.PublicKeyEncSessionPacket;
import org.spongycastle.openpgp.PGPCompressedData;
import org.spongycastle.openpgp.PGPEncryptedData;
import org.spongycastle.openpgp.PGPEncryptedDataList;
@@ -40,11 +41,10 @@ import org.spongycastle.openpgp.PGPUtil;
import org.spongycastle.openpgp.jcajce.JcaPGPObjectFactory;
import org.spongycastle.openpgp.operator.PBEDataDecryptorFactory;
import org.spongycastle.openpgp.operator.PGPDigestCalculatorProvider;
-import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
+import org.spongycastle.openpgp.operator.jcajce.CachingDataDecryptorFactory;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder;
-import org.spongycastle.openpgp.operator.jcajce.NfcSyncPublicKeyDataDecryptorFactoryBuilder;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.BaseOperation;
@@ -541,24 +541,33 @@ public class PgpDecryptVerify extends BaseOperation {
currentProgress += 2;
updateProgress(R.string.progress_preparing_streams, currentProgress, 100);
- try {
- PublicKeyDataDecryptorFactory decryptorFactory
- = secretEncryptionKey.getDecryptorFactory(cryptoInput);
- try {
- clear = encryptedDataAsymmetric.getDataStream(decryptorFactory);
- } catch (PGPKeyValidationException | ArrayIndexOutOfBoundsException e) {
- log.add(LogType.MSG_DC_ERROR_CORRUPT_DATA, indent + 1);
- return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
- }
+ CachingDataDecryptorFactory decryptorFactory
+ = secretEncryptionKey.getCachingDecryptorFactory(cryptoInput);
+
+ // special case: if the decryptor does not have a session key cached for this encrypted
+ // data, and can't actually decrypt on its own, return a pending intent
+ if (!decryptorFactory.canDecrypt()
+ && !decryptorFactory.hasCachedSessionData(encryptedDataAsymmetric)) {
- symmetricEncryptionAlgo = encryptedDataAsymmetric.getSymmetricAlgorithm(decryptorFactory);
- } catch (NfcSyncPublicKeyDataDecryptorFactoryBuilder.NfcInteractionNeeded e) {
log.add(LogType.MSG_DC_PENDING_NFC, indent + 1);
return new DecryptVerifyResult(log, RequiredInputParcel.createNfcDecryptOperation(
secretEncryptionKey.getRing().getMasterKeyId(),
- secretEncryptionKey.getKeyId(), e.encryptedSessionKey
+ secretEncryptionKey.getKeyId(), encryptedDataAsymmetric.getSessionKey()[0]
));
+
}
+
+ try {
+ clear = encryptedDataAsymmetric.getDataStream(decryptorFactory);
+ } catch (PGPKeyValidationException | ArrayIndexOutOfBoundsException e) {
+ log.add(LogType.MSG_DC_ERROR_CORRUPT_DATA, indent + 1);
+ return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
+ }
+
+ symmetricEncryptionAlgo = encryptedDataAsymmetric.getSymmetricAlgorithm(decryptorFactory);
+
+ cryptoInput.addCryptoData(decryptorFactory.getCachedSessionKeys());
+
encryptedData = encryptedDataAsymmetric;
} else {
// there wasn't even any useful data
@@ -821,6 +830,7 @@ public class PgpDecryptVerify extends BaseOperation {
// Return a positive result, with metadata and verification info
DecryptVerifyResult result =
new DecryptVerifyResult(DecryptVerifyResult.RESULT_OK, log);
+ result.setCachedCryptoInputParcel(cryptoInput);
result.setDecryptMetadata(metadata);
result.setSignatureResult(signatureResultBuilder.build());
result.setCharset(charset);