diff options
Diffstat (limited to 'OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp')
11 files changed, 721 insertions, 636 deletions
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java index c7dd7d647..1f8dec7a1 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpConversionHelper.java @@ -17,11 +17,6 @@ package org.sufficientlysecure.keychain.pgp; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; - import org.spongycastle.openpgp.PGPKeyRing; import org.spongycastle.openpgp.PGPObjectFactory; import org.spongycastle.openpgp.PGPSecretKey; @@ -29,12 +24,17 @@ import org.spongycastle.openpgp.PGPSecretKeyRing; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.util.Log; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; + public class PgpConversionHelper { /** * Convert from byte[] to PGPKeyRing - * + * * @param keysBytes * @return */ @@ -54,7 +54,7 @@ public class PgpConversionHelper { /** * Convert from byte[] to ArrayList<PGPSecretKey> - * + * * @param keysBytes * @return */ @@ -90,10 +90,10 @@ public class PgpConversionHelper { /** * Convert from byte[] to PGPSecretKey - * + * <p/> * Singles keys are encoded as keyRings with one single key in it by Bouncy Castle - * - * @param keysBytes + * + * @param keyBytes * @return */ public static PGPSecretKey BytesToPGPSecretKey(byte[] keyBytes) { @@ -105,13 +105,13 @@ public class PgpConversionHelper { Log.e(Constants.TAG, "Error while converting to PGPSecretKey!", e); } PGPSecretKey secKey = null; - if(obj instanceof PGPSecretKey) { - if ((secKey = (PGPSecretKey)obj ) == null) { + if (obj instanceof PGPSecretKey) { + if ((secKey = (PGPSecretKey) obj) == null) { Log.e(Constants.TAG, "No keys given!"); } - } else if(obj instanceof PGPSecretKeyRing) { //master keys are sent as keyrings + } else if (obj instanceof PGPSecretKeyRing) { //master keys are sent as keyrings PGPSecretKeyRing keyRing = null; - if ((keyRing = (PGPSecretKeyRing)obj) == null) { + if ((keyRing = (PGPSecretKeyRing) obj) == null) { Log.e(Constants.TAG, "No keys given!"); } secKey = keyRing.getSecretKey(); @@ -122,7 +122,7 @@ public class PgpConversionHelper { /** * Convert from ArrayList<PGPSecretKey> to byte[] - * + * * @param keys * @return */ @@ -141,8 +141,8 @@ public class PgpConversionHelper { /** * Convert from PGPSecretKey to byte[] - * - * @param keysBytes + * + * @param key * @return */ public static byte[] PGPSecretKeyToBytes(PGPSecretKey key) { @@ -157,8 +157,8 @@ public class PgpConversionHelper { /** * Convert from PGPSecretKeyRing to byte[] - * - * @param keysBytes + * + * @param keyRing * @return */ public static byte[] PGPSecretKeyRingToBytes(PGPSecretKeyRing keyRing) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index ccd6ff8df..571729bc5 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -18,38 +18,16 @@ package org.sufficientlysecure.keychain.pgp; import android.content.Context; - import org.openintents.openpgp.OpenPgpSignatureResult; import org.spongycastle.bcpg.ArmoredInputStream; import org.spongycastle.bcpg.SignatureSubpacketTags; -import org.spongycastle.openpgp.PGPCompressedData; -import org.spongycastle.openpgp.PGPEncryptedData; -import org.spongycastle.openpgp.PGPEncryptedDataList; -import org.spongycastle.openpgp.PGPException; -import org.spongycastle.openpgp.PGPLiteralData; -import org.spongycastle.openpgp.PGPObjectFactory; -import org.spongycastle.openpgp.PGPOnePassSignature; -import org.spongycastle.openpgp.PGPOnePassSignatureList; -import org.spongycastle.openpgp.PGPPBEEncryptedData; -import org.spongycastle.openpgp.PGPPrivateKey; -import org.spongycastle.openpgp.PGPPublicKey; -import org.spongycastle.openpgp.PGPPublicKeyEncryptedData; -import org.spongycastle.openpgp.PGPPublicKeyRing; -import org.spongycastle.openpgp.PGPSecretKey; -import org.spongycastle.openpgp.PGPSecretKeyRing; -import org.spongycastle.openpgp.PGPSignature; -import org.spongycastle.openpgp.PGPSignatureList; -import org.spongycastle.openpgp.PGPSignatureSubpacketVector; +import org.spongycastle.openpgp.*; import org.spongycastle.openpgp.PGPUtil; import org.spongycastle.openpgp.operator.PBEDataDecryptorFactory; import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; import org.spongycastle.openpgp.operator.PGPDigestCalculatorProvider; import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory; -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.JcePBESecretKeyDecryptorBuilder; -import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; +import org.spongycastle.openpgp.operator.jcajce.*; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; @@ -59,12 +37,7 @@ import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; import java.security.SignatureException; import java.util.Iterator; @@ -72,57 +45,57 @@ import java.util.Iterator; * This class uses a Builder pattern! */ public class PgpDecryptVerify { - private Context context; - private InputData data; - private OutputStream outStream; + private Context mContext; + private InputData mData; + private OutputStream mOutStream; - private ProgressDialogUpdater progressDialogUpdater; - private boolean assumeSymmetric; - private String passphrase; - private long enforcedKeyId; + private ProgressDialogUpdater mProgressDialogUpdater; + private boolean mAssumeSymmetric; + private String mPassphrase; + private long mEnforcedKeyId; private PgpDecryptVerify(Builder builder) { // private Constructor can only be called from Builder - this.context = builder.context; - this.data = builder.data; - this.outStream = builder.outStream; - - this.progressDialogUpdater = builder.progressDialogUpdater; - this.assumeSymmetric = builder.assumeSymmetric; - this.passphrase = builder.passphrase; - this.enforcedKeyId = builder.enforcedKeyId; + this.mContext = builder.mContext; + this.mData = builder.mData; + this.mOutStream = builder.mOutStream; + + this.mProgressDialogUpdater = builder.mProgressDialogUpdater; + this.mAssumeSymmetric = builder.mAssumeSymmetric; + this.mPassphrase = builder.mPassphrase; + this.mEnforcedKeyId = builder.mEnforcedKeyId; } public static class Builder { // mandatory parameter - private Context context; - private InputData data; - private OutputStream outStream; + private Context mContext; + private InputData mData; + private OutputStream mOutStream; // optional - private ProgressDialogUpdater progressDialogUpdater = null; - private boolean assumeSymmetric = false; - private String passphrase = ""; - private long enforcedKeyId = 0; + private ProgressDialogUpdater mProgressDialogUpdater = null; + private boolean mAssumeSymmetric = false; + private String mPassphrase = ""; + private long mEnforcedKeyId = 0; public Builder(Context context, InputData data, OutputStream outStream) { - this.context = context; - this.data = data; - this.outStream = outStream; + this.mContext = context; + this.mData = data; + this.mOutStream = outStream; } public Builder progressDialogUpdater(ProgressDialogUpdater progressDialogUpdater) { - this.progressDialogUpdater = progressDialogUpdater; + this.mProgressDialogUpdater = progressDialogUpdater; return this; } public Builder assumeSymmetric(boolean assumeSymmetric) { - this.assumeSymmetric = assumeSymmetric; + this.mAssumeSymmetric = assumeSymmetric; return this; } public Builder passphrase(String passphrase) { - this.passphrase = passphrase; + this.mPassphrase = passphrase; return this; } @@ -134,7 +107,7 @@ public class PgpDecryptVerify { * @return */ public Builder enforcedKeyId(long enforcedKeyId) { - this.enforcedKeyId = enforcedKeyId; + this.mEnforcedKeyId = enforcedKeyId; return this; } @@ -144,14 +117,14 @@ public class PgpDecryptVerify { } public void updateProgress(int message, int current, int total) { - if (progressDialogUpdater != null) { - progressDialogUpdater.setProgress(message, current, total); + if (mProgressDialogUpdater != null) { + mProgressDialogUpdater.setProgress(message, current, total); } } public void updateProgress(int current, int total) { - if (progressDialogUpdater != null) { - progressDialogUpdater.setProgress(current, total); + if (mProgressDialogUpdater != null) { + mProgressDialogUpdater.setProgress(current, total); } } @@ -196,7 +169,7 @@ public class PgpDecryptVerify { public PgpDecryptVerifyResult execute() throws IOException, PgpGeneralException, PGPException, SignatureException { // automatically works with ascii armor input and binary - InputStream in = PGPUtil.getDecoderStream(data.getInputStream()); + InputStream in = PGPUtil.getDecoderStream(mData.getInputStream()); if (in instanceof ArmoredInputStream) { ArmoredInputStream aIn = (ArmoredInputStream) in; // it is ascii armored @@ -240,7 +213,7 @@ public class PgpDecryptVerify { } if (enc == null) { - throw new PgpGeneralException(context.getString(R.string.error_invalid_data)); + throw new PgpGeneralException(mContext.getString(R.string.error_invalid_data)); } InputStream clear; @@ -250,7 +223,7 @@ public class PgpDecryptVerify { // TODO: currently we always only look at the first known key or symmetric encryption, // there might be more... - if (assumeSymmetric) { + if (mAssumeSymmetric) { PGPPBEEncryptedData pbe = null; Iterator<?> it = enc.getEncryptedDataObjects(); // find secret key @@ -264,7 +237,7 @@ public class PgpDecryptVerify { if (pbe == null) { throw new PgpGeneralException( - context.getString(R.string.error_no_symmetric_encryption_packet)); + mContext.getString(R.string.error_no_symmetric_encryption_packet)); } updateProgress(R.string.progress_preparing_streams, currentProgress, 100); @@ -273,7 +246,7 @@ public class PgpDecryptVerify { .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(); PBEDataDecryptorFactory decryptorFactory = new JcePBEDataDecryptorFactoryBuilder( digestCalcProvider).setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - passphrase.toCharArray()); + mPassphrase.toCharArray()); clear = pbe.getDataStream(decryptorFactory); @@ -290,33 +263,37 @@ public class PgpDecryptVerify { Object obj = it.next(); if (obj instanceof PGPPublicKeyEncryptedData) { PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj; - secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, encData.getKeyID()); + secretKey = ProviderHelper.getPGPSecretKeyByKeyId(mContext, encData.getKeyID()); if (secretKey != null) { // secret key exists in database // allow only a specific key for decryption? - if (enforcedKeyId != 0) { + if (mEnforcedKeyId != 0) { // TODO: improve this code! get master key directly! - PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(context, encData.getKeyID()); + PGPSecretKeyRing secretKeyRing = + ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, encData.getKeyID()); long masterKeyId = PgpKeyHelper.getMasterKey(secretKeyRing).getKeyID(); Log.d(Constants.TAG, "encData.getKeyID():" + encData.getKeyID()); - Log.d(Constants.TAG, "enforcedKeyId: " + enforcedKeyId); + Log.d(Constants.TAG, "enforcedKeyId: " + mEnforcedKeyId); Log.d(Constants.TAG, "masterKeyId: " + masterKeyId); - if (enforcedKeyId != masterKeyId) { - throw new PgpGeneralException(context.getString(R.string.error_no_secret_key_found)); + if (mEnforcedKeyId != masterKeyId) { + throw new PgpGeneralException( + mContext.getString(R.string.error_no_secret_key_found)); } } pbe = encData; // if no passphrase was explicitly set try to get it from the cache service - if (passphrase == null) { + if (mPassphrase == null) { // returns "" if key has no passphrase - passphrase = PassphraseCacheService.getCachedPassphrase(context, encData.getKeyID()); + mPassphrase = + PassphraseCacheService.getCachedPassphrase(mContext, encData.getKeyID()); - // if passphrase was not cached, return here indicating that a passphrase is missing! - if (passphrase == null) { + // if passphrase was not cached, return here + // indicating that a passphrase is missing! + if (mPassphrase == null) { returnData.setKeyPassphraseNeeded(true); return returnData; } @@ -330,7 +307,7 @@ public class PgpDecryptVerify { } if (secretKey == null) { - throw new PgpGeneralException(context.getString(R.string.error_no_secret_key_found)); + throw new PgpGeneralException(mContext.getString(R.string.error_no_secret_key_found)); } currentProgress += 5; @@ -339,14 +316,14 @@ public class PgpDecryptVerify { try { PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - passphrase.toCharArray()); + mPassphrase.toCharArray()); privateKey = secretKey.extractPrivateKey(keyDecryptor); } catch (PGPException e) { - throw new PGPException(context.getString(R.string.error_wrong_passphrase)); + throw new PGPException(mContext.getString(R.string.error_wrong_passphrase)); } if (privateKey == null) { throw new PgpGeneralException( - context.getString(R.string.error_could_not_extract_private_key)); + mContext.getString(R.string.error_could_not_extract_private_key)); } currentProgress += 5; updateProgress(R.string.progress_preparing_streams, currentProgress, 100); @@ -386,7 +363,7 @@ public class PgpDecryptVerify { for (int i = 0; i < sigList.size(); ++i) { signature = sigList.get(i); signatureKey = ProviderHelper - .getPGPPublicKeyByKeyId(context, signature.getKeyID()); + .getPGPPublicKeyByKeyId(mContext, signature.getKeyID()); if (signatureKeyId == 0) { signatureKeyId = signature.getKeyID(); } @@ -397,7 +374,7 @@ public class PgpDecryptVerify { signatureKeyId = signature.getKeyID(); String userId = null; PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId( - context, signatureKeyId); + mContext, signatureKeyId); if (signKeyRing != null) { userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing)); } @@ -409,7 +386,8 @@ public class PgpDecryptVerify { signatureResult.setKeyId(signatureKeyId); if (signature != null) { - JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() + JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = + new JcaPGPContentVerifierBuilderProvider() .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); signature.init(contentVerifierBuilderProvider, signatureKey); @@ -444,9 +422,9 @@ public class PgpDecryptVerify { int n; // TODO: progress calculation is broken here! Try to rework it based on commented code! // int progress = 0; - long startPos = data.getStreamPosition(); + long startPos = mData.getStreamPosition(); while ((n = dataIn.read(buffer)) > 0) { - outStream.write(buffer, 0, n); + mOutStream.write(buffer, 0, n); // progress += n; if (signature != null) { try { @@ -460,11 +438,11 @@ public class PgpDecryptVerify { // unknown size, but try to at least have a moving, slowing down progress bar // currentProgress = startProgress + (endProgress - startProgress) * progress // / (progress + 100000); - if (data.getSize() - startPos == 0) { + if (mData.getSize() - startPos == 0) { currentProgress = endProgress; } else { currentProgress = (int) (startProgress + (endProgress - startProgress) - * (data.getStreamPosition() - startPos) / (data.getSize() - startPos)); + * (mData.getStreamPosition() - startPos) / (mData.getSize() - startPos)); } updateProgress(currentProgress, 100); } @@ -480,7 +458,7 @@ public class PgpDecryptVerify { signatureResult.setSignatureOnly(false); //Now check binding signatures - boolean validKeyBinding = verifyKeyBinding(context, messageSignature, signatureKey); + boolean validKeyBinding = verifyKeyBinding(mContext, messageSignature, signatureKey); boolean validSignature = signature.verify(messageSignature); // TODO: implement CERTIFIED! @@ -499,7 +477,7 @@ public class PgpDecryptVerify { } else { // failed Log.d(Constants.TAG, "Integrity verification: failed!"); - throw new PgpGeneralException(context.getString(R.string.error_integrity_check_failed)); + throw new PgpGeneralException(mContext.getString(R.string.error_integrity_check_failed)); } } else { // no integrity check @@ -555,21 +533,21 @@ public class PgpDecryptVerify { out.close(); byte[] clearText = out.toByteArray(); - outStream.write(clearText); + mOutStream.write(clearText); updateProgress(R.string.progress_processing_signature, 60, 100); PGPObjectFactory pgpFact = new PGPObjectFactory(aIn); PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject(); if (sigList == null) { - throw new PgpGeneralException(context.getString(R.string.error_corrupt_data)); + throw new PgpGeneralException(mContext.getString(R.string.error_corrupt_data)); } PGPSignature signature = null; long signatureKeyId = 0; PGPPublicKey signatureKey = null; for (int i = 0; i < sigList.size(); ++i) { signature = sigList.get(i); - signatureKey = ProviderHelper.getPGPPublicKeyByKeyId(context, signature.getKeyID()); + signatureKey = ProviderHelper.getPGPPublicKeyByKeyId(mContext, signature.getKeyID()); if (signatureKeyId == 0) { signatureKeyId = signature.getKeyID(); } @@ -579,7 +557,7 @@ public class PgpDecryptVerify { } else { signatureKeyId = signature.getKeyID(); String userId = null; - PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(context, + PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(mContext, signatureKeyId); if (signKeyRing != null) { userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing)); @@ -623,7 +601,7 @@ public class PgpDecryptVerify { } //Now check binding signatures - boolean validKeyBinding = verifyKeyBinding(context, signature, signatureKey); + boolean validKeyBinding = verifyKeyBinding(mContext, signature, signatureKey); boolean validSignature = signature.verify(); if (validSignature & validKeyBinding) { @@ -638,7 +616,8 @@ public class PgpDecryptVerify { return returnData; } - private static boolean verifyKeyBinding(Context context, PGPSignature signature, PGPPublicKey signatureKey) { + private static boolean verifyKeyBinding(Context context, + PGPSignature signature, PGPPublicKey signatureKey) { long signatureKeyId = signature.getKeyID(); boolean validKeyBinding = false; @@ -673,7 +652,8 @@ public class PgpDecryptVerify { //about keys without subkey signing. Can't get it to import a slightly broken one //either, so we will err on bad subkey binding here. PGPSignature sig = itr.next(); - if (sig.getKeyID() == masterPublicKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { + if (sig.getKeyID() == masterPublicKey.getKeyID() && + sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { //check and if ok, check primary key binding. try { sig.init(contentVerifierBuilderProvider, masterPublicKey); @@ -684,34 +664,37 @@ public class PgpDecryptVerify { continue; } - if (validTempSubkeyBinding) + if (validTempSubkeyBinding) { validSubkeyBinding = true; + } if (validTempSubkeyBinding) { validPrimaryKeyBinding = verifyPrimaryKeyBinding(sig.getUnhashedSubPackets(), masterPublicKey, signingPublicKey); - if (validPrimaryKeyBinding) + if (validPrimaryKeyBinding) { break; + } validPrimaryKeyBinding = verifyPrimaryKeyBinding(sig.getHashedSubPackets(), masterPublicKey, signingPublicKey); - if (validPrimaryKeyBinding) + if (validPrimaryKeyBinding) { break; + } } } } return (validSubkeyBinding & validPrimaryKeyBinding); } - private static boolean verifyPrimaryKeyBinding(PGPSignatureSubpacketVector Pkts, - PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { + private static boolean verifyPrimaryKeyBinding(PGPSignatureSubpacketVector pkts, + PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { boolean validPrimaryKeyBinding = false; JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); PGPSignatureList eSigList; - if (Pkts.hasSubpacket(SignatureSubpacketTags.EMBEDDED_SIGNATURE)) { + if (pkts.hasSubpacket(SignatureSubpacketTags.EMBEDDED_SIGNATURE)) { try { - eSigList = Pkts.getEmbeddedSignatures(); + eSigList = pkts.getEmbeddedSignatures(); } catch (IOException e) { return false; } catch (PGPException e) { @@ -723,8 +706,9 @@ public class PgpDecryptVerify { try { emSig.init(contentVerifierBuilderProvider, signingPublicKey); validPrimaryKeyBinding = emSig.verifyCertification(masterPublicKey, signingPublicKey); - if (validPrimaryKeyBinding) + if (validPrimaryKeyBinding) { break; + } } catch (PGPException e) { continue; } catch (SignatureException e) { @@ -743,10 +727,9 @@ public class PgpDecryptVerify { * @param sig * @param line * @throws SignatureException - * @throws IOException */ private static void processLine(PGPSignature sig, byte[] line) - throws SignatureException, IOException { + throws SignatureException { int length = getLengthWithoutWhiteSpace(line); if (length > 0) { sig.update(line, 0, length); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java index 0477c4fdf..d4a4f6075 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java @@ -19,36 +19,35 @@ package org.sufficientlysecure.keychain.pgp; import android.os.Parcel; import android.os.Parcelable; - import org.openintents.openpgp.OpenPgpSignatureResult; public class PgpDecryptVerifyResult implements Parcelable { - boolean symmetricPassphraseNeeded; - boolean keyPassphraseNeeded; - OpenPgpSignatureResult signatureResult; + boolean mSymmetricPassphraseNeeded; + boolean mKeyPassphraseNeeded; + OpenPgpSignatureResult mSignatureResult; public boolean isSymmetricPassphraseNeeded() { - return symmetricPassphraseNeeded; + return mSymmetricPassphraseNeeded; } public void setSymmetricPassphraseNeeded(boolean symmetricPassphraseNeeded) { - this.symmetricPassphraseNeeded = symmetricPassphraseNeeded; + this.mSymmetricPassphraseNeeded = symmetricPassphraseNeeded; } public boolean isKeyPassphraseNeeded() { - return keyPassphraseNeeded; + return mKeyPassphraseNeeded; } public void setKeyPassphraseNeeded(boolean keyPassphraseNeeded) { - this.keyPassphraseNeeded = keyPassphraseNeeded; + this.mKeyPassphraseNeeded = keyPassphraseNeeded; } public OpenPgpSignatureResult getSignatureResult() { - return signatureResult; + return mSignatureResult; } public void setSignatureResult(OpenPgpSignatureResult signatureResult) { - this.signatureResult = signatureResult; + this.mSignatureResult = signatureResult; } public PgpDecryptVerifyResult() { @@ -56,9 +55,9 @@ public class PgpDecryptVerifyResult implements Parcelable { } public PgpDecryptVerifyResult(PgpDecryptVerifyResult b) { - this.symmetricPassphraseNeeded = b.symmetricPassphraseNeeded; - this.keyPassphraseNeeded = b.keyPassphraseNeeded; - this.signatureResult = b.signatureResult; + this.mSymmetricPassphraseNeeded = b.mSymmetricPassphraseNeeded; + this.mKeyPassphraseNeeded = b.mKeyPassphraseNeeded; + this.mSignatureResult = b.mSignatureResult; } @@ -67,17 +66,17 @@ public class PgpDecryptVerifyResult implements Parcelable { } public void writeToParcel(Parcel dest, int flags) { - dest.writeByte((byte) (symmetricPassphraseNeeded ? 1 : 0)); - dest.writeByte((byte) (keyPassphraseNeeded ? 1 : 0)); - dest.writeParcelable(signatureResult, 0); + dest.writeByte((byte) (mSymmetricPassphraseNeeded ? 1 : 0)); + dest.writeByte((byte) (mKeyPassphraseNeeded ? 1 : 0)); + dest.writeParcelable(mSignatureResult, 0); } public static final Creator<PgpDecryptVerifyResult> CREATOR = new Creator<PgpDecryptVerifyResult>() { public PgpDecryptVerifyResult createFromParcel(final Parcel source) { PgpDecryptVerifyResult vr = new PgpDecryptVerifyResult(); - vr.symmetricPassphraseNeeded = source.readByte() == 1; - vr.keyPassphraseNeeded = source.readByte() == 1; - vr.signatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader()); + vr.mSymmetricPassphraseNeeded = source.readByte() == 1; + vr.mKeyPassphraseNeeded = source.readByte() == 1; + vr.mSignatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader()); return vr; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java index 7ac904d89..2680d77af 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java @@ -17,22 +17,10 @@ package org.sufficientlysecure.keychain.pgp; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.RandomAccessFile; -import java.security.SecureRandom; -import java.util.Iterator; -import java.util.regex.Pattern; - -import org.spongycastle.openpgp.PGPEncryptedDataList; -import org.spongycastle.openpgp.PGPObjectFactory; -import org.spongycastle.openpgp.PGPPublicKeyEncryptedData; -import org.spongycastle.openpgp.PGPPublicKeyRing; -import org.spongycastle.openpgp.PGPSecretKey; -import org.spongycastle.openpgp.PGPSecretKeyRing; -import org.spongycastle.openpgp.PGPUtil; +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager.NameNotFoundException; +import org.spongycastle.openpgp.*; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; @@ -42,21 +30,25 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; -import android.content.Context; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager.NameNotFoundException; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.security.SecureRandom; +import java.util.Iterator; +import java.util.regex.Pattern; public class PgpHelper { - public static Pattern PGP_MESSAGE = Pattern.compile( + public static final Pattern PGP_MESSAGE = Pattern.compile( ".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", Pattern.DOTALL); - public static Pattern PGP_SIGNED_MESSAGE = Pattern + public static final Pattern PGP_SIGNED_MESSAGE = Pattern .compile( ".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*", Pattern.DOTALL); - public static Pattern PGP_PUBLIC_KEY = Pattern.compile( + public static final Pattern PGP_PUBLIC_KEY = Pattern.compile( ".*?(-----BEGIN PGP PUBLIC KEY BLOCK-----.*?-----END PGP PUBLIC KEY BLOCK-----).*", Pattern.DOTALL); @@ -140,7 +132,7 @@ public class PgpHelper { /** * Generate a random filename - * + * * @param length * @return */ @@ -170,7 +162,7 @@ public class PgpHelper { /** * Go once through stream to get length of stream. The length is later used to display progress * when encrypting/decrypting - * + * * @param in * @return * @throws IOException @@ -187,17 +179,16 @@ public class PgpHelper { /** * Deletes file securely by overwriting it with random data before deleting it. - * + * <p/> * TODO: Does this really help on flash storage? - * + * * @param context * @param progress * @param file - * @throws FileNotFoundException * @throws IOException */ public static void deleteFileSecurely(Context context, ProgressDialogUpdater progress, File file) - throws FileNotFoundException, IOException { + throws IOException { long length = file.length(); SecureRandom random = new SecureRandom(); RandomAccessFile raf = new RandomAccessFile(file, "rws"); @@ -207,8 +198,9 @@ public class PgpHelper { int pos = 0; String msg = context.getString(R.string.progress_deleting_securely, file.getName()); while (pos < length) { - if (progress != null) + if (progress != null) { progress.setProgress(msg, (int) (100 * pos / length), 100); + } random.nextBytes(data); raf.write(data); pos += data.length; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java index 2495a212c..0e0fdec83 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java @@ -17,24 +17,11 @@ package org.sufficientlysecure.keychain.pgp; -import java.io.BufferedInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - +import android.content.Context; +import android.os.Bundle; +import android.os.Environment; import org.spongycastle.bcpg.ArmoredOutputStream; -import org.spongycastle.openpgp.PGPException; -import org.spongycastle.openpgp.PGPKeyRing; -import org.spongycastle.openpgp.PGPObjectFactory; -import org.spongycastle.openpgp.PGPPublicKey; -import org.spongycastle.openpgp.PGPPublicKeyRing; -import org.spongycastle.openpgp.PGPSecretKey; -import org.spongycastle.openpgp.PGPSecretKeyRing; -import org.spongycastle.openpgp.PGPUtil; +import org.spongycastle.openpgp.*; import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; @@ -43,28 +30,37 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; -import org.sufficientlysecure.keychain.util.HkpKeyServer; -import org.sufficientlysecure.keychain.util.InputData; -import org.sufficientlysecure.keychain.util.IterableIterator; +import org.sufficientlysecure.keychain.util.*; import org.sufficientlysecure.keychain.util.KeyServer.AddKeyException; -import org.sufficientlysecure.keychain.util.Log; -import org.sufficientlysecure.keychain.util.PositionAwareInputStream; -import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; -import android.content.Context; -import android.os.Bundle; -import android.os.Environment; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.security.Provider; +import java.util.ArrayList; +import java.util.List; public class PgpImportExport { + private Context mContext; private ProgressDialogUpdater mProgress; + private KeychainServiceListener mKeychainServiceListener; + public PgpImportExport(Context context, ProgressDialogUpdater progress) { super(); this.mContext = context; this.mProgress = progress; } + public PgpImportExport(Context context, + ProgressDialogUpdater progress, KeychainServiceListener keychainListener) { + super(); + this.mContext = context; + this.mProgress = progress; + this.mKeychainServiceListener = keychainListener; + } + public void updateProgress(int message, int current, int total) { if (mProgress != null) { mProgress.setProgress(message, current, total); @@ -85,8 +81,9 @@ public class PgpImportExport { public boolean uploadKeyRingToServer(HkpKeyServer server, PGPPublicKeyRing keyring) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ArmoredOutputStream aos = new ArmoredOutputStream(bos); + ArmoredOutputStream aos = null; try { + aos = new ArmoredOutputStream(bos); aos.write(keyring.getEncoded()); aos.close(); @@ -101,7 +98,8 @@ public class PgpImportExport { return false; } finally { try { - bos.close(); + if (aos != null) { aos.close(); } + if (bos != null) { bos.close(); } } catch (IOException e) { } } @@ -161,59 +159,68 @@ public class PgpImportExport { return returnData; } - public Bundle exportKeyRings(ArrayList<Long> keyRingMasterKeyIds, int keyType, - OutputStream outStream) throws PgpGeneralException, FileNotFoundException, + public Bundle exportKeyRings(ArrayList<Long> publicKeyRingMasterIds, ArrayList<Long> secretKeyRingMasterIds, + OutputStream outStream) throws PgpGeneralException, PGPException, IOException { Bundle returnData = new Bundle(); + int masterKeyIdsSize = publicKeyRingMasterIds.size() + secretKeyRingMasterIds.size(); + int progress = 0; + updateProgress( mContext.getResources().getQuantityString(R.plurals.progress_exporting_key, - keyRingMasterKeyIds.size()), 0, 100); + masterKeyIdsSize), 0, 100); if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { throw new PgpGeneralException( mContext.getString(R.string.error_external_storage_not_ready)); } + // For each public masterKey id + for (long pubKeyMasterId : publicKeyRingMasterIds) { + progress++; + // Create an output stream + ArmoredOutputStream arOutStream = new ArmoredOutputStream(outStream); + arOutStream.setHeader("Version", PgpHelper.getFullVersion(mContext)); + + updateProgress(progress * 100 / masterKeyIdsSize, 100); + PGPPublicKeyRing publicKeyRing = + ProviderHelper.getPGPPublicKeyRingByMasterKeyId(mContext, pubKeyMasterId); + + if (publicKeyRing != null) { + publicKeyRing.encode(arOutStream); + } - if (keyType == Id.type.secret_key) { - ArmoredOutputStream outSec = new ArmoredOutputStream(outStream); - outSec.setHeader("Version", PgpHelper.getFullVersion(mContext)); - - for (int i = 0; i < keyRingMasterKeyIds.size(); ++i) { - updateProgress(i * 100 / keyRingMasterKeyIds.size() / 2, 100); + if (mKeychainServiceListener.hasServiceStopped()) { + arOutStream.close(); + return null; + } - PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId( - mContext, keyRingMasterKeyIds.get(i)); + arOutStream.close(); + } - if (secretKeyRing != null) { - secretKeyRing.encode(outSec); - } - } - outSec.close(); - } else { - // export public keyrings... - ArmoredOutputStream outPub = new ArmoredOutputStream(outStream); - outPub.setHeader("Version", PgpHelper.getFullVersion(mContext)); - - for (int i = 0; i < keyRingMasterKeyIds.size(); ++i) { - // double the needed time if exporting both public and secret parts - if (keyType == Id.type.secret_key) { - updateProgress(i * 100 / keyRingMasterKeyIds.size() / 2, 100); - } else { - updateProgress(i * 100 / keyRingMasterKeyIds.size(), 100); - } + // For each secret masterKey id + for (long secretKeyMasterId : secretKeyRingMasterIds) { + progress++; + // Create an output stream + ArmoredOutputStream arOutStream = new ArmoredOutputStream(outStream); + arOutStream.setHeader("Version", PgpHelper.getFullVersion(mContext)); - PGPPublicKeyRing publicKeyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId( - mContext, keyRingMasterKeyIds.get(i)); + updateProgress(progress * 100 / masterKeyIdsSize, 100); + PGPSecretKeyRing secretKeyRing = + ProviderHelper.getPGPSecretKeyRingByMasterKeyId(mContext, secretKeyMasterId); - if (publicKeyRing != null) { - publicKeyRing.encode(outPub); - } + if (secretKeyRing != null) { + secretKeyRing.encode(arOutStream); + } + if (mKeychainServiceListener.hasServiceStopped()) { + arOutStream.close(); + return null; } - outPub.close(); + + arOutStream.close(); } - returnData.putInt(KeychainIntentService.RESULT_EXPORT, keyRingMasterKeyIds.size()); + returnData.putInt(KeychainIntentService.RESULT_EXPORT, masterKeyIdsSize); updateProgress(R.string.progress_done, 100, 100); @@ -234,7 +241,7 @@ public class PgpImportExport { for (PGPSecretKey testSecretKey : new IterableIterator<PGPSecretKey>( secretKeyRing.getSecretKeys())) { if (!testSecretKey.isMasterKey()) { - if (PgpKeyHelper.isSecretKeyPrivateEmpty(testSecretKey)) { + if (testSecretKey.isPrivateKeyEmpty()) { // this is bad, something is very wrong... save = false; status = Id.return_value.bad; @@ -255,8 +262,9 @@ public class PgpImportExport { } newPubRing = PGPPublicKeyRing.insertPublicKey(newPubRing, key); } - if (newPubRing != null) + if (newPubRing != null) { ProviderHelper.saveKeyRing(mContext, newPubRing); + } // TODO: remove status returns, use exceptions! status = Id.return_value.ok; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index c1c6f3088..b4bf0747f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -17,28 +17,27 @@ package org.sufficientlysecure.keychain.pgp; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.Locale; -import java.util.Vector; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import android.content.Context; +import android.graphics.Color; +import android.text.Spannable; +import android.text.SpannableStringBuilder; +import android.text.style.ForegroundColorSpan; import org.spongycastle.bcpg.sig.KeyFlags; -import org.spongycastle.openpgp.PGPPublicKey; -import org.spongycastle.openpgp.PGPPublicKeyRing; -import org.spongycastle.openpgp.PGPSecretKey; -import org.spongycastle.openpgp.PGPSecretKeyRing; -import org.spongycastle.openpgp.PGPSignature; -import org.spongycastle.openpgp.PGPSignatureSubpacketVector; +import org.spongycastle.openpgp.*; +import org.spongycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; -import android.content.Context; +import java.security.DigestException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class PgpKeyHelper { @@ -466,55 +465,30 @@ public class PgpKeyHelper { String algorithmStr; switch (algorithm) { - case PGPPublicKey.RSA_ENCRYPT: - case PGPPublicKey.RSA_GENERAL: - case PGPPublicKey.RSA_SIGN: { - algorithmStr = "RSA"; - break; - } - - case PGPPublicKey.DSA: { - algorithmStr = "DSA"; - break; - } - - case PGPPublicKey.ELGAMAL_ENCRYPT: - case PGPPublicKey.ELGAMAL_GENERAL: { - algorithmStr = "ElGamal"; - break; - } + case PGPPublicKey.RSA_ENCRYPT: + case PGPPublicKey.RSA_GENERAL: + case PGPPublicKey.RSA_SIGN: { + algorithmStr = "RSA"; + break; + } - default: { - algorithmStr = "Unknown"; - break; - } - } - return algorithmStr + ", " + keySize + " bit"; - } + case PGPPublicKey.DSA: { + algorithmStr = "DSA"; + break; + } - /** - * Converts fingerprint to hex with whitespaces after 4 characters - * - * @param fp - * @return - */ - public static String convertFingerprintToHex(byte[] fp, boolean chunked) { - String fingerPrint = ""; - for (int i = 0; i < fp.length; ++i) { - if (chunked && i != 0 && i % 10 == 0) { - fingerPrint += " "; - } else if (chunked && i != 0 && i % 2 == 0) { - fingerPrint += " "; + case PGPPublicKey.ELGAMAL_ENCRYPT: + case PGPPublicKey.ELGAMAL_GENERAL: { + algorithmStr = "ElGamal"; + break; } - String chunk = Integer.toHexString((fp[i] + 256) % 256).toUpperCase(Locale.US); - while (chunk.length() < 2) { - chunk = "0" + chunk; + + default: { + algorithmStr = "Unknown"; + break; } - fingerPrint += chunk; } - - return fingerPrint; - + return algorithmStr + ", " + keySize + " bit"; } public static String getFingerPrint(Context context, long keyId) { @@ -529,55 +503,150 @@ public class PgpKeyHelper { key = secretKey.getPublicKey(); } - return convertFingerprintToHex(key.getFingerprint(), true); - } - - public static boolean isSecretKeyPrivateEmpty(PGPSecretKey secretKey) { - return secretKey.isPrivateKeyEmpty(); + return convertFingerprintToHex(key.getFingerprint()); } -// public static boolean isSecretKeyPrivateEmpty(Context context, long keyId) { -// PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, keyId); -// if (secretKey == null) { -// Log.e(Constants.TAG, "Key could not be found!"); -// return false; // could be a public key, assume it is not empty -// } -// return isSecretKeyPrivateEmpty(secretKey); -// } + /** + * Converts fingerprint to hex (optional: with whitespaces after 4 characters) + * <p/> + * Fingerprint is shown using lowercase characters. Studies have shown that humans can + * better differentiate between numbers and letters when letters are lowercase. + * + * @param fingerprint + * @param split split into 4 character chunks + * @return + */ + public static String convertFingerprintToHex(byte[] fingerprint) { + String hexString = Hex.toHexString(fingerprint); - public static String convertKeyIdToHex(long keyId) { - String fingerPrint = Long.toHexString(keyId & 0xffffffffL).toUpperCase(Locale.US); - while (fingerPrint.length() < 8) { - fingerPrint = "0" + fingerPrint; - } - return fingerPrint; + return hexString; } /** - * TODO: documentation - * + * Convert key id from long to 64 bit hex string + * <p/> + * V4: "The Key ID is the low-order 64 bits of the fingerprint" + * <p/> + * see http://tools.ietf.org/html/rfc4880#section-12.2 + * * @param keyId * @return */ - public static String convertKeyToHex(long keyId) { - return convertKeyIdToHex(keyId >> 32) + convertKeyIdToHex(keyId); + public static String convertKeyIdToHex(long keyId) { + long upper = keyId >> 32; + if (upper == 0) { + // this is a short key id + return convertKeyIdToHexShort(keyId); + } + return "0x" + convertKeyIdToHex32bit(keyId >> 32) + convertKeyIdToHex32bit(keyId); } - public static long convertHexToKeyId(String data) { - int len = data.length(); - String s2 = data.substring(len - 8); - String s1 = data.substring(0, len - 8); - return (Long.parseLong(s1, 16) << 32) | Long.parseLong(s2, 16); + public static String convertKeyIdToHexShort(long keyId) { + return "0x" + convertKeyIdToHex32bit(keyId); + } + + private static String convertKeyIdToHex32bit(long keyId) { + String hexString = Long.toHexString(keyId & 0xffffffffL).toLowerCase(Locale.US); + while (hexString.length() < 8) { + hexString = "0" + hexString; + } + return hexString; + } + + + public static SpannableStringBuilder colorizeFingerprint(String fingerprint) { + // split by 4 characters + fingerprint = fingerprint.replaceAll("(.{4})(?!$)", "$1 "); + + // add line breaks to have a consistent "image" that can be recognized + char[] chars = fingerprint.toCharArray(); + chars[24] = '\n'; + fingerprint = String.valueOf(chars); + + SpannableStringBuilder sb = new SpannableStringBuilder(fingerprint); + try { + // for each 4 characters of the fingerprint + 1 space + for (int i = 0; i < fingerprint.length(); i += 5) { + int spanEnd = Math.min(i + 4, fingerprint.length()); + String fourChars = fingerprint.substring(i, spanEnd); + + int raw = Integer.parseInt(fourChars, 16); + byte[] bytes = {(byte) ((raw >> 8) & 0xff - 128), (byte) (raw & 0xff - 128)}; + int[] color = getRgbForData(bytes); + int r = color[0]; + int g = color[1]; + int b = color[2]; + + // we cannot change black by multiplication, so adjust it to an almost-black grey, + // which will then be brightened to the minimal brightness level + if (r == 0 && g == 0 && b == 0) { + r = 1; + g = 1; + b = 1; + } + + // Convert rgb to brightness + double brightness = 0.2126 * r + 0.7152 * g + 0.0722 * b; + + // If a color is too dark to be seen on black, + // then brighten it up to a minimal brightness. + if (brightness < 80) { + double factor = 80.0 / brightness; + r = Math.min(255, (int) (r * factor)); + g = Math.min(255, (int) (g * factor)); + b = Math.min(255, (int) (b * factor)); + + // If it is too light, then darken it to a respective maximal brightness. + } else if (brightness > 180) { + double factor = 180.0 / brightness; + r = (int) (r * factor); + g = (int) (g * factor); + b = (int) (b * factor); + } + + // Create a foreground color with the 3 digest integers as RGB + // and then converting that int to hex to use as a color + sb.setSpan(new ForegroundColorSpan(Color.rgb(r, g, b)), + i, spanEnd, Spannable.SPAN_INCLUSIVE_INCLUSIVE); + } + } catch (Exception e) { + Log.e(Constants.TAG, "Colorization failed", e); + // if anything goes wrong, then just display the fingerprint without colour, + // instead of partially correct colour or wrong colours + return new SpannableStringBuilder(fingerprint); + } + + return sb; + } + + /** + * Converts the given bytes to a unique RGB color using SHA1 algorithm + * + * @param bytes + * @return an integer array containing 3 numeric color representations (Red, Green, Black) + * @throws java.security.NoSuchAlgorithmException + * @throws java.security.DigestException + */ + private static int[] getRgbForData(byte[] bytes) throws NoSuchAlgorithmException, DigestException { + MessageDigest md = MessageDigest.getInstance("SHA1"); + + md.update(bytes); + byte[] digest = md.digest(); + + int[] result = {((int) digest[0] + 256) % 256, + ((int) digest[1] + 256) % 256, + ((int) digest[2] + 256) % 256}; + return result; } /** * Splits userId string into naming part, email part, and comment part - * + * * @param userId * @return array with naming (0), email (1), comment (2) */ public static String[] splitUserId(String userId) { - String[] result = new String[] { null, null, null }; + String[] result = new String[]{null, null, null}; if (userId == null || userId.equals("")) { return result; @@ -598,7 +667,6 @@ public class PgpKeyHelper { result[0] = matcher.group(1); result[1] = matcher.group(3); result[2] = matcher.group(2); - return result; } return result; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index b7f84ccdc..05ca99578 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -30,35 +30,19 @@ import java.util.Date; import java.util.GregorianCalendar; import java.util.Iterator; import java.util.TimeZone; - +import android.content.Context; import org.spongycastle.bcpg.CompressionAlgorithmTags; import org.spongycastle.bcpg.HashAlgorithmTags; import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags; import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.jce.spec.ElGamalParameterSpec; -import org.spongycastle.openpgp.PGPEncryptedData; -import org.spongycastle.openpgp.PGPException; -import org.spongycastle.openpgp.PGPKeyPair; -import org.spongycastle.openpgp.PGPKeyRingGenerator; -import org.spongycastle.openpgp.PGPPrivateKey; -import org.spongycastle.openpgp.PGPPublicKey; -import org.spongycastle.openpgp.PGPPublicKeyRing; -import org.spongycastle.openpgp.PGPSecretKey; -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.*; import org.spongycastle.openpgp.PGPUtil; 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.spongycastle.openpgp.operator.jcajce.*; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; @@ -70,20 +54,34 @@ import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; import android.content.Context; import android.util.Pair; +import org.sufficientlysecure.keychain.util.IterableIterator; +import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.Primes; +import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Iterator; +import java.util.List; +import java.util.TimeZone; public class PgpKeyOperation { private final Context mContext; private final ProgressDialogUpdater mProgress; - private static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[] { + private static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[]{ SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, SymmetricKeyAlgorithmTags.AES_128, SymmetricKeyAlgorithmTags.CAST5, - SymmetricKeyAlgorithmTags.TRIPLE_DES }; - private static final int[] PREFERRED_HASH_ALGORITHMS = new int[] { HashAlgorithmTags.SHA1, - HashAlgorithmTags.SHA256, HashAlgorithmTags.RIPEMD160 }; - private static final int[] PREFERRED_COMPRESSION_ALGORITHMS = new int[] { + SymmetricKeyAlgorithmTags.TRIPLE_DES}; + private static final int[] PREFERRED_HASH_ALGORITHMS = new int[]{HashAlgorithmTags.SHA1, + HashAlgorithmTags.SHA256, HashAlgorithmTags.RIPEMD160}; + private static final int[] PREFERRED_COMPRESSION_ALGORITHMS = new int[]{ CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.BZIP2, - CompressionAlgorithmTags.ZIP }; + CompressionAlgorithmTags.ZIP}; public PgpKeyOperation(Context context, ProgressDialogUpdater progress) { super(); @@ -104,8 +102,9 @@ public class PgpKeyOperation { } public PGPSecretKey createKey(int algorithmChoice, int keySize, String passphrase, - boolean isMasterKey) throws NoSuchAlgorithmException, PGPException, NoSuchProviderException, - PgpGeneralException, InvalidAlgorithmParameterException { + boolean isMasterKey) + throws NoSuchAlgorithmException, PGPException, NoSuchProviderException, + PgpGeneralException, InvalidAlgorithmParameterException { if (keySize < 512) { throw new PgpGeneralException(mContext.getString(R.string.error_key_size_minimum512bit)); @@ -119,41 +118,41 @@ public class PgpKeyOperation { KeyPairGenerator keyGen; switch (algorithmChoice) { - case Id.choice.algorithm.dsa: { - keyGen = KeyPairGenerator.getInstance("DSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME); - keyGen.initialize(keySize, new SecureRandom()); - algorithm = PGPPublicKey.DSA; - break; - } - - case Id.choice.algorithm.elgamal: { - if (isMasterKey) { - throw new PgpGeneralException( - mContext.getString(R.string.error_master_key_must_not_be_el_gamal)); + case Id.choice.algorithm.dsa: { + keyGen = KeyPairGenerator.getInstance("DSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME); + keyGen.initialize(keySize, new SecureRandom()); + algorithm = PGPPublicKey.DSA; + break; } - keyGen = KeyPairGenerator.getInstance("ElGamal", Constants.BOUNCY_CASTLE_PROVIDER_NAME); - BigInteger p = Primes.getBestPrime(keySize); - BigInteger g = new BigInteger("2"); - ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); + case Id.choice.algorithm.elgamal: { + if (isMasterKey) { + throw new PgpGeneralException( + mContext.getString(R.string.error_master_key_must_not_be_el_gamal)); + } + keyGen = KeyPairGenerator.getInstance("ElGamal", Constants.BOUNCY_CASTLE_PROVIDER_NAME); + BigInteger p = Primes.getBestPrime(keySize); + BigInteger g = new BigInteger("2"); - keyGen.initialize(elParams); - algorithm = PGPPublicKey.ELGAMAL_ENCRYPT; - break; - } + ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); - case Id.choice.algorithm.rsa: { - keyGen = KeyPairGenerator.getInstance("RSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME); - keyGen.initialize(keySize, new SecureRandom()); + keyGen.initialize(elParams); + algorithm = PGPPublicKey.ELGAMAL_ENCRYPT; + break; + } - algorithm = PGPPublicKey.RSA_GENERAL; - break; - } + case Id.choice.algorithm.rsa: { + keyGen = KeyPairGenerator.getInstance("RSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME); + keyGen.initialize(keySize, new SecureRandom()); - default: { - throw new PgpGeneralException( - mContext.getString(R.string.error_unknown_algorithm_choice)); - } + algorithm = PGPPublicKey.RSA_GENERAL; + break; + } + + default: { + throw new PgpGeneralException( + mContext.getString(R.string.error_unknown_algorithm_choice)); + } } // build new key pair @@ -170,11 +169,10 @@ public class PgpKeyOperation { return new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(), sha1Calc, isMasterKey, keyEncryptor); - } public void changeSecretKeyPassphrase(PGPSecretKeyRing keyRing, String oldPassPhrase, - String newPassPhrase) throws IOException, PGPException { + String newPassPhrase) throws IOException, PGPException { updateProgress(R.string.progress_building_key, 0, 100); if (oldPassPhrase == null) { @@ -221,15 +219,15 @@ public class PgpKeyOperation { updateProgress(R.string.progress_certifying_master_key, 20, 100); int user_id_index = 0; for (String userId : userIds) { - PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( - masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1) - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); + PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( + masterPublicKey.getAlgorithm(), HashAlgorithmTags.SHA1) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); - sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey); + sGen.init(PGPSignature.POSITIVE_CERTIFICATION, masterPrivateKey); - PGPSignature certification = sGen.generateCertification(userId, masterPublicKey); - masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification); + PGPSignature certification = sGen.generateCertification(userId, masterPublicKey); + masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, userId, certification); user_id_index++; } @@ -280,7 +278,7 @@ public class PgpKeyOperation { updateProgress(R.string.progress_adding_sub_keys, 40, 100); for (int i = 1; i < keys.size(); ++i) { - updateProgress(40 + 50 * (i - 1) / (keys.size() - 1), 100); + updateProgress(40 + 40 * (i - 1) / (keys.size() - 1), 100); PGPSecretKey subKey = keys.get(i); PGPPublicKey subPublicKey = subKey.getPublicKey(); @@ -345,7 +343,7 @@ public class PgpKeyOperation { updateProgress(R.string.progress_done, 100, 100); } - public void buildSecretKey(SaveKeyringParcel saveParcel) throws PgpGeneralException, + public void buildSecretKey (SaveKeyringParcel saveParcel)throws PgpGeneralException, PGPException, SignatureException, IOException { updateProgress(R.string.progress_building_key, 0, 100); @@ -387,7 +385,7 @@ public class PgpKeyOperation { Todo identify more things which need to be preserved - e.g. trust levels? user attributes - */ + */ if (saveParcel.deletedKeys != null) { for (PGPSecretKey dKey : saveParcel.deletedKeys) { @@ -546,7 +544,7 @@ public class PgpKeyOperation { unhashedPacketsGen.generate(), certificationSignerBuilder, keyEncryptor); for (int i = 1; i < saveParcel.keys.size(); ++i) { - updateProgress(40 + 50 * i/ saveParcel.keys.size(), 100); + updateProgress(40 + 50 * i / saveParcel.keys.size(), 100); if (saveParcel.moddedKeys[i]) { PGPSecretKey subKey = saveParcel.keys.get(i); PGPPublicKey subPublicKey = subKey.getPublicKey(); @@ -558,8 +556,8 @@ public class PgpKeyOperation { "".toCharArray()); } else { keyDecryptor2 = new JcePBESecretKeyDecryptorBuilder() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - saveParcel.oldPassPhrase.toCharArray()); + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( + saveParcel.oldPassPhrase.toCharArray()); } PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(keyDecryptor2); PGPKeyPair subKeyPair = new PGPKeyPair(subPublicKey, subPrivateKey); @@ -642,50 +640,80 @@ public class PgpKeyOperation { mKR = PGPSecretKeyRing.copyWithNewPassword(mKR, keyDecryptor, keyEncryptorNew); updateProgress(R.string.progress_saving_key_ring, 90, 100); + /* additional handy debug info + + Log.d(Constants.TAG, " ------- in private key -------"); + + for(String uid : new IterableIterator<String>(secretKeyRing.getPublicKey().getUserIDs())) { + for(PGPSignature sig : new IterableIterator<PGPSignature>(secretKeyRing.getPublicKey().getSignaturesForID(uid))) { + Log.d(Constants.TAG, "sig: " + PgpKeyHelper.convertKeyIdToHex(sig.getKeyID()) + " for " + uid); + } + + } + + Log.d(Constants.TAG, " ------- in public key -------"); + + for(String uid : new IterableIterator<String>(publicKeyRing.getPublicKey().getUserIDs())) { + for(PGPSignature sig : new IterableIterator<PGPSignature>(publicKeyRing.getPublicKey().getSignaturesForID(uid))) { + Log.d(Constants.TAG, "sig: " + PgpKeyHelper.convertKeyIdToHex(sig.getKeyID()) + " for " + uid); + } + } + + */ + + ProviderHelper.saveKeyRing(mContext, mKR); ProviderHelper.saveKeyRing(mContext, pKR); updateProgress(R.string.progress_done, 100, 100); } - public PGPPublicKeyRing certifyKey(long masterKeyId, long pubKeyId, String passphrase) - throws PgpGeneralException, PGPException, SignatureException { + public PGPPublicKeyRing certifyKey(long masterKeyId, long pubKeyId, List<String> userIds, String passphrase) + throws PgpGeneralException, NoSuchAlgorithmException, NoSuchProviderException, + PGPException, SignatureException { if (passphrase == null) { throw new PgpGeneralException("Unable to obtain passphrase"); } else { - PGPPublicKeyRing pubring = ProviderHelper - .getPGPPublicKeyRingByKeyId(mContext, pubKeyId); - PGPSecretKey certificationKey = PgpKeyHelper.getCertificationKey(mContext, masterKeyId); - if (certificationKey == null) { - throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed)); - } + // create a signatureGenerator from the supplied masterKeyId and passphrase + PGPSignatureGenerator signatureGenerator; { - PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( - Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray()); - PGPPrivateKey signaturePrivateKey = certificationKey.extractPrivateKey(keyDecryptor); - if (signaturePrivateKey == null) { - throw new PgpGeneralException( - mContext.getString(R.string.error_could_not_extract_private_key)); - } - - // TODO: SHA256 fixed? - JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder( - certificationKey.getPublicKey().getAlgorithm(), PGPUtil.SHA256) - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + PGPSecretKey certificationKey = PgpKeyHelper.getCertificationKey(mContext, masterKeyId); + if (certificationKey == null) { + throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed)); + } - PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator( - contentSignerBuilder); + PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( + Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray()); + PGPPrivateKey signaturePrivateKey = certificationKey.extractPrivateKey(keyDecryptor); + if (signaturePrivateKey == null) { + throw new PgpGeneralException( + mContext.getString(R.string.error_could_not_extract_private_key)); + } - signatureGenerator.init(PGPSignature.DIRECT_KEY, signaturePrivateKey); + // TODO: SHA256 fixed? + JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder( + certificationKey.getPublicKey().getAlgorithm(), PGPUtil.SHA256) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); + signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder); + signatureGenerator.init(PGPSignature.DEFAULT_CERTIFICATION, signaturePrivateKey); + } - PGPSignatureSubpacketVector packetVector = spGen.generate(); - signatureGenerator.setHashedSubpackets(packetVector); + { // supply signatureGenerator with a SubpacketVector + PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); + PGPSignatureSubpacketVector packetVector = spGen.generate(); + signatureGenerator.setHashedSubpackets(packetVector); + } - PGPPublicKey signedKey = PGPPublicKey.addCertification(pubring.getPublicKey(pubKeyId), - signatureGenerator.generate()); + // fetch public key ring, add the certification and return it + PGPPublicKeyRing pubring = ProviderHelper + .getPGPPublicKeyRingByKeyId(mContext, pubKeyId); + PGPPublicKey signedKey = pubring.getPublicKey(pubKeyId); + for(String userId : new IterableIterator<String>(userIds.iterator())) { + PGPSignature sig = signatureGenerator.generateCertification(userId, signedKey); + signedKey = PGPPublicKey.addCertification(signedKey, userId, sig); + } pubring = PGPPublicKeyRing.insertPublicKey(pubring, signedKey); return pubring; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java index ba1182c1b..737e9c75d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java @@ -18,28 +18,11 @@ package org.sufficientlysecure.keychain.pgp; import android.content.Context; - import org.spongycastle.bcpg.ArmoredOutputStream; import org.spongycastle.bcpg.BCPGOutputStream; -import org.spongycastle.openpgp.PGPCompressedDataGenerator; -import org.spongycastle.openpgp.PGPEncryptedDataGenerator; -import org.spongycastle.openpgp.PGPException; -import org.spongycastle.openpgp.PGPLiteralData; -import org.spongycastle.openpgp.PGPLiteralDataGenerator; -import org.spongycastle.openpgp.PGPPrivateKey; -import org.spongycastle.openpgp.PGPPublicKey; -import org.spongycastle.openpgp.PGPSecretKey; -import org.spongycastle.openpgp.PGPSecretKeyRing; -import org.spongycastle.openpgp.PGPSignature; -import org.spongycastle.openpgp.PGPSignatureGenerator; -import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator; -import org.spongycastle.openpgp.PGPV3SignatureGenerator; +import org.spongycastle.openpgp.*; import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; -import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; -import org.spongycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator; -import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; -import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; -import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator; +import org.spongycastle.openpgp.operator.jcajce.*; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; @@ -49,11 +32,7 @@ import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; +import java.io.*; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SignatureException; @@ -63,110 +42,110 @@ import java.util.Date; * This class uses a Builder pattern! */ public class PgpSignEncrypt { - private Context context; - private InputData data; - private OutputStream outStream; - - private ProgressDialogUpdater progress; - private boolean enableAsciiArmorOutput; - private int compressionId; - private long[] encryptionKeyIds; - private String encryptionPassphrase; - private int symmetricEncryptionAlgorithm; - private long signatureKeyId; - private int signatureHashAlgorithm; - private boolean signatureForceV3; - private String signaturePassphrase; + private Context mContext; + private InputData mData; + private OutputStream mOutStream; + + private ProgressDialogUpdater mProgress; + private boolean mEnableAsciiArmorOutput; + private int mCompressionId; + private long[] mEncryptionKeyIds; + private String mEncryptionPassphrase; + private int mSymmetricEncryptionAlgorithm; + private long mSignatureKeyId; + private int mSignatureHashAlgorithm; + private boolean mSignatureForceV3; + private String mSignaturePassphrase; private PgpSignEncrypt(Builder builder) { // private Constructor can only be called from Builder - this.context = builder.context; - this.data = builder.data; - this.outStream = builder.outStream; - - this.progress = builder.progress; - this.enableAsciiArmorOutput = builder.enableAsciiArmorOutput; - this.compressionId = builder.compressionId; - this.encryptionKeyIds = builder.encryptionKeyIds; - this.encryptionPassphrase = builder.encryptionPassphrase; - this.symmetricEncryptionAlgorithm = builder.symmetricEncryptionAlgorithm; - this.signatureKeyId = builder.signatureKeyId; - this.signatureHashAlgorithm = builder.signatureHashAlgorithm; - this.signatureForceV3 = builder.signatureForceV3; - this.signaturePassphrase = builder.signaturePassphrase; + this.mContext = builder.mContext; + this.mData = builder.mData; + this.mOutStream = builder.mOutStream; + + this.mProgress = builder.mProgress; + this.mEnableAsciiArmorOutput = builder.mEnableAsciiArmorOutput; + this.mCompressionId = builder.mCompressionId; + this.mEncryptionKeyIds = builder.mEncryptionKeyIds; + this.mEncryptionPassphrase = builder.mEncryptionPassphrase; + this.mSymmetricEncryptionAlgorithm = builder.mSymmetricEncryptionAlgorithm; + this.mSignatureKeyId = builder.mSignatureKeyId; + this.mSignatureHashAlgorithm = builder.mSignatureHashAlgorithm; + this.mSignatureForceV3 = builder.mSignatureForceV3; + this.mSignaturePassphrase = builder.mSignaturePassphrase; } public static class Builder { // mandatory parameter - private Context context; - private InputData data; - private OutputStream outStream; + private Context mContext; + private InputData mData; + private OutputStream mOutStream; // optional - private ProgressDialogUpdater progress = null; - private boolean enableAsciiArmorOutput = false; - private int compressionId = Id.choice.compression.none; - private long[] encryptionKeyIds = new long[0]; - private String encryptionPassphrase = null; - private int symmetricEncryptionAlgorithm = 0; - private long signatureKeyId = Id.key.none; - private int signatureHashAlgorithm = 0; - private boolean signatureForceV3 = false; - private String signaturePassphrase = null; + private ProgressDialogUpdater mProgress = null; + private boolean mEnableAsciiArmorOutput = false; + private int mCompressionId = Id.choice.compression.none; + private long[] mEncryptionKeyIds = new long[0]; + private String mEncryptionPassphrase = null; + private int mSymmetricEncryptionAlgorithm = 0; + private long mSignatureKeyId = Id.key.none; + private int mSignatureHashAlgorithm = 0; + private boolean mSignatureForceV3 = false; + private String mSignaturePassphrase = null; public Builder(Context context, InputData data, OutputStream outStream) { - this.context = context; - this.data = data; - this.outStream = outStream; + this.mContext = context; + this.mData = data; + this.mOutStream = outStream; } public Builder progress(ProgressDialogUpdater progress) { - this.progress = progress; + this.mProgress = progress; return this; } public Builder enableAsciiArmorOutput(boolean enableAsciiArmorOutput) { - this.enableAsciiArmorOutput = enableAsciiArmorOutput; + this.mEnableAsciiArmorOutput = enableAsciiArmorOutput; return this; } public Builder compressionId(int compressionId) { - this.compressionId = compressionId; + this.mCompressionId = compressionId; return this; } public Builder encryptionKeyIds(long[] encryptionKeyIds) { - this.encryptionKeyIds = encryptionKeyIds; + this.mEncryptionKeyIds = encryptionKeyIds; return this; } public Builder encryptionPassphrase(String encryptionPassphrase) { - this.encryptionPassphrase = encryptionPassphrase; + this.mEncryptionPassphrase = encryptionPassphrase; return this; } public Builder symmetricEncryptionAlgorithm(int symmetricEncryptionAlgorithm) { - this.symmetricEncryptionAlgorithm = symmetricEncryptionAlgorithm; + this.mSymmetricEncryptionAlgorithm = symmetricEncryptionAlgorithm; return this; } public Builder signatureKeyId(long signatureKeyId) { - this.signatureKeyId = signatureKeyId; + this.mSignatureKeyId = signatureKeyId; return this; } public Builder signatureHashAlgorithm(int signatureHashAlgorithm) { - this.signatureHashAlgorithm = signatureHashAlgorithm; + this.mSignatureHashAlgorithm = signatureHashAlgorithm; return this; } public Builder signatureForceV3(boolean signatureForceV3) { - this.signatureForceV3 = signatureForceV3; + this.mSignatureForceV3 = signatureForceV3; return this; } public Builder signaturePassphrase(String signaturePassphrase) { - this.signaturePassphrase = signaturePassphrase; + this.mSignaturePassphrase = signaturePassphrase; return this; } @@ -176,14 +155,14 @@ public class PgpSignEncrypt { } public void updateProgress(int message, int current, int total) { - if (progress != null) { - progress.setProgress(message, current, total); + if (mProgress != null) { + mProgress.setProgress(message, current, total); } } public void updateProgress(int current, int total) { - if (progress != null) { - progress.setProgress(current, total); + if (mProgress != null) { + mProgress.setProgress(current, total); } } @@ -201,17 +180,17 @@ public class PgpSignEncrypt { throws IOException, PgpGeneralException, PGPException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException { - boolean enableSignature = signatureKeyId != Id.key.none; - boolean enableEncryption = (encryptionKeyIds.length != 0 || encryptionPassphrase != null); - boolean enableCompression = (enableEncryption && compressionId != Id.choice.compression.none); + boolean enableSignature = mSignatureKeyId != Id.key.none; + boolean enableEncryption = (mEncryptionKeyIds.length != 0 || mEncryptionPassphrase != null); + boolean enableCompression = (enableEncryption && mCompressionId != Id.choice.compression.none); Log.d(Constants.TAG, "enableSignature:" + enableSignature + "\nenableEncryption:" + enableEncryption + "\nenableCompression:" + enableCompression - + "\nenableAsciiArmorOutput:" + enableAsciiArmorOutput); + + "\nenableAsciiArmorOutput:" + mEnableAsciiArmorOutput); int signatureType; - if (enableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) { + if (mEnableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) { // for sign-only ascii text signatureType = PGPSignature.CANONICAL_TEXT_DOCUMENT; } else { @@ -220,12 +199,12 @@ public class PgpSignEncrypt { ArmoredOutputStream armorOut = null; OutputStream out; - if (enableAsciiArmorOutput) { - armorOut = new ArmoredOutputStream(outStream); - armorOut.setHeader("Version", PgpHelper.getFullVersion(context)); + if (mEnableAsciiArmorOutput) { + armorOut = new ArmoredOutputStream(mOutStream); + armorOut.setHeader("Version", PgpHelper.getFullVersion(mContext)); out = armorOut; } else { - out = outStream; + out = mOutStream; } /* Get keys for signature generation for later usage */ @@ -233,25 +212,25 @@ public class PgpSignEncrypt { PGPSecretKeyRing signingKeyRing = null; PGPPrivateKey signaturePrivateKey = null; if (enableSignature) { - signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(context, signatureKeyId); - signingKey = PgpKeyHelper.getSigningKey(context, signatureKeyId); + signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, mSignatureKeyId); + signingKey = PgpKeyHelper.getSigningKey(mContext, mSignatureKeyId); if (signingKey == null) { - throw new PgpGeneralException(context.getString(R.string.error_signature_failed)); + throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed)); } - if (signaturePassphrase == null) { + if (mSignaturePassphrase == null) { throw new PgpGeneralException( - context.getString(R.string.error_no_signature_passphrase)); + mContext.getString(R.string.error_no_signature_passphrase)); } updateProgress(R.string.progress_extracting_signature_key, 0, 100); PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( - Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassphrase.toCharArray()); + Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(mSignaturePassphrase.toCharArray()); signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor); if (signaturePrivateKey == null) { throw new PgpGeneralException( - context.getString(R.string.error_could_not_extract_private_key)); + mContext.getString(R.string.error_could_not_extract_private_key)); } } updateProgress(R.string.progress_preparing_streams, 5, 100); @@ -261,23 +240,23 @@ public class PgpSignEncrypt { if (enableEncryption) { // has Integrity packet enabled! JcePGPDataEncryptorBuilder encryptorBuilder = - new JcePGPDataEncryptorBuilder(symmetricEncryptionAlgorithm) + new JcePGPDataEncryptorBuilder(mSymmetricEncryptionAlgorithm) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME) .setWithIntegrityPacket(true); cPk = new PGPEncryptedDataGenerator(encryptorBuilder); - if (encryptionKeyIds.length == 0) { + if (mEncryptionKeyIds.length == 0) { // Symmetric encryption Log.d(Constants.TAG, "encryptionKeyIds length is 0 -> symmetric encryption"); JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator = - new JcePBEKeyEncryptionMethodGenerator(encryptionPassphrase.toCharArray()); + new JcePBEKeyEncryptionMethodGenerator(mEncryptionPassphrase.toCharArray()); cPk.addMethod(symmetricEncryptionGenerator); } else { // Asymmetric encryption - for (long id : encryptionKeyIds) { - PGPPublicKey key = PgpKeyHelper.getEncryptPublicKey(context, id); + for (long id : mEncryptionKeyIds) { + PGPPublicKey key = PgpKeyHelper.getEncryptPublicKey(mContext, id); if (key != null) { JcePublicKeyKeyEncryptionMethodGenerator pubKeyEncryptionGenerator = new JcePublicKeyKeyEncryptionMethodGenerator(key); @@ -295,10 +274,10 @@ public class PgpSignEncrypt { // content signer based on signing key algorithm and chosen hash algorithm JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder( - signingKey.getPublicKey().getAlgorithm(), signatureHashAlgorithm) + signingKey.getPublicKey().getAlgorithm(), mSignatureHashAlgorithm) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - if (signatureForceV3) { + if (mSignatureForceV3) { signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder); signatureV3Generator.init(signatureType, signaturePrivateKey); } else { @@ -322,14 +301,14 @@ public class PgpSignEncrypt { encryptionOut = cPk.open(out, new byte[1 << 16]); if (enableCompression) { - compressGen = new PGPCompressedDataGenerator(compressionId); + compressGen = new PGPCompressedDataGenerator(mCompressionId); bcpgOut = new BCPGOutputStream(compressGen.open(encryptionOut)); } else { bcpgOut = new BCPGOutputStream(encryptionOut); } if (enableSignature) { - if (signatureForceV3) { + if (mSignatureForceV3) { signatureV3Generator.generateOnePassVersion(false).encode(bcpgOut); } else { signatureGenerator.generateOnePassVersion(false).encode(bcpgOut); @@ -345,13 +324,13 @@ public class PgpSignEncrypt { long progress = 0; int n; byte[] buffer = new byte[1 << 16]; - InputStream in = data.getInputStream(); + InputStream in = mData.getInputStream(); while ((n = in.read(buffer)) > 0) { pOut.write(buffer, 0, n); // update signature buffer if signature is requested if (enableSignature) { - if (signatureForceV3) { + if (mSignatureForceV3) { signatureV3Generator.update(buffer, 0, n); } else { signatureGenerator.update(buffer, 0, n); @@ -359,26 +338,26 @@ public class PgpSignEncrypt { } progress += n; - if (data.getSize() != 0) { - updateProgress((int) (20 + (95 - 20) * progress / data.getSize()), 100); + if (mData.getSize() != 0) { + updateProgress((int) (20 + (95 - 20) * progress / mData.getSize()), 100); } } literalGen.close(); - } else if (enableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) { + } else if (mEnableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) { /* sign-only of ascii text */ updateProgress(R.string.progress_signing, 40, 100); // write directly on armor output stream - armorOut.beginClearText(signatureHashAlgorithm); + armorOut.beginClearText(mSignatureHashAlgorithm); - InputStream in = data.getInputStream(); + InputStream in = mData.getInputStream(); final BufferedReader reader = new BufferedReader(new InputStreamReader(in)); final byte[] newline = "\r\n".getBytes("UTF-8"); - if (signatureForceV3) { + if (mSignatureForceV3) { processLine(reader.readLine(), armorOut, signatureV3Generator); } else { processLine(reader.readLine(), armorOut, signatureGenerator); @@ -395,7 +374,7 @@ public class PgpSignEncrypt { armorOut.write(newline); // update signature buffer with input line - if (signatureForceV3) { + if (mSignatureForceV3) { signatureV3Generator.update(newline); processLine(line, armorOut, signatureV3Generator); } else { @@ -415,7 +394,7 @@ public class PgpSignEncrypt { if (enableSignature) { updateProgress(R.string.progress_generating_signature, 95, 100); - if (signatureForceV3) { + if (mSignatureForceV3) { signatureV3Generator.generate().encode(pOut); } else { signatureGenerator.generate().encode(pOut); @@ -432,12 +411,12 @@ public class PgpSignEncrypt { encryptionOut.close(); } - if (enableAsciiArmorOutput) { + if (mEnableAsciiArmorOutput) { armorOut.close(); } out.close(); - outStream.close(); + mOutStream.close(); updateProgress(R.string.progress_done, 100, 100); } @@ -449,35 +428,36 @@ public class PgpSignEncrypt { SignatureException { OutputStream out; - if (enableAsciiArmorOutput) { + if (mEnableAsciiArmorOutput) { // Ascii Armor (Radix-64) - ArmoredOutputStream armorOut = new ArmoredOutputStream(outStream); - armorOut.setHeader("Version", PgpHelper.getFullVersion(context)); + ArmoredOutputStream armorOut = new ArmoredOutputStream(mOutStream); + armorOut.setHeader("Version", PgpHelper.getFullVersion(mContext)); out = armorOut; } else { - out = outStream; + out = mOutStream; } - if (signatureKeyId == 0) { - throw new PgpGeneralException(context.getString(R.string.error_no_signature_key)); + if (mSignatureKeyId == 0) { + throw new PgpGeneralException(mContext.getString(R.string.error_no_signature_key)); } - PGPSecretKeyRing signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(context, signatureKeyId); - PGPSecretKey signingKey = PgpKeyHelper.getSigningKey(context, signatureKeyId); + PGPSecretKeyRing signingKeyRing = + ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, mSignatureKeyId); + PGPSecretKey signingKey = PgpKeyHelper.getSigningKey(mContext, mSignatureKeyId); if (signingKey == null) { - throw new PgpGeneralException(context.getString(R.string.error_signature_failed)); + throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed)); } - if (signaturePassphrase == null) { - throw new PgpGeneralException(context.getString(R.string.error_no_signature_passphrase)); + if (mSignaturePassphrase == null) { + throw new PgpGeneralException(mContext.getString(R.string.error_no_signature_passphrase)); } PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( - Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassphrase.toCharArray()); + Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(mSignaturePassphrase.toCharArray()); PGPPrivateKey signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor); if (signaturePrivateKey == null) { throw new PgpGeneralException( - context.getString(R.string.error_could_not_extract_private_key)); + mContext.getString(R.string.error_could_not_extract_private_key)); } updateProgress(R.string.progress_preparing_streams, 0, 100); @@ -490,12 +470,12 @@ public class PgpSignEncrypt { // content signer based on signing key algorithm and chosen hash algorithm JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(signingKey - .getPublicKey().getAlgorithm(), signatureHashAlgorithm) + .getPublicKey().getAlgorithm(), mSignatureHashAlgorithm) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); PGPSignatureGenerator signatureGenerator = null; PGPV3SignatureGenerator signatureV3Generator = null; - if (signatureForceV3) { + if (mSignatureForceV3) { signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder); signatureV3Generator.init(type, signaturePrivateKey); } else { @@ -510,7 +490,7 @@ public class PgpSignEncrypt { updateProgress(R.string.progress_signing, 40, 100); - InputStream inStream = data.getInputStream(); + InputStream inStream = mData.getInputStream(); // if (binary) { // byte[] buffer = new byte[1 << 16]; // int n = 0; @@ -527,7 +507,7 @@ public class PgpSignEncrypt { String line; while ((line = reader.readLine()) != null) { - if (signatureForceV3) { + if (mSignatureForceV3) { processLine(line, null, signatureV3Generator); signatureV3Generator.update(newline); } else { @@ -538,13 +518,13 @@ public class PgpSignEncrypt { // } BCPGOutputStream bOut = new BCPGOutputStream(out); - if (signatureForceV3) { + if (mSignatureForceV3) { signatureV3Generator.generate().encode(bOut); } else { signatureGenerator.generate().encode(bOut); } out.close(); - outStream.close(); + mOutStream.close(); updateProgress(R.string.progress_done, 100, 100); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpToX509.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpToX509.java index e18eb0d6d..54601173d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpToX509.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpToX509.java @@ -1,33 +1,24 @@ -package org.sufficientlysecure.keychain.pgp; - -import java.io.IOException; -import java.math.BigInteger; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.SignatureException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.text.DateFormat; -import java.util.Date; -import java.util.Iterator; -import java.util.Vector; +/* + * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de> + * Copyright (C) 2010 Thialfihar <thi@thialfihar.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.callback.UnsupportedCallbackException; +package org.sufficientlysecure.keychain.pgp; import org.spongycastle.asn1.DERObjectIdentifier; -import org.spongycastle.asn1.x509.AuthorityKeyIdentifier; -import org.spongycastle.asn1.x509.BasicConstraints; -import org.spongycastle.asn1.x509.GeneralName; -import org.spongycastle.asn1.x509.GeneralNames; -import org.spongycastle.asn1.x509.SubjectKeyIdentifier; -import org.spongycastle.asn1.x509.X509Extensions; -import org.spongycastle.asn1.x509.X509Name; +import org.spongycastle.asn1.x509.*; import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPPrivateKey; import org.spongycastle.openpgp.PGPPublicKey; @@ -38,30 +29,38 @@ import org.spongycastle.x509.extension.SubjectKeyIdentifierStructure; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.util.Log; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import java.io.IOException; +import java.math.BigInteger; +import java.security.*; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.text.DateFormat; +import java.util.Date; +import java.util.Iterator; +import java.util.Vector; + public class PgpToX509 { - public final static String DN_COMMON_PART_O = "OpenPGP to X.509 Bridge"; - public final static String DN_COMMON_PART_OU = "OpenPGP Keychain cert"; + public static final String DN_COMMON_PART_O = "OpenPGP to X.509 Bridge"; + public static final String DN_COMMON_PART_OU = "OpenPGP Keychain cert"; /** * Creates a self-signed certificate from a public and private key. The (critical) key-usage * extension is set up with: digital signature, non-repudiation, key-encipherment, key-agreement * and certificate-signing. The (non-critical) Netscape extension is set up with: SSL client and * S/MIME. A URI subjectAltName may also be set up. - * - * @param pubKey - * public key - * @param privKey - * private key - * @param subject - * subject (and issuer) DN for this certificate, RFC 2253 format preferred. - * @param startDate - * date from which the certificate will be valid (defaults to current date and time - * if null) - * @param endDate - * date until which the certificate will be valid (defaults to current date and time - * if null) * - * @param subjAltNameURI - * URI to be placed in subjectAltName + * + * @param pubKey public key + * @param privKey private key + * @param subject subject (and issuer) DN for this certificate, RFC 2253 format preferred. + * @param startDate date from which the certificate will be valid (defaults to current date and time + * if null) + * @param endDate date until which the certificate will be valid (defaults to current date and time + * if null) * + * @param subjAltNameURI URI to be placed in subjectAltName * @return self-signed certificate * @throws InvalidKeyException * @throws SignatureException @@ -70,11 +69,10 @@ public class PgpToX509 { * @throws NoSuchProviderException * @throws CertificateException * @throws Exception - * * @author Bruno Harbulot */ public static X509Certificate createSelfSignedCert(PublicKey pubKey, PrivateKey privKey, - X509Name subject, Date startDate, Date endDate, String subjAltNameURI) + X509Name subject, Date startDate, Date endDate, String subjAltNameURI) throws InvalidKeyException, IllegalStateException, NoSuchAlgorithmException, SignatureException, CertificateException, NoSuchProviderException { @@ -171,15 +169,12 @@ public class PgpToX509 { /** * Creates a self-signed certificate from a PGP Secret Key. - * - * @param pgpSecKey - * PGP Secret Key (from which one can extract the public and private keys and other - * attributes). - * @param pgpPrivKey - * PGP Private Key corresponding to the Secret Key (password callbacks should be done - * before calling this method) - * @param subjAltNameURI - * optional URI to embed in the subject alternative-name + * + * @param pgpSecKey PGP Secret Key (from which one can extract the public and private keys and other + * attributes). + * @param pgpPrivKey PGP Private Key corresponding to the Secret Key (password callbacks should be done + * before calling this method) + * @param subjAltNameURI optional URI to embed in the subject alternative-name * @return self-signed certificate * @throws PGPException * @throws NoSuchProviderException @@ -187,11 +182,10 @@ public class PgpToX509 { * @throws NoSuchAlgorithmException * @throws SignatureException * @throws CertificateException - * * @author Bruno Harbulot */ public static X509Certificate createSelfSignedCert(PGPSecretKey pgpSecKey, - PGPPrivateKey pgpPrivKey, String subjAltNameURI) throws PGPException, + PGPPrivateKey pgpPrivKey, String subjAltNameURI) throws PGPException, NoSuchProviderException, InvalidKeyException, NoSuchAlgorithmException, SignatureException, CertificateException { // get public key from secret key @@ -213,7 +207,7 @@ public class PgpToX509 { x509NameValues.add(DN_COMMON_PART_OU); for (@SuppressWarnings("unchecked") - Iterator<Object> it = (Iterator<Object>) pgpSecKey.getUserIDs(); it.hasNext();) { + Iterator<Object> it = (Iterator<Object>) pgpSecKey.getUserIDs(); it.hasNext(); ) { Object attrib = it.next(); x509NameOids.add(X509Name.CN); x509NameValues.add("CryptoCall"); @@ -225,7 +219,7 @@ public class PgpToX509 { */ Log.d(Constants.TAG, "User attributes: "); for (@SuppressWarnings("unchecked") - Iterator<Object> it = (Iterator<Object>) pgpSecKey.getUserAttributes(); it.hasNext();) { + Iterator<Object> it = (Iterator<Object>) pgpSecKey.getUserAttributes(); it.hasNext(); ) { Object attrib = it.next(); Log.d(Constants.TAG, " - " + attrib + " -- " + attrib.getClass()); } @@ -261,14 +255,13 @@ public class PgpToX509 { * This is a password callback handler that will fill in a password automatically. Useful to * configure passwords in advance, but should be used with caution depending on how much you * allow passwords to be stored within your application. - * + * * @author Bruno Harbulot. - * */ - public final static class PredefinedPasswordCallbackHandler implements CallbackHandler { + public static final class PredefinedPasswordCallbackHandler implements CallbackHandler { - private char[] password; - private String prompt; + private char[] mPassword; + private String mPrompt; public PredefinedPasswordCallbackHandler(String password) { this(password == null ? null : password.toCharArray(), null); @@ -283,16 +276,16 @@ public class PgpToX509 { } public PredefinedPasswordCallbackHandler(char[] password, String prompt) { - this.password = password; - this.prompt = prompt; + this.mPassword = password; + this.mPrompt = prompt; } public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (Callback callback : callbacks) { if (callback instanceof PasswordCallback) { PasswordCallback pwCallback = (PasswordCallback) callback; - if ((this.prompt == null) || (this.prompt.equals(pwCallback.getPrompt()))) { - pwCallback.setPassword(this.password); + if ((this.mPrompt == null) || (this.mPrompt.equals(pwCallback.getPrompt()))) { + pwCallback.setPassword(this.mPassword); } } else { throw new UnsupportedCallbackException(callback, "Unrecognised callback."); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/NoAsymmetricEncryptionException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/NoAsymmetricEncryptionException.java index 92542fa35..23c4bbbd9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/NoAsymmetricEncryptionException.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/NoAsymmetricEncryptionException.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de> + * Copyright (C) 2010 Thialfihar <thi@thialfihar.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.sufficientlysecure.keychain.pgp.exception; public class NoAsymmetricEncryptionException extends Exception { @@ -6,4 +23,4 @@ public class NoAsymmetricEncryptionException extends Exception { public NoAsymmetricEncryptionException() { super(); } -}
\ No newline at end of file +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralException.java index 36c663727..bb80d27ee 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralException.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/exception/PgpGeneralException.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de> + * Copyright (C) 2010 Thialfihar <thi@thialfihar.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.sufficientlysecure.keychain.pgp.exception; public class PgpGeneralException extends Exception { @@ -6,4 +23,4 @@ public class PgpGeneralException extends Exception { public PgpGeneralException(String message) { super(message); } -}
\ No newline at end of file +} |