PgpSignEncrypt is now context-free

This commit is contained in:
Dominik Schürmann 2014-04-11 19:14:39 +02:00
parent 5346d2e878
commit bd6aeea6db
4 changed files with 51 additions and 22 deletions

View File

@ -27,6 +27,7 @@ import org.spongycastle.openpgp.PGPObjectFactory;
import org.spongycastle.openpgp.PGPPublicKeyRing; import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKeyRing; import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPUtil; import org.spongycastle.openpgp.PGPUtil;
import org.sufficientlysecure.keychain.BuildConfig;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
@ -55,14 +56,14 @@ public class PgpHelper {
Pattern.DOTALL); Pattern.DOTALL);
public static String getVersion(Context context) { public static String getVersion(Context context) {
String version = null; String version;
try { try {
PackageInfo pi = context.getPackageManager().getPackageInfo(Constants.PACKAGE_NAME, 0); PackageInfo pi = context.getPackageManager().getPackageInfo(Constants.PACKAGE_NAME, 0);
version = pi.versionName; version = pi.versionName;
return version; return version;
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
Log.e(Constants.TAG, "Version could not be retrieved!", e); Log.e(Constants.TAG, "Version could not be retrieved!", e);
return "0.0.0"; return "0.0";
} }
} }

View File

@ -18,8 +18,6 @@
package org.sufficientlysecure.keychain.pgp; package org.sufficientlysecure.keychain.pgp;
import android.content.Context;
import org.spongycastle.bcpg.ArmoredOutputStream; import org.spongycastle.bcpg.ArmoredOutputStream;
import org.spongycastle.bcpg.BCPGOutputStream; import org.spongycastle.bcpg.BCPGOutputStream;
import org.spongycastle.openpgp.PGPCompressedDataGenerator; import org.spongycastle.openpgp.PGPCompressedDataGenerator;
@ -67,8 +65,8 @@ import java.util.Date;
* This class uses a Builder pattern! * This class uses a Builder pattern!
*/ */
public class PgpSignEncrypt { public class PgpSignEncrypt {
private Context mContext;
private ProviderHelper mProviderHelper; private ProviderHelper mProviderHelper;
private String mVersionHeader;
private InputData mData; private InputData mData;
private OutputStream mOutStream; private OutputStream mOutStream;
@ -95,11 +93,10 @@ public class PgpSignEncrypt {
} }
} }
private PgpSignEncrypt(Builder builder) { private PgpSignEncrypt(Builder builder) {
// private Constructor can only be called from Builder // private Constructor can only be called from Builder
this.mContext = builder.mContext; this.mProviderHelper = builder.mProviderHelper;
this.mProviderHelper = new ProviderHelper(mContext); this.mVersionHeader = builder.mVersionHeader;
this.mData = builder.mData; this.mData = builder.mData;
this.mOutStream = builder.mOutStream; this.mOutStream = builder.mOutStream;
@ -119,7 +116,8 @@ public class PgpSignEncrypt {
public static class Builder { public static class Builder {
// mandatory parameter // mandatory parameter
private Context mContext; private ProviderHelper mProviderHelper;
private String mVersionHeader;
private InputData mData; private InputData mData;
private OutputStream mOutStream; private OutputStream mOutStream;
@ -137,8 +135,9 @@ public class PgpSignEncrypt {
private boolean mEncryptToSigner = false; private boolean mEncryptToSigner = false;
private boolean mBinaryInput = false; private boolean mBinaryInput = false;
public Builder(Context context, InputData data, OutputStream outStream) { public Builder(ProviderHelper providerHelper, String versionHeader, InputData data, OutputStream outStream) {
this.mContext = context; this.mProviderHelper = providerHelper;
this.mVersionHeader = versionHeader;
this.mData = data; this.mData = data;
this.mOutStream = outStream; this.mOutStream = outStream;
} }
@ -232,6 +231,21 @@ public class PgpSignEncrypt {
} }
} }
public static class KeyExtractionException extends Exception {
public KeyExtractionException() {
}
}
public static class NoPassphraseException extends Exception {
public NoPassphraseException() {
}
}
public static class NoSigningKeyException extends Exception {
public NoSigningKeyException() {
}
}
/** /**
* Signs and/or encrypts data based on parameters of class * Signs and/or encrypts data based on parameters of class
* *
@ -244,7 +258,7 @@ public class PgpSignEncrypt {
*/ */
public void execute() public void execute()
throws IOException, PgpGeneralException, PGPException, NoSuchProviderException, throws IOException, PgpGeneralException, PGPException, NoSuchProviderException,
NoSuchAlgorithmException, SignatureException { NoSuchAlgorithmException, SignatureException, KeyExtractionException, NoSigningKeyException, NoPassphraseException {
boolean enableSignature = mSignatureMasterKeyId != Id.key.none; boolean enableSignature = mSignatureMasterKeyId != Id.key.none;
boolean enableEncryption = ((mEncryptionMasterKeyIds != null && mEncryptionMasterKeyIds.length > 0) boolean enableEncryption = ((mEncryptionMasterKeyIds != null && mEncryptionMasterKeyIds.length > 0)
@ -274,7 +288,7 @@ public class PgpSignEncrypt {
OutputStream out; OutputStream out;
if (mEnableAsciiArmorOutput) { if (mEnableAsciiArmorOutput) {
armorOut = new ArmoredOutputStream(mOutStream); armorOut = new ArmoredOutputStream(mOutStream);
armorOut.setHeader("Version", PgpHelper.getFullVersion(mContext)); armorOut.setHeader("Version", mVersionHeader);
out = armorOut; out = armorOut;
} else { } else {
out = mOutStream; out = mOutStream;
@ -288,16 +302,19 @@ public class PgpSignEncrypt {
try { try {
signingKeyRing = mProviderHelper.getPGPSecretKeyRing(mSignatureMasterKeyId); signingKeyRing = mProviderHelper.getPGPSecretKeyRing(mSignatureMasterKeyId);
} catch (ProviderHelper.NotFoundException e) { } catch (ProviderHelper.NotFoundException e) {
throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed)); throw new NoSigningKeyException();
// throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed));
} }
signingKey = PgpKeyHelper.getSigningKey(signingKeyRing); signingKey = PgpKeyHelper.getSigningKey(signingKeyRing);
if (signingKey == null) { if (signingKey == null) {
throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed)); throw new NoSigningKeyException();
// throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed));
} }
if (mSignaturePassphrase == null) { if (mSignaturePassphrase == null) {
throw new PgpGeneralException( // throw new PgpGeneralException(
mContext.getString(R.string.error_no_signature_passphrase)); // mContext.getString(R.string.error_no_signature_passphrase));
throw new NoPassphraseException();
} }
updateProgress(R.string.progress_extracting_signature_key, 0, 100); updateProgress(R.string.progress_extracting_signature_key, 0, 100);
@ -306,8 +323,9 @@ public class PgpSignEncrypt {
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(mSignaturePassphrase.toCharArray()); Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(mSignaturePassphrase.toCharArray());
signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor); signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
if (signaturePrivateKey == null) { if (signaturePrivateKey == null) {
throw new PgpGeneralException( // throw new PgpGeneralException(
mContext.getString(R.string.error_could_not_extract_private_key)); // mContext.getString(R.string.error_could_not_extract_private_key));
throw new KeyExtractionException();
} }
} }
updateProgress(R.string.progress_preparing_streams, 5, 100); updateProgress(R.string.progress_preparing_streams, 5, 100);

View File

@ -33,6 +33,7 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt; import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
@ -165,7 +166,10 @@ public class OpenPgpService extends RemoteService {
InputData inputData = new InputData(is, inputLength); InputData inputData = new InputData(is, inputLength);
// sign-only // sign-only
PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(getContext(), inputData, os); PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(
new ProviderHelper(getContext()),
PgpHelper.getFullVersion(getContext()),
inputData, os);
builder.enableAsciiArmorOutput(asciiArmor) builder.enableAsciiArmorOutput(asciiArmor)
.signatureHashAlgorithm(accSettings.getHashAlgorithm()) .signatureHashAlgorithm(accSettings.getHashAlgorithm())
.signatureForceV3(false) .signatureForceV3(false)
@ -231,7 +235,10 @@ public class OpenPgpService extends RemoteService {
long inputLength = is.available(); long inputLength = is.available();
InputData inputData = new InputData(is, inputLength); InputData inputData = new InputData(is, inputLength);
PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(getContext(), inputData, os); PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(
new ProviderHelper(getContext()),
PgpHelper.getFullVersion(getContext()),
inputData, os);
builder.enableAsciiArmorOutput(asciiArmor) builder.enableAsciiArmorOutput(asciiArmor)
.compressionId(accSettings.getCompression()) .compressionId(accSettings.getCompression())
.symmetricEncryptionAlgorithm(accSettings.getEncryptionAlgorithm()) .symmetricEncryptionAlgorithm(accSettings.getEncryptionAlgorithm())

View File

@ -311,7 +311,10 @@ public class KeychainIntentService extends IntentService
/* Operation */ /* Operation */
PgpSignEncrypt.Builder builder = PgpSignEncrypt.Builder builder =
new PgpSignEncrypt.Builder(this, inputData, outStream); new PgpSignEncrypt.Builder(
new ProviderHelper(this),
PgpHelper.getFullVersion(this),
inputData, outStream);
builder.progress(this); builder.progress(this);
builder.enableAsciiArmorOutput(useAsciiArmor) builder.enableAsciiArmorOutput(useAsciiArmor)