Fix symmetric encryption and cleanup

This commit is contained in:
Dominik Schürmann 2014-04-01 14:10:32 +02:00
parent b020f950e1
commit c859bbb6da
8 changed files with 91 additions and 136 deletions

View File

@ -18,6 +18,7 @@
package org.sufficientlysecure.keychain.pgp;
import android.content.Context;
import org.spongycastle.bcpg.ArmoredOutputStream;
import org.spongycastle.bcpg.BCPGOutputStream;
import org.spongycastle.openpgp.*;
@ -50,7 +51,7 @@ public class PgpSignEncrypt {
private boolean mEnableAsciiArmorOutput;
private int mCompressionId;
private long[] mEncryptionKeyIds;
private String mEncryptionPassphrase;
private String mSymmetricPassphrase;
private int mSymmetricEncryptionAlgorithm;
private long mSignatureKeyId;
private int mSignatureHashAlgorithm;
@ -67,7 +68,7 @@ public class PgpSignEncrypt {
this.mEnableAsciiArmorOutput = builder.mEnableAsciiArmorOutput;
this.mCompressionId = builder.mCompressionId;
this.mEncryptionKeyIds = builder.mEncryptionKeyIds;
this.mEncryptionPassphrase = builder.mEncryptionPassphrase;
this.mSymmetricPassphrase = builder.mSymmetricPassphrase;
this.mSymmetricEncryptionAlgorithm = builder.mSymmetricEncryptionAlgorithm;
this.mSignatureKeyId = builder.mSignatureKeyId;
this.mSignatureHashAlgorithm = builder.mSignatureHashAlgorithm;
@ -85,8 +86,8 @@ public class PgpSignEncrypt {
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 long[] mEncryptionKeyIds = null;
private String mSymmetricPassphrase = null;
private int mSymmetricEncryptionAlgorithm = 0;
private long mSignatureKeyId = Id.key.none;
private int mSignatureHashAlgorithm = 0;
@ -119,8 +120,8 @@ public class PgpSignEncrypt {
return this;
}
public Builder encryptionPassphrase(String encryptionPassphrase) {
this.mEncryptionPassphrase = encryptionPassphrase;
public Builder symmetricPassphrase(String symmetricPassphrase) {
this.mSymmetricPassphrase = symmetricPassphrase;
return this;
}
@ -181,7 +182,8 @@ public class PgpSignEncrypt {
NoSuchAlgorithmException, SignatureException {
boolean enableSignature = mSignatureKeyId != Id.key.none;
boolean enableEncryption = (mEncryptionKeyIds.length != 0 || mEncryptionPassphrase != null);
boolean enableEncryption = ((mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0)
|| mSymmetricPassphrase != null);
boolean enableCompression = (enableEncryption && mCompressionId != Id.choice.compression.none);
Log.d(Constants.TAG, "enableSignature:" + enableSignature
@ -246,12 +248,12 @@ public class PgpSignEncrypt {
cPk = new PGPEncryptedDataGenerator(encryptorBuilder);
if (mEncryptionKeyIds.length == 0) {
if (mSymmetricPassphrase != null) {
// Symmetric encryption
Log.d(Constants.TAG, "encryptionKeyIds length is 0 -> symmetric encryption");
JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator =
new JcePBEKeyEncryptionMethodGenerator(mEncryptionPassphrase.toCharArray());
new JcePBEKeyEncryptionMethodGenerator(mSymmetricPassphrase.toCharArray());
cPk.addMethod(symmetricEncryptionGenerator);
} else {
// Asymmetric encryption

View File

@ -43,7 +43,6 @@ import org.sufficientlysecure.keychain.util.*;
import java.io.*;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.List;
/**
@ -99,6 +98,7 @@ public class KeychainIntentService extends IntentService
public static final String ENCRYPT_INPUT_FILE = "input_file";
public static final String ENCRYPT_OUTPUT_FILE = "output_file";
public static final String ENCRYPT_PROVIDER_URI = "provider_uri";
public static final String ENCRYPT_SYMMETRIC_PASSPHRASE = "passphrase";
// decrypt/verify
public static final String DECRYPT_CIPHERTEXT_BYTES = "ciphertext_bytes";
@ -221,7 +221,7 @@ public class KeychainIntentService extends IntentService
int target = data.getInt(TARGET);
long secretKeyId = data.getLong(ENCRYPT_SECRET_KEY_ID);
String encryptionPassphrase = data.getString(GENERATE_KEY_SYMMETRIC_PASSPHRASE);
String symmetricPassphrase = data.getString(ENCRYPT_SYMMETRIC_PASSPHRASE);
boolean useAsciiArmor = data.getBoolean(ENCRYPT_USE_ASCII_ARMOR);
long encryptionKeyIds[] = data.getLongArray(ENCRYPT_ENCRYPTION_KEYS_IDS);
@ -329,7 +329,7 @@ public class KeychainIntentService extends IntentService
Preferences.getPreferences(this).getDefaultEncryptionAlgorithm())
.signatureForceV3(Preferences.getPreferences(this).getForceV3Signatures())
.encryptionKeyIds(encryptionKeyIds)
.encryptionPassphrase(encryptionPassphrase)
.symmetricPassphrase(symmetricPassphrase)
.signatureKeyId(secretKeyId)
.signatureHashAlgorithm(
Preferences.getPreferences(this).getDefaultHashAlgorithm())

View File

@ -71,18 +71,12 @@ public class EncryptActivity extends DrawerActivity implements
private static final int PAGER_CONTENT_MESSAGE = 0;
private static final int PAGER_CONTENT_FILE = 1;
// model
// model useb by message and file fragment
private long mEncryptionKeyIds[] = null;
private long mSigningKeyId = Id.key.none;
private String mPassphrase;
private String mPassphraseAgain;
private boolean mAsciiArmorDemand = false;
private boolean mOverrideAsciiArmor = false;
private boolean mGenerateSignature = false;
@Override
public void onSigningKeySelected(long signingKeyId) {
mSigningKeyId = signingKeyId;
@ -208,8 +202,8 @@ public class EncryptActivity extends DrawerActivity implements
}
if (extras.containsKey(EXTRA_ASCII_ARMOR)) {
mAsciiArmorDemand = extras.getBoolean(EXTRA_ASCII_ARMOR, true);
mFileFragmentBundle.putBoolean(EncryptFileFragment.ARG_ASCII_ARMOR, mAsciiArmorDemand);
boolean requestAsciiArmor = extras.getBoolean(EXTRA_ASCII_ARMOR, true);
mFileFragmentBundle.putBoolean(EncryptFileFragment.ARG_ASCII_ARMOR, requestAsciiArmor);
}
String textData = extras.getString(EXTRA_TEXT);
@ -252,51 +246,4 @@ public class EncryptActivity extends DrawerActivity implements
}
}
// /**
// * Update ActionBar buttons based on current selection in view
// */
// private void updateActionBarButtons() {
// switch (mSource.getCurrentView().getId()) {
// case R.id.sourceFile: {
// mEncryptShare.setVisibility(View.GONE);
// mEncryptClipboard.setVisibility(View.GONE);
// mEncryptFile.setVisibility(View.VISIBLE);
// break;
// }
//
// case R.id.sourceMessage: {
// mSourceLabel.setText(R.string.label_message);
//
// mEncryptShare.setVisibility(View.VISIBLE);
// mEncryptClipboard.setVisibility(View.VISIBLE);
// mEncryptFile.setVisibility(View.GONE);
//
// if (mMode.getCurrentView().getId() == R.id.modeSymmetric) {
// mEncryptShare.setEnabled(true);
// mEncryptClipboard.setEnabled(true);
// } else {
// if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) {
// if (mSecretKeyId == 0) {
// mEncryptShare.setEnabled(false);
// mEncryptClipboard.setEnabled(false);
// } else {
// mEncryptShare.setEnabled(true);
// mEncryptClipboard.setEnabled(true);
// }
// } else {
// mEncryptShare.setEnabled(true);
// mEncryptClipboard.setEnabled(true);
// }
// }
// break;
// }
//
// default: {
// break;
// }
// }
//
// }
}

View File

@ -1,5 +1,21 @@
package org.sufficientlysecure.keychain.ui;
/*
* Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.ui;
public interface EncryptActivityInterface {

View File

@ -79,15 +79,16 @@ public class EncryptAsymmetricFragment extends Fragment {
private void setSignatureKeyId(long signatureKeyId) {
mSecretKeyId = signatureKeyId;
// update key selection in EncryptActivity
mKeySelectionListener.onSigningKeySelected(signatureKeyId);
}
private void setEncryptionKeyIds(long[] encryptionKeyIds) {
mEncryptionKeyIds = encryptionKeyIds;
// update key selection in EncryptActivity
mKeySelectionListener.onEncryptionKeysSelected(encryptionKeyIds);
}
/**
* Inflate the layout for this fragment
*/
@ -138,6 +139,7 @@ public class EncryptAsymmetricFragment extends Fragment {
*/
private void preselectKeys(long preselectedSignatureKeyId, long[] preselectedEncryptionKeyIds) {
if (preselectedSignatureKeyId != 0) {
// TODO: don't use bouncy castle objects!
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(getActivity(),
preselectedSignatureKeyId);
PGPSecretKey masterKey;
@ -155,6 +157,8 @@ public class EncryptAsymmetricFragment extends Fragment {
if (preselectedEncryptionKeyIds != null) {
Vector<Long> goodIds = new Vector<Long>();
for (int i = 0; i < preselectedEncryptionKeyIds.length; ++i) {
// TODO: don't use bouncy castle objects!
PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(getActivity(),
preselectedEncryptionKeyIds[i]);
PGPPublicKey masterKey;
@ -197,7 +201,7 @@ public class EncryptAsymmetricFragment extends Fragment {
} else {
String uid = getResources().getString(R.string.user_id_no_name);
String uidExtra = "";
// TODO: make it nice and use helper!
// TODO: don't use bouncy castle objects!
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(getActivity(),
mSecretKeyId);
if (keyRing != null) {
@ -215,9 +219,6 @@ public class EncryptAsymmetricFragment extends Fragment {
mMainUserIdRest.setText(uidExtra);
mSign.setChecked(true);
}
//TODO
// updateActionBarButtons();
}
private void selectPublicKeys() {

View File

@ -223,29 +223,30 @@ public class EncryptFileFragment extends Fragment {
if (mEncryptInterface.isModeSymmetric()) {
// symmetric encryption
if (!mEncryptInterface.getPassphrase().equals(mEncryptInterface.getPassphraseAgain())) {
AppMsg.makeText(getActivity(), R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show();
return;
}
boolean gotPassPhrase = (mEncryptInterface.getPassphrase().length() != 0);
boolean gotPassPhrase = (mEncryptInterface.getPassphrase() != null
&& mEncryptInterface.getPassphrase().length() != 0);
if (!gotPassPhrase) {
AppMsg.makeText(getActivity(), R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT)
.show();
return;
}
if (!mEncryptInterface.getPassphrase().equals(mEncryptInterface.getPassphraseAgain())) {
AppMsg.makeText(getActivity(), R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show();
return;
}
} else {
// asymmetric encryption
boolean encryptIt = (mEncryptInterface.getEncryptionKeys() != null
boolean gotEncryptionKeys = (mEncryptInterface.getEncryptionKeys() != null
&& mEncryptInterface.getEncryptionKeys().length > 0);
// for now require at least one form of encryption for files
if (!encryptIt) {
if (!gotEncryptionKeys) {
AppMsg.makeText(getActivity(), R.string.select_encryption_key, AppMsg.STYLE_ALERT).show();
return;
}
if (!encryptIt && mEncryptInterface.getSignatureKey() == 0) {
if (!gotEncryptionKeys && mEncryptInterface.getSignatureKey() == 0) {
AppMsg.makeText(getActivity(), R.string.select_encryption_or_signature_key,
AppMsg.STYLE_ALERT).show();
return;
@ -266,14 +267,12 @@ public class EncryptFileFragment extends Fragment {
// Send all information needed to service to edit key in other thread
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
intent.setAction(KeychainIntentService.ACTION_ENCRYPT_SIGN);
// fill values for this action
Bundle data = new Bundle();
boolean useAsciiArmor = true;
long encryptionKeyIds[] = null;
int compressionId = 0;
boolean signOnly = false;
long mSecretKeyIdToPass = 0;
data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_URI);
if (mEncryptInterface.isModeSymmetric()) {
Log.d(Constants.TAG, "Symmetric encryption enabled!");
@ -281,35 +280,28 @@ public class EncryptFileFragment extends Fragment {
if (passphrase.length() == 0) {
passphrase = null;
}
data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passphrase);
data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase);
} else {
mSecretKeyIdToPass = mEncryptInterface.getSignatureKey();
encryptionKeyIds = mEncryptInterface.getEncryptionKeys();
signOnly = (mEncryptInterface.getEncryptionKeys() == null
data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mEncryptInterface.getSignatureKey());
data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, mEncryptInterface.getEncryptionKeys());
boolean signOnly = (mEncryptInterface.getEncryptionKeys() == null
|| mEncryptInterface.getEncryptionKeys().length == 0);
data.putBoolean(KeychainIntentService.ENCRYPT_SIGN_ONLY, signOnly);
}
intent.setAction(KeychainIntentService.ACTION_ENCRYPT_SIGN);
// choose default settings, target and data bundle by target
useAsciiArmor = mAsciiArmor.isChecked();
compressionId = ((Choice) mFileCompression.getSelectedItem()).getId();
data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_URI);
Log.d(Constants.TAG, "mInputFilename=" + mInputFilename + ", mOutputFilename="
+ mOutputFilename);
data.putString(KeychainIntentService.ENCRYPT_INPUT_FILE, mInputFilename);
data.putString(KeychainIntentService.ENCRYPT_OUTPUT_FILE, mOutputFilename);
data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mSecretKeyIdToPass);
boolean useAsciiArmor = mAsciiArmor.isChecked();
data.putBoolean(KeychainIntentService.ENCRYPT_USE_ASCII_ARMOR, useAsciiArmor);
data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, encryptionKeyIds);
int compressionId = ((Choice) mFileCompression.getSelectedItem()).getId();
data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID, compressionId);
// data.putBoolean(KeychainIntentService.ENCRYPT_GENERATE_SIGNATURE, mGenerateSignature);
data.putBoolean(KeychainIntentService.ENCRYPT_SIGN_ONLY, signOnly);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);

View File

@ -125,25 +125,26 @@ public class EncryptMessageFragment extends Fragment {
if (mEncryptInterface.isModeSymmetric()) {
// symmetric encryption
boolean gotPassPhrase = false;
if (!mEncryptInterface.getPassphrase().equals(mEncryptInterface.getPassphraseAgain())) {
AppMsg.makeText(getActivity(), R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show();
return;
}
gotPassPhrase = (mEncryptInterface.getPassphrase().length() != 0);
boolean gotPassPhrase = (mEncryptInterface.getPassphrase() != null
&& mEncryptInterface.getPassphrase().length() != 0);
if (!gotPassPhrase) {
AppMsg.makeText(getActivity(), R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT)
.show();
return;
}
if (!mEncryptInterface.getPassphrase().equals(mEncryptInterface.getPassphraseAgain())) {
AppMsg.makeText(getActivity(), R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show();
return;
}
} else {
// asymmetric encryption
boolean encryptIt = (mEncryptInterface.getEncryptionKeys() != null
boolean gotEncryptionKeys = (mEncryptInterface.getEncryptionKeys() != null
&& mEncryptInterface.getEncryptionKeys().length > 0);
if (!encryptIt && mEncryptInterface.getSignatureKey() == 0) {
if (!gotEncryptionKeys && mEncryptInterface.getSignatureKey() == 0) {
AppMsg.makeText(getActivity(), R.string.select_encryption_or_signature_key,
AppMsg.STYLE_ALERT).show();
return;
@ -164,13 +165,14 @@ public class EncryptMessageFragment extends Fragment {
// Send all information needed to service to edit key in other thread
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
intent.setAction(KeychainIntentService.ACTION_ENCRYPT_SIGN);
// fill values for this action
Bundle data = new Bundle();
long encryptionKeyIds[] = null;
int compressionId = 0;
boolean signOnly = false;
long mSecretKeyIdToPass = 0;
data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES);
String message = mMessage.getText().toString();
if (mEncryptInterface.isModeSymmetric()) {
Log.d(Constants.TAG, "Symmetric encryption enabled!");
@ -178,33 +180,26 @@ public class EncryptMessageFragment extends Fragment {
if (passphrase.length() == 0) {
passphrase = null;
}
data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passphrase);
data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase);
} else {
mSecretKeyIdToPass = mEncryptInterface.getSignatureKey();
encryptionKeyIds = mEncryptInterface.getEncryptionKeys();
signOnly = (mEncryptInterface.getEncryptionKeys() == null
data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mEncryptInterface.getSignatureKey());
data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, mEncryptInterface.getEncryptionKeys());
boolean signOnly = (mEncryptInterface.getEncryptionKeys() == null
|| mEncryptInterface.getEncryptionKeys().length == 0);
data.putBoolean(KeychainIntentService.ENCRYPT_SIGN_ONLY, signOnly);
if (signOnly) {
message = fixBadCharactersForGmail(message);
}
}
intent.setAction(KeychainIntentService.ACTION_ENCRYPT_SIGN);
// choose default settings, target and data bundle by target
compressionId = Preferences.getPreferences(getActivity()).getDefaultMessageCompression();
data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES);
String message = mMessage.getText().toString();
if (signOnly) {
message = fixBadCharactersForGmail(message);
}
data.putByteArray(KeychainIntentService.ENCRYPT_MESSAGE_BYTES, message.getBytes());
data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mSecretKeyIdToPass);
data.putBoolean(KeychainIntentService.ENCRYPT_USE_ASCII_ARMOR, true);
data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, encryptionKeyIds);
int compressionId = Preferences.getPreferences(getActivity()).getDefaultMessageCompression();
data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID, compressionId);
// data.putBoolean(KeychainIntentService.ENCRYPT_GENERATE_SIGNATURE, mGenerateSignature);
data.putBoolean(KeychainIntentService.ENCRYPT_SIGN_ONLY, signOnly);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);

View File

@ -73,6 +73,7 @@ public class EncryptSymmetricFragment extends Fragment {
@Override
public void afterTextChanged(Editable s) {
// update passphrase in EncryptActivity
mPassphraseUpdateListener.onPassphraseUpdate(s.toString());
}
});
@ -87,6 +88,7 @@ public class EncryptSymmetricFragment extends Fragment {
@Override
public void afterTextChanged(Editable s) {
// update passphrase in EncryptActivity
mPassphraseUpdateListener.onPassphraseAgainUpdate(s.toString());
}
});