jury-rig broken sign mechanism

Should improve situation on #811
This commit is contained in:
Vincent Breitmoser 2014-09-09 22:41:24 +02:00
parent a925e8b83f
commit 7dbb7cf1e1
4 changed files with 61 additions and 30 deletions

View File

@ -68,6 +68,7 @@ public class PgpSignEncrypt {
private String mSymmetricPassphrase; private String mSymmetricPassphrase;
private int mSymmetricEncryptionAlgorithm; private int mSymmetricEncryptionAlgorithm;
private long mSignatureMasterKeyId; private long mSignatureMasterKeyId;
private Long mSignatureSubKeyId;
private int mSignatureHashAlgorithm; private int mSignatureHashAlgorithm;
private String mSignaturePassphrase; private String mSignaturePassphrase;
private long mAdditionalEncryptId; private long mAdditionalEncryptId;
@ -101,6 +102,7 @@ public class PgpSignEncrypt {
this.mSymmetricPassphrase = builder.mSymmetricPassphrase; this.mSymmetricPassphrase = builder.mSymmetricPassphrase;
this.mSymmetricEncryptionAlgorithm = builder.mSymmetricEncryptionAlgorithm; this.mSymmetricEncryptionAlgorithm = builder.mSymmetricEncryptionAlgorithm;
this.mSignatureMasterKeyId = builder.mSignatureMasterKeyId; this.mSignatureMasterKeyId = builder.mSignatureMasterKeyId;
this.mSignatureSubKeyId = builder.mSignatureSubKeyId;
this.mSignatureHashAlgorithm = builder.mSignatureHashAlgorithm; this.mSignatureHashAlgorithm = builder.mSignatureHashAlgorithm;
this.mSignaturePassphrase = builder.mSignaturePassphrase; this.mSignaturePassphrase = builder.mSignaturePassphrase;
this.mAdditionalEncryptId = builder.mAdditionalEncryptId; this.mAdditionalEncryptId = builder.mAdditionalEncryptId;
@ -125,6 +127,7 @@ public class PgpSignEncrypt {
private String mSymmetricPassphrase = null; private String mSymmetricPassphrase = null;
private int mSymmetricEncryptionAlgorithm = 0; private int mSymmetricEncryptionAlgorithm = 0;
private long mSignatureMasterKeyId = Constants.key.none; private long mSignatureMasterKeyId = Constants.key.none;
private Long mSignatureSubKeyId = null;
private int mSignatureHashAlgorithm = 0; private int mSignatureHashAlgorithm = 0;
private String mSignaturePassphrase = null; private String mSignaturePassphrase = null;
private long mAdditionalEncryptId = Constants.key.none; private long mAdditionalEncryptId = Constants.key.none;
@ -179,6 +182,11 @@ public class PgpSignEncrypt {
return this; return this;
} }
public Builder setSignatureSubKeyId(long signatureSubKeyId) {
mSignatureSubKeyId = signatureSubKeyId;
return this;
}
public Builder setSignatureHashAlgorithm(int signatureHashAlgorithm) { public Builder setSignatureHashAlgorithm(int signatureHashAlgorithm) {
mSignatureHashAlgorithm = signatureHashAlgorithm; mSignatureHashAlgorithm = signatureHashAlgorithm;
return this; return this;
@ -309,26 +317,32 @@ public class PgpSignEncrypt {
/* Get keys for signature generation for later usage */ /* Get keys for signature generation for later usage */
CanonicalizedSecretKey signingKey = null; CanonicalizedSecretKey signingKey = null;
if (enableSignature) { if (enableSignature) {
CanonicalizedSecretKeyRing signingKeyRing;
// If we weren't handed a passphrase, throw early
if (mSignaturePassphrase == null) {
throw new NoPassphraseException();
}
try { try {
signingKeyRing = mProviderHelper.getCanonicalizedSecretKeyRing(mSignatureMasterKeyId); // fetch the indicated master key id (the one whose name we sign in)
CanonicalizedSecretKeyRing signingKeyRing =
mProviderHelper.getCanonicalizedSecretKeyRing(mSignatureMasterKeyId);
// fetch the specific subkey to sign with, or just use the master key if none specified
long signKeyId = mSignatureSubKeyId != null ? mSignatureSubKeyId : mSignatureMasterKeyId;
signingKey = signingKeyRing.getSecretKey(signKeyId);
// make sure it's a signing key alright!
} catch (ProviderHelper.NotFoundException e) { } catch (ProviderHelper.NotFoundException e) {
throw new NoSigningKeyException(); throw new NoSigningKeyException();
} }
try {
signingKey = signingKeyRing.getSigningSubKey();
} catch (PgpGeneralException e) {
throw new NoSigningKeyException();
}
if (mSignaturePassphrase == null) { if ( ! signingKey.canSign()) {
throw new NoPassphraseException(); throw new NoSigningKeyException();
} }
updateProgress(R.string.progress_extracting_signature_key, 0, 100); updateProgress(R.string.progress_extracting_signature_key, 0, 100);
try { try {
if (!signingKey.unlock(mSignaturePassphrase)) { if ( ! signingKey.unlock(mSignaturePassphrase)) {
throw new WrongPassphraseException(); throw new WrongPassphraseException();
} }
} catch (PgpGeneralException e) { } catch (PgpGeneralException e) {

View File

@ -50,6 +50,7 @@ import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException;
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainDatabase; import org.sufficientlysecure.keychain.provider.KeychainDatabase;
@ -128,7 +129,7 @@ public class KeychainIntentService extends IntentService implements Progressable
public static final String SELECTED_URI = "selected_uri"; public static final String SELECTED_URI = "selected_uri";
// encrypt // encrypt
public static final String ENCRYPT_SIGNATURE_KEY_ID = "secret_key_id"; public static final String ENCRYPT_SIGNATURE_MASTER_ID = "secret_key_id";
public static final String ENCRYPT_USE_ASCII_ARMOR = "use_ascii_armor"; public static final String ENCRYPT_USE_ASCII_ARMOR = "use_ascii_armor";
public static final String ENCRYPT_ENCRYPTION_KEYS_IDS = "encryption_keys_ids"; public static final String ENCRYPT_ENCRYPTION_KEYS_IDS = "encryption_keys_ids";
public static final String ENCRYPT_COMPRESSION_ID = "compression_id"; public static final String ENCRYPT_COMPRESSION_ID = "compression_id";
@ -251,7 +252,7 @@ public class KeychainIntentService extends IntentService implements Progressable
int source = data.get(SOURCE) != null ? data.getInt(SOURCE) : data.getInt(TARGET); int source = data.get(SOURCE) != null ? data.getInt(SOURCE) : data.getInt(TARGET);
Bundle resultData = new Bundle(); Bundle resultData = new Bundle();
long signatureKeyId = data.getLong(ENCRYPT_SIGNATURE_KEY_ID); long sigMasterKeyId = data.getLong(ENCRYPT_SIGNATURE_MASTER_ID);
String symmetricPassphrase = data.getString(ENCRYPT_SYMMETRIC_PASSPHRASE); String symmetricPassphrase = data.getString(ENCRYPT_SYMMETRIC_PASSPHRASE);
boolean useAsciiArmor = data.getBoolean(ENCRYPT_USE_ASCII_ARMOR); boolean useAsciiArmor = data.getBoolean(ENCRYPT_USE_ASCII_ARMOR);
@ -280,14 +281,20 @@ public class KeychainIntentService extends IntentService implements Progressable
.setOriginalFilename(originalFilename); .setOriginalFilename(originalFilename);
try { try {
builder.setSignatureMasterKeyId(signatureKeyId) CachedPublicKeyRing signingRing =
.setSignaturePassphrase( new ProviderHelper(this).getCachedPublicKeyRing(sigMasterKeyId);
PassphraseCacheService.getCachedPassphrase(this, signatureKeyId)) long sigSubKeyId = signingRing.getSignId();
// It is assumed that the passphrase was cached prior to the service call.
String passphrase = PassphraseCacheService.getCachedPassphrase(this, sigSubKeyId);
builder.setSignatureMasterKeyId(sigMasterKeyId)
.setSignatureSubKeyId(sigSubKeyId)
.setSignaturePassphrase(passphrase)
.setSignatureHashAlgorithm( .setSignatureHashAlgorithm(
Preferences.getPreferences(this).getDefaultHashAlgorithm()) Preferences.getPreferences(this).getDefaultHashAlgorithm())
.setAdditionalEncryptId(signatureKeyId); .setAdditionalEncryptId(sigMasterKeyId);
} catch (PassphraseCacheService.KeyNotFoundException e) { } catch (PgpGeneralException e) {
// encrypt-only // encrypt-only
// TODO Just silently drop the requested signature? Shouldn't we throw here?
} }
// this assumes that the bytes are cleartext (valid for current implementation!) // this assumes that the bytes are cleartext (valid for current implementation!)

View File

@ -252,7 +252,7 @@ public class EncryptFileActivity extends DrawerActivity implements EncryptActivi
} }
data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase); data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase);
} else { } else {
data.putLong(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_ID, mSigningKeyId); data.putLong(KeychainIntentService.ENCRYPT_SIGNATURE_MASTER_ID, mSigningKeyId);
data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, mEncryptionKeyIds); data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, mEncryptionKeyIds);
} }
return data; return data;

View File

@ -36,6 +36,9 @@ import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.helper.Preferences; import org.sufficientlysecure.keychain.helper.Preferences;
import org.sufficientlysecure.keychain.helper.ShareHelper; import org.sufficientlysecure.keychain.helper.ShareHelper;
import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.service.PassphraseCacheService;
@ -235,7 +238,7 @@ public class EncryptTextActivity extends DrawerActivity implements EncryptActivi
} }
data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase); data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase);
} else { } else {
data.putLong(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_ID, mSigningKeyId); data.putLong(KeychainIntentService.ENCRYPT_SIGNATURE_MASTER_ID, mSigningKeyId);
data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, mEncryptionKeyIds); data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, mEncryptionKeyIds);
} }
return data; return data;
@ -310,21 +313,28 @@ public class EncryptTextActivity extends DrawerActivity implements EncryptActivi
} }
try { try {
if (mSigningKeyId != 0 && PassphraseCacheService.getCachedPassphrase(this, mSigningKeyId) == null) { if (mSigningKeyId != 0) {
PassphraseDialogFragment.show(this, mSigningKeyId, CachedPublicKeyRing signingRing =
new Handler() { new ProviderHelper(this).getCachedPublicKeyRing(mSigningKeyId);
@Override long sigSubKeyId = signingRing.getSignId();
public void handleMessage(Message message) { if (PassphraseCacheService.getCachedPassphrase(this, sigSubKeyId) == null) {
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { PassphraseDialogFragment.show(this, sigSubKeyId,
// restart new Handler() {
startEncrypt(); @Override
public void handleMessage(Message message) {
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
// restart
startEncrypt();
}
} }
} }
} );
);
return false; return false;
}
} }
} catch (PgpGeneralException e) {
Log.e(Constants.TAG, "Key not found!", e);
} catch (PassphraseCacheService.KeyNotFoundException e) { } catch (PassphraseCacheService.KeyNotFoundException e) {
Log.e(Constants.TAG, "Key not found!", e); Log.e(Constants.TAG, "Key not found!", e);
} }