mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-24 01:32:16 -05:00
Enforce private key for applications, verify signed-only texts without passphrase input, better internal decrypt and verify method
This commit is contained in:
parent
89a4c38cc0
commit
06f9134eb1
@ -38,18 +38,34 @@ public class OpenPgpSignatureResult implements Parcelable {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStatus(int status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isSignatureOnly() {
|
public boolean isSignatureOnly() {
|
||||||
return signatureOnly;
|
return signatureOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSignatureOnly(boolean signatureOnly) {
|
||||||
|
this.signatureOnly = signatureOnly;
|
||||||
|
}
|
||||||
|
|
||||||
public String getUserId() {
|
public String getUserId() {
|
||||||
return userId;
|
return userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setUserId(String userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
public long getKeyId() {
|
public long getKeyId() {
|
||||||
return keyId;
|
return keyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setKeyId(long keyId) {
|
||||||
|
this.keyId = keyId;
|
||||||
|
}
|
||||||
|
|
||||||
public OpenPgpSignatureResult() {
|
public OpenPgpSignatureResult() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
package org.sufficientlysecure.keychain.pgp;
|
package org.sufficientlysecure.keychain.pgp;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
|
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||||
import org.spongycastle.bcpg.ArmoredInputStream;
|
import org.spongycastle.bcpg.ArmoredInputStream;
|
||||||
import org.spongycastle.bcpg.SignatureSubpacketTags;
|
import org.spongycastle.bcpg.SignatureSubpacketTags;
|
||||||
import org.spongycastle.openpgp.PGPCompressedData;
|
import org.spongycastle.openpgp.PGPCompressedData;
|
||||||
@ -36,6 +36,7 @@ import org.spongycastle.openpgp.PGPPublicKey;
|
|||||||
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
|
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
|
||||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.spongycastle.openpgp.PGPSecretKey;
|
import org.spongycastle.openpgp.PGPSecretKey;
|
||||||
|
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.spongycastle.openpgp.PGPSignature;
|
import org.spongycastle.openpgp.PGPSignature;
|
||||||
import org.spongycastle.openpgp.PGPSignatureList;
|
import org.spongycastle.openpgp.PGPSignatureList;
|
||||||
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
|
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
|
||||||
@ -53,7 +54,7 @@ import org.sufficientlysecure.keychain.Constants;
|
|||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
||||||
import org.sufficientlysecure.keychain.util.InputData;
|
import org.sufficientlysecure.keychain.util.InputData;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
|
import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
|
||||||
@ -75,9 +76,10 @@ public class PgpDecryptVerify {
|
|||||||
private InputData data;
|
private InputData data;
|
||||||
private OutputStream outStream;
|
private OutputStream outStream;
|
||||||
|
|
||||||
private ProgressDialogUpdater progress;
|
private ProgressDialogUpdater progressDialogUpdater;
|
||||||
boolean assumeSymmetric;
|
private boolean assumeSymmetric;
|
||||||
String passphrase;
|
private String passphrase;
|
||||||
|
private long enforcedKeyId;
|
||||||
|
|
||||||
private PgpDecryptVerify(Builder builder) {
|
private PgpDecryptVerify(Builder builder) {
|
||||||
// private Constructor can only be called from Builder
|
// private Constructor can only be called from Builder
|
||||||
@ -85,9 +87,10 @@ public class PgpDecryptVerify {
|
|||||||
this.data = builder.data;
|
this.data = builder.data;
|
||||||
this.outStream = builder.outStream;
|
this.outStream = builder.outStream;
|
||||||
|
|
||||||
this.progress = builder.progress;
|
this.progressDialogUpdater = builder.progressDialogUpdater;
|
||||||
this.assumeSymmetric = builder.assumeSymmetric;
|
this.assumeSymmetric = builder.assumeSymmetric;
|
||||||
this.passphrase = builder.passphrase;
|
this.passphrase = builder.passphrase;
|
||||||
|
this.enforcedKeyId = builder.enforcedKeyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
@ -97,9 +100,10 @@ public class PgpDecryptVerify {
|
|||||||
private OutputStream outStream;
|
private OutputStream outStream;
|
||||||
|
|
||||||
// optional
|
// optional
|
||||||
private ProgressDialogUpdater progress = null;
|
private ProgressDialogUpdater progressDialogUpdater = null;
|
||||||
private boolean assumeSymmetric = false;
|
private boolean assumeSymmetric = false;
|
||||||
private String passphrase = "";
|
private String passphrase = "";
|
||||||
|
private long enforcedKeyId = 0;
|
||||||
|
|
||||||
public Builder(Context context, InputData data, OutputStream outStream) {
|
public Builder(Context context, InputData data, OutputStream outStream) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
@ -107,8 +111,8 @@ public class PgpDecryptVerify {
|
|||||||
this.outStream = outStream;
|
this.outStream = outStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder progress(ProgressDialogUpdater progress) {
|
public Builder progressDialogUpdater(ProgressDialogUpdater progressDialogUpdater) {
|
||||||
this.progress = progress;
|
this.progressDialogUpdater = progressDialogUpdater;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,20 +126,32 @@ public class PgpDecryptVerify {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow this key id alone for decryption.
|
||||||
|
* This means only ciphertexts encrypted for this private key can be decrypted.
|
||||||
|
*
|
||||||
|
* @param enforcedKeyId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Builder enforcedKeyId(long enforcedKeyId) {
|
||||||
|
this.enforcedKeyId = enforcedKeyId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public PgpDecryptVerify build() {
|
public PgpDecryptVerify build() {
|
||||||
return new PgpDecryptVerify(this);
|
return new PgpDecryptVerify(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateProgress(int message, int current, int total) {
|
public void updateProgress(int message, int current, int total) {
|
||||||
if (progress != null) {
|
if (progressDialogUpdater != null) {
|
||||||
progress.setProgress(message, current, total);
|
progressDialogUpdater.setProgress(message, current, total);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateProgress(int current, int total) {
|
public void updateProgress(int current, int total) {
|
||||||
if (progress != null) {
|
if (progressDialogUpdater != null) {
|
||||||
progress.setProgress(current, total);
|
progressDialogUpdater.setProgress(current, total);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,9 +193,8 @@ public class PgpDecryptVerify {
|
|||||||
* @throws PGPException
|
* @throws PGPException
|
||||||
* @throws SignatureException
|
* @throws SignatureException
|
||||||
*/
|
*/
|
||||||
public Bundle execute()
|
public PgpDecryptVerifyResult execute()
|
||||||
throws IOException, PgpGeneralException, PGPException, SignatureException {
|
throws IOException, PgpGeneralException, PGPException, SignatureException {
|
||||||
|
|
||||||
// automatically works with ascii armor input and binary
|
// automatically works with ascii armor input and binary
|
||||||
InputStream in = PGPUtil.getDecoderStream(data.getInputStream());
|
InputStream in = PGPUtil.getDecoderStream(data.getInputStream());
|
||||||
if (in instanceof ArmoredInputStream) {
|
if (in instanceof ArmoredInputStream) {
|
||||||
@ -207,9 +222,9 @@ public class PgpDecryptVerify {
|
|||||||
* @throws PGPException
|
* @throws PGPException
|
||||||
* @throws SignatureException
|
* @throws SignatureException
|
||||||
*/
|
*/
|
||||||
private Bundle decryptVerify(InputStream in)
|
private PgpDecryptVerifyResult decryptVerify(InputStream in)
|
||||||
throws IOException, PgpGeneralException, PGPException, SignatureException {
|
throws IOException, PgpGeneralException, PGPException, SignatureException {
|
||||||
Bundle returnData = new Bundle();
|
PgpDecryptVerifyResult returnData = new PgpDecryptVerifyResult();
|
||||||
|
|
||||||
PGPObjectFactory pgpF = new PGPObjectFactory(in);
|
PGPObjectFactory pgpF = new PGPObjectFactory(in);
|
||||||
PGPEncryptedDataList enc;
|
PGPEncryptedDataList enc;
|
||||||
@ -277,9 +292,38 @@ public class PgpDecryptVerify {
|
|||||||
PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj;
|
PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj;
|
||||||
secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, encData.getKeyID());
|
secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, encData.getKeyID());
|
||||||
if (secretKey != null) {
|
if (secretKey != null) {
|
||||||
|
// secret key exists in database
|
||||||
|
|
||||||
|
// allow only a specific key for decryption?
|
||||||
|
if (enforcedKeyId != 0) {
|
||||||
|
// TODO: improve this code! get master key directly!
|
||||||
|
PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(context, 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, "masterKeyId: " + masterKeyId);
|
||||||
|
|
||||||
|
if (enforcedKeyId != masterKeyId) {
|
||||||
|
throw new PgpGeneralException(context.getString(R.string.error_no_secret_key_found));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pbe = encData;
|
pbe = encData;
|
||||||
|
|
||||||
|
// passphrase handling...
|
||||||
|
if (passphrase == null) {
|
||||||
|
// try to get cached passphrase
|
||||||
|
passphrase = PassphraseCacheService.getCachedPassphrase(context, encData.getKeyID());
|
||||||
|
}
|
||||||
|
// if passphrase was not cached, return here!
|
||||||
|
if (passphrase == null) {
|
||||||
|
returnData.setKeyPassphraseNeeded(true);
|
||||||
|
return returnData;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,6 +361,7 @@ public class PgpDecryptVerify {
|
|||||||
PGPObjectFactory plainFact = new PGPObjectFactory(clear);
|
PGPObjectFactory plainFact = new PGPObjectFactory(clear);
|
||||||
Object dataChunk = plainFact.nextObject();
|
Object dataChunk = plainFact.nextObject();
|
||||||
PGPOnePassSignature signature = null;
|
PGPOnePassSignature signature = null;
|
||||||
|
OpenPgpSignatureResult signatureResult = null;
|
||||||
PGPPublicKey signatureKey = null;
|
PGPPublicKey signatureKey = null;
|
||||||
int signatureIndex = -1;
|
int signatureIndex = -1;
|
||||||
|
|
||||||
@ -334,7 +379,7 @@ public class PgpDecryptVerify {
|
|||||||
if (dataChunk instanceof PGPOnePassSignatureList) {
|
if (dataChunk instanceof PGPOnePassSignatureList) {
|
||||||
updateProgress(R.string.progress_processing_signature, currentProgress, 100);
|
updateProgress(R.string.progress_processing_signature, currentProgress, 100);
|
||||||
|
|
||||||
returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE, true);
|
signatureResult = new OpenPgpSignatureResult();
|
||||||
PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk;
|
PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk;
|
||||||
for (int i = 0; i < sigList.size(); ++i) {
|
for (int i = 0; i < sigList.size(); ++i) {
|
||||||
signature = sigList.get(i);
|
signature = sigList.get(i);
|
||||||
@ -354,12 +399,12 @@ public class PgpDecryptVerify {
|
|||||||
if (signKeyRing != null) {
|
if (signKeyRing != null) {
|
||||||
userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing));
|
userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing));
|
||||||
}
|
}
|
||||||
returnData.putString(KeychainIntentService.RESULT_SIGNATURE_USER_ID, userId);
|
signatureResult.setUserId(userId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
returnData.putLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, signatureKeyId);
|
signatureResult.setKeyId(signatureKeyId);
|
||||||
|
|
||||||
if (signature != null) {
|
if (signature != null) {
|
||||||
JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider()
|
JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider()
|
||||||
@ -367,7 +412,7 @@ public class PgpDecryptVerify {
|
|||||||
|
|
||||||
signature.init(contentVerifierBuilderProvider, signatureKey);
|
signature.init(contentVerifierBuilderProvider, signatureKey);
|
||||||
} else {
|
} else {
|
||||||
returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, true);
|
signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
dataChunk = plainFact.nextObject();
|
dataChunk = plainFact.nextObject();
|
||||||
@ -395,25 +440,24 @@ public class PgpDecryptVerify {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int n;
|
int n;
|
||||||
// TODO: progress calculation is broken here! Try to rework it based on commented code!
|
// TODO: progressDialogUpdater calculation is broken here! Try to rework it based on commented code!
|
||||||
// int progress = 0;
|
// int progressDialogUpdater = 0;
|
||||||
long startPos = data.getStreamPosition();
|
long startPos = data.getStreamPosition();
|
||||||
while ((n = dataIn.read(buffer)) > 0) {
|
while ((n = dataIn.read(buffer)) > 0) {
|
||||||
outStream.write(buffer, 0, n);
|
outStream.write(buffer, 0, n);
|
||||||
// progress += n;
|
// progressDialogUpdater += n;
|
||||||
if (signature != null) {
|
if (signature != null) {
|
||||||
try {
|
try {
|
||||||
signature.update(buffer, 0, n);
|
signature.update(buffer, 0, n);
|
||||||
} catch (SignatureException e) {
|
} catch (SignatureException e) {
|
||||||
returnData
|
signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_ERROR);
|
||||||
.putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, false);
|
|
||||||
signature = null;
|
signature = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: dead code?!
|
// TODO: dead code?!
|
||||||
// unknown size, but try to at least have a moving, slowing down progress bar
|
// unknown size, but try to at least have a moving, slowing down progressDialogUpdater bar
|
||||||
// currentProgress = startProgress + (endProgress - startProgress) * progress
|
// currentProgress = startProgress + (endProgress - startProgress) * progressDialogUpdater
|
||||||
// / (progress + 100000);
|
// / (progressDialogUpdater + 100000);
|
||||||
if (data.getSize() - startPos == 0) {
|
if (data.getSize() - startPos == 0) {
|
||||||
currentProgress = endProgress;
|
currentProgress = endProgress;
|
||||||
} else {
|
} else {
|
||||||
@ -430,17 +474,20 @@ public class PgpDecryptVerify {
|
|||||||
PGPSignature messageSignature = signatureList.get(signatureIndex);
|
PGPSignature messageSignature = signatureList.get(signatureIndex);
|
||||||
|
|
||||||
// these are not cleartext signatures!
|
// these are not cleartext signatures!
|
||||||
returnData.putBoolean(KeychainIntentService.RESULT_CLEARTEXT_SIGNATURE_ONLY, false);
|
// TODO: what about binary signatures?
|
||||||
|
signatureResult.setSignatureOnly(false);
|
||||||
|
|
||||||
//Now check binding signatures
|
//Now check binding signatures
|
||||||
boolean keyBinding_isok = verifyKeyBinding(context, messageSignature, signatureKey);
|
boolean keyBinding_isok = verifyKeyBinding(context, messageSignature, signatureKey);
|
||||||
boolean sig_isok = signature.verify(messageSignature);
|
boolean sig_isok = signature.verify(messageSignature);
|
||||||
|
|
||||||
returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, keyBinding_isok & sig_isok);
|
// TODO: implement CERTIFIED!
|
||||||
|
if (keyBinding_isok & sig_isok) {
|
||||||
|
signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: test if this integrity really check works!
|
|
||||||
if (encryptedData.isIntegrityProtected()) {
|
if (encryptedData.isIntegrityProtected()) {
|
||||||
updateProgress(R.string.progress_verifying_integrity, 95, 100);
|
updateProgress(R.string.progress_verifying_integrity, 95, 100);
|
||||||
|
|
||||||
@ -455,9 +502,12 @@ public class PgpDecryptVerify {
|
|||||||
} else {
|
} else {
|
||||||
// no integrity check
|
// no integrity check
|
||||||
Log.e(Constants.TAG, "Encrypted data was not integrity protected!");
|
Log.e(Constants.TAG, "Encrypted data was not integrity protected!");
|
||||||
|
// TODO: inform user?
|
||||||
}
|
}
|
||||||
|
|
||||||
updateProgress(R.string.progress_done, 100, 100);
|
updateProgress(R.string.progress_done, 100, 100);
|
||||||
|
|
||||||
|
returnData.setSignatureResult(signatureResult);
|
||||||
return returnData;
|
return returnData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -474,11 +524,12 @@ public class PgpDecryptVerify {
|
|||||||
* @throws PGPException
|
* @throws PGPException
|
||||||
* @throws SignatureException
|
* @throws SignatureException
|
||||||
*/
|
*/
|
||||||
private Bundle verifyCleartextSignature(ArmoredInputStream aIn)
|
private PgpDecryptVerifyResult verifyCleartextSignature(ArmoredInputStream aIn)
|
||||||
throws IOException, PgpGeneralException, PGPException, SignatureException {
|
throws IOException, PgpGeneralException, PGPException, SignatureException {
|
||||||
Bundle returnData = new Bundle();
|
PgpDecryptVerifyResult returnData = new PgpDecryptVerifyResult();
|
||||||
|
OpenPgpSignatureResult signatureResult = new OpenPgpSignatureResult();
|
||||||
// cleartext signatures are never encrypted ;)
|
// cleartext signatures are never encrypted ;)
|
||||||
returnData.putBoolean(KeychainIntentService.RESULT_CLEARTEXT_SIGNATURE_ONLY, true);
|
signatureResult.setSignatureOnly(true);
|
||||||
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
@ -504,8 +555,6 @@ public class PgpDecryptVerify {
|
|||||||
byte[] clearText = out.toByteArray();
|
byte[] clearText = out.toByteArray();
|
||||||
outStream.write(clearText);
|
outStream.write(clearText);
|
||||||
|
|
||||||
returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE, true);
|
|
||||||
|
|
||||||
updateProgress(R.string.progress_processing_signature, 60, 100);
|
updateProgress(R.string.progress_processing_signature, 60, 100);
|
||||||
PGPObjectFactory pgpFact = new PGPObjectFactory(aIn);
|
PGPObjectFactory pgpFact = new PGPObjectFactory(aIn);
|
||||||
|
|
||||||
@ -533,15 +582,15 @@ public class PgpDecryptVerify {
|
|||||||
if (signKeyRing != null) {
|
if (signKeyRing != null) {
|
||||||
userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing));
|
userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing));
|
||||||
}
|
}
|
||||||
returnData.putString(KeychainIntentService.RESULT_SIGNATURE_USER_ID, userId);
|
signatureResult.setUserId(userId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
returnData.putLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, signatureKeyId);
|
signatureResult.setKeyId(signatureKeyId);
|
||||||
|
|
||||||
if (signature == null) {
|
if (signature == null) {
|
||||||
returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, true);
|
signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY);
|
||||||
updateProgress(R.string.progress_done, 100, 100);
|
updateProgress(R.string.progress_done, 100, 100);
|
||||||
return returnData;
|
return returnData;
|
||||||
}
|
}
|
||||||
@ -574,9 +623,15 @@ public class PgpDecryptVerify {
|
|||||||
//Now check binding signatures
|
//Now check binding signatures
|
||||||
boolean keyBinding_isok = verifyKeyBinding(context, signature, signatureKey);
|
boolean keyBinding_isok = verifyKeyBinding(context, signature, signatureKey);
|
||||||
|
|
||||||
returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, sig_isok & keyBinding_isok);
|
if (sig_isok & keyBinding_isok) {
|
||||||
|
signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: what about SIGNATURE_SUCCESS_CERTIFIED and SIGNATURE_ERROR????
|
||||||
|
|
||||||
updateProgress(R.string.progress_done, 100, 100);
|
updateProgress(R.string.progress_done, 100, 100);
|
||||||
|
|
||||||
|
returnData.setSignatureResult(signatureResult);
|
||||||
return returnData;
|
return returnData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* 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.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;
|
||||||
|
|
||||||
|
public boolean isSymmetricPassphraseNeeded() {
|
||||||
|
return symmetricPassphraseNeeded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSymmetricPassphraseNeeded(boolean symmetricPassphraseNeeded) {
|
||||||
|
this.symmetricPassphraseNeeded = symmetricPassphraseNeeded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isKeyPassphraseNeeded() {
|
||||||
|
return keyPassphraseNeeded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKeyPassphraseNeeded(boolean keyPassphraseNeeded) {
|
||||||
|
this.keyPassphraseNeeded = keyPassphraseNeeded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenPgpSignatureResult getSignatureResult() {
|
||||||
|
return signatureResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSignatureResult(OpenPgpSignatureResult signatureResult) {
|
||||||
|
this.signatureResult = signatureResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PgpDecryptVerifyResult() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public PgpDecryptVerifyResult(PgpDecryptVerifyResult b) {
|
||||||
|
this.symmetricPassphraseNeeded = b.symmetricPassphraseNeeded;
|
||||||
|
this.keyPassphraseNeeded = b.keyPassphraseNeeded;
|
||||||
|
this.signatureResult = b.signatureResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeByte((byte) (symmetricPassphraseNeeded ? 1 : 0));
|
||||||
|
dest.writeByte((byte) (keyPassphraseNeeded ? 1 : 0));
|
||||||
|
dest.writeParcelable(signatureResult, 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());
|
||||||
|
return vr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PgpDecryptVerifyResult[] newArray(final int size) {
|
||||||
|
return new PgpDecryptVerifyResult[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -44,6 +44,7 @@ import org.sufficientlysecure.keychain.helper.OtherHelper;
|
|||||||
import org.sufficientlysecure.keychain.helper.Preferences;
|
import org.sufficientlysecure.keychain.helper.Preferences;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
|
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpImportExport;
|
import org.sufficientlysecure.keychain.pgp.PgpImportExport;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
|
||||||
@ -181,13 +182,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial
|
|||||||
// decrypt/verify
|
// decrypt/verify
|
||||||
public static final String RESULT_DECRYPTED_STRING = "decrypted_message";
|
public static final String RESULT_DECRYPTED_STRING = "decrypted_message";
|
||||||
public static final String RESULT_DECRYPTED_BYTES = "decrypted_data";
|
public static final String RESULT_DECRYPTED_BYTES = "decrypted_data";
|
||||||
public static final String RESULT_SIGNATURE = "signature";
|
public static final String RESULT_DECRYPT_VERIFY_RESULT = "signature";
|
||||||
public static final String RESULT_SIGNATURE_KEY_ID = "signature_key_id";
|
|
||||||
public static final String RESULT_SIGNATURE_USER_ID = "signature_user_id";
|
|
||||||
public static final String RESULT_CLEARTEXT_SIGNATURE_ONLY = "signature_only";
|
|
||||||
|
|
||||||
public static final String RESULT_SIGNATURE_SUCCESS = "signature_success";
|
|
||||||
public static final String RESULT_SIGNATURE_UNKNOWN = "signature_unknown";
|
|
||||||
|
|
||||||
// import
|
// import
|
||||||
public static final String RESULT_IMPORT_ADDED = "added";
|
public static final String RESULT_IMPORT_ADDED = "added";
|
||||||
@ -489,15 +484,17 @@ public class KeychainIntentService extends IntentService implements ProgressDial
|
|||||||
// verifyText and decrypt returning additional resultData values for the
|
// verifyText and decrypt returning additional resultData values for the
|
||||||
// verification of signatures
|
// verification of signatures
|
||||||
PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, outStream);
|
PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, outStream);
|
||||||
builder.progress(this);
|
builder.progressDialogUpdater(this);
|
||||||
|
|
||||||
builder.assumeSymmetric(assumeSymmetricEncryption)
|
builder.assumeSymmetric(assumeSymmetricEncryption)
|
||||||
.passphrase(PassphraseCacheService.getCachedPassphrase(this, secretKeyId));
|
.passphrase(PassphraseCacheService.getCachedPassphrase(this, secretKeyId));
|
||||||
|
|
||||||
resultData = builder.build().execute();
|
PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute();
|
||||||
|
|
||||||
outStream.close();
|
outStream.close();
|
||||||
|
|
||||||
|
resultData.putParcelable(RESULT_DECRYPT_VERIFY_RESULT, decryptVerifyResult);
|
||||||
|
|
||||||
/* Output */
|
/* Output */
|
||||||
|
|
||||||
switch (target) {
|
switch (target) {
|
||||||
@ -867,10 +864,10 @@ public class KeychainIntentService extends IntentService implements ProgressDial
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set progress of ProgressDialog by sending message to handler on UI thread
|
* Set progressDialogUpdater of ProgressDialog by sending message to handler on UI thread
|
||||||
*/
|
*/
|
||||||
public void setProgress(String message, int progress, int max) {
|
public void setProgress(String message, int progress, int max) {
|
||||||
Log.d(Constants.TAG, "Send message by setProgress with progress=" + progress + ", max="
|
Log.d(Constants.TAG, "Send message by setProgress with progressDialogUpdater=" + progress + ", max="
|
||||||
+ max);
|
+ max);
|
||||||
|
|
||||||
Bundle data = new Bundle();
|
Bundle data = new Bundle();
|
||||||
|
@ -21,7 +21,6 @@ import android.app.PendingIntent;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
|
|
||||||
@ -33,9 +32,10 @@ import org.spongycastle.util.Arrays;
|
|||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
|
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt;
|
import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
|
||||||
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
||||||
import org.sufficientlysecure.keychain.util.InputData;
|
import org.sufficientlysecure.keychain.util.InputData;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
@ -284,98 +284,29 @@ public class OpenPgpService extends RemoteService {
|
|||||||
Intent result = new Intent();
|
Intent result = new Intent();
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// TODO:
|
String passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
|
||||||
// fix the mess: http://stackoverflow.com/questions/148130/how-do-i-peek-at-the-first-two-bytes-in-an-inputstream
|
|
||||||
// should we allow to decrypt everything under every key id or only the one set?
|
|
||||||
// TODO: instead of trying to get the passphrase before
|
|
||||||
// pause stream when passphrase is missing and then resume
|
|
||||||
|
|
||||||
// TODO: put this code into PgpDecryptVerify class
|
|
||||||
|
|
||||||
// TODO: This allows to decrypt messages with ALL secret keys, not only the one for the
|
|
||||||
// app, Fix this?
|
|
||||||
// String passphrase = null;
|
|
||||||
// if (!signedOnly) {
|
|
||||||
// // BEGIN Get key
|
|
||||||
// // TODO: this input stream is consumed after PgpMain.getDecryptionKeyId()... do it
|
|
||||||
// // better!
|
|
||||||
// InputStream inputStream2 = new ByteArrayInputStream(inputBytes);
|
|
||||||
//
|
|
||||||
// // TODO: duplicates functions from DecryptActivity!
|
|
||||||
// long secretKeyId;
|
|
||||||
// try {
|
|
||||||
// if (inputStream2.markSupported()) {
|
|
||||||
// // should probably set this to the max size of two
|
|
||||||
// // pgpF objects, if it even needs to be anything other
|
|
||||||
// // than 0.
|
|
||||||
// inputStream2.mark(200);
|
|
||||||
// }
|
|
||||||
// secretKeyId = PgpHelper.getDecryptionKeyId(this, inputStream2);
|
|
||||||
// if (secretKeyId == Id.key.none) {
|
|
||||||
// throw new PgpGeneralException(getString(R.string.error_no_secret_key_found));
|
|
||||||
// }
|
|
||||||
// } catch (NoAsymmetricEncryptionException e) {
|
|
||||||
// if (inputStream2.markSupported()) {
|
|
||||||
// inputStream2.reset();
|
|
||||||
// }
|
|
||||||
// secretKeyId = Id.key.symmetric;
|
|
||||||
// if (!PgpDecryptVerify.hasSymmetricEncryption(this, inputStream2)) {
|
|
||||||
// throw new PgpGeneralException(
|
|
||||||
// getString(R.string.error_no_known_encryption_found));
|
|
||||||
// }
|
|
||||||
// // we do not support symmetric decryption from the API!
|
|
||||||
// throw new Exception("Symmetric decryption is not supported!");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Log.d(Constants.TAG, "secretKeyId " + secretKeyId);
|
|
||||||
|
|
||||||
// NOTE: currently this only gets the passphrase for the key set for this client
|
|
||||||
String passphrase;
|
|
||||||
if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) {
|
|
||||||
passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
|
|
||||||
} else {
|
|
||||||
passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId());
|
|
||||||
}
|
|
||||||
if (passphrase == null) {
|
|
||||||
// get PendingIntent for passphrase input, add it to given params and return to client
|
|
||||||
Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId());
|
|
||||||
return passphraseBundle;
|
|
||||||
}
|
|
||||||
|
|
||||||
long inputLength = is.available();
|
long inputLength = is.available();
|
||||||
InputData inputData = new InputData(is, inputLength);
|
InputData inputData = new InputData(is, inputLength);
|
||||||
|
|
||||||
Bundle outputBundle;
|
|
||||||
PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, os);
|
PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, os);
|
||||||
|
builder.assumeSymmetric(false) // no support for symmetric encryption
|
||||||
builder.assumeSymmetric(false)
|
.enforcedKeyId(appSettings.getKeyId()) // allow only the private key for this app for decryption
|
||||||
.passphrase(passphrase);
|
.passphrase(passphrase);
|
||||||
|
|
||||||
// TODO: this also decrypts with other secret keys that have no passphrase!!!
|
// TODO: currently does not support binary signed-only content
|
||||||
outputBundle = builder.build().execute();
|
PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute();
|
||||||
|
|
||||||
//TODO: instead of using all these wrapping use OpenPgpSignatureResult directly
|
if (decryptVerifyResult.isKeyPassphraseNeeded()) {
|
||||||
// in DecryptVerify class and then in DecryptActivity
|
// get PendingIntent for passphrase input, add it to given params and return to client
|
||||||
boolean signature = outputBundle.getBoolean(KeychainIntentService.RESULT_SIGNATURE, false);
|
Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId());
|
||||||
if (signature) {
|
return passphraseBundle;
|
||||||
long signatureKeyId = outputBundle
|
} else if (decryptVerifyResult.isSymmetricPassphraseNeeded()) {
|
||||||
.getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, 0);
|
throw new PgpGeneralException("Decryption of symmetric content not supported by API!");
|
||||||
String signatureUserId = outputBundle
|
}
|
||||||
.getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID);
|
|
||||||
boolean signatureSuccess = outputBundle
|
|
||||||
.getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, false);
|
|
||||||
boolean signatureUnknown = outputBundle
|
|
||||||
.getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, false);
|
|
||||||
boolean signatureOnly = outputBundle
|
|
||||||
.getBoolean(KeychainIntentService.RESULT_CLEARTEXT_SIGNATURE_ONLY, false);
|
|
||||||
|
|
||||||
// TODO: SIGNATURE_SUCCESS_CERTIFIED is currently not implemented
|
|
||||||
int signatureStatus = OpenPgpSignatureResult.SIGNATURE_ERROR;
|
|
||||||
if (signatureSuccess) {
|
|
||||||
signatureStatus = OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED;
|
|
||||||
} else if (signatureUnknown) {
|
|
||||||
signatureStatus = OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY;
|
|
||||||
|
|
||||||
|
OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult();
|
||||||
|
if (signatureResult != null) {
|
||||||
|
if (signatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY) {
|
||||||
// If signature is unknown we return an additional PendingIntent
|
// If signature is unknown we return an additional PendingIntent
|
||||||
// to retrieve the missing key
|
// to retrieve the missing key
|
||||||
// TODO!!!
|
// TODO!!!
|
||||||
@ -390,11 +321,9 @@ public class OpenPgpService extends RemoteService {
|
|||||||
result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
|
result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result.putExtra(OpenPgpApi.RESULT_SIGNATURE, signatureResult);
|
||||||
OpenPgpSignatureResult sigResult = new OpenPgpSignatureResult(signatureStatus,
|
|
||||||
signatureUserId, signatureOnly, signatureKeyId);
|
|
||||||
result.putExtra(OpenPgpApi.RESULT_SIGNATURE, sigResult);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
is.close();
|
is.close();
|
||||||
os.close();
|
os.close();
|
||||||
|
@ -25,6 +25,7 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
@ -32,6 +33,7 @@ import org.sufficientlysecure.keychain.R;
|
|||||||
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
||||||
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
|
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
|
||||||
import org.sufficientlysecure.keychain.helper.FileHelper;
|
import org.sufficientlysecure.keychain.helper.FileHelper;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
|
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
|
||||||
@ -690,11 +692,15 @@ public class DecryptActivity extends DrawerActivity {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (returnData.getBoolean(KeychainIntentService.RESULT_SIGNATURE)) {
|
PgpDecryptVerifyResult decryptVerifyResult =
|
||||||
String userId = returnData
|
returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT);
|
||||||
.getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID);
|
|
||||||
mSignatureKeyId = returnData
|
OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult();
|
||||||
.getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID);
|
|
||||||
|
if (signatureResult != null) {
|
||||||
|
|
||||||
|
String userId = signatureResult.getUserId();
|
||||||
|
mSignatureKeyId = signatureResult.getKeyId();
|
||||||
mUserIdRest.setText("id: "
|
mUserIdRest.setText("id: "
|
||||||
+ PgpKeyHelper.convertKeyIdToHex(mSignatureKeyId));
|
+ PgpKeyHelper.convertKeyIdToHex(mSignatureKeyId));
|
||||||
if (userId == null) {
|
if (userId == null) {
|
||||||
@ -707,19 +713,32 @@ public class DecryptActivity extends DrawerActivity {
|
|||||||
}
|
}
|
||||||
mUserId.setText(userId);
|
mUserId.setText(userId);
|
||||||
|
|
||||||
if (returnData.getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS)) {
|
switch (signatureResult.getStatus()) {
|
||||||
|
case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: {
|
||||||
mSignatureStatusImage.setImageResource(R.drawable.overlay_ok);
|
mSignatureStatusImage.setImageResource(R.drawable.overlay_ok);
|
||||||
mLookupKey.setVisibility(View.GONE);
|
mLookupKey.setVisibility(View.GONE);
|
||||||
} else if (returnData
|
break;
|
||||||
.getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN)) {
|
}
|
||||||
|
|
||||||
|
// TODO!
|
||||||
|
// case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
case OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY: {
|
||||||
mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
|
mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
|
||||||
mLookupKey.setVisibility(View.VISIBLE);
|
mLookupKey.setVisibility(View.VISIBLE);
|
||||||
AppMsg.makeText(DecryptActivity.this,
|
AppMsg.makeText(DecryptActivity.this,
|
||||||
R.string.unknown_signature,
|
R.string.unknown_signature,
|
||||||
AppMsg.STYLE_ALERT).show();
|
AppMsg.STYLE_ALERT).show();
|
||||||
} else {
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
|
mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
|
||||||
mLookupKey.setVisibility(View.GONE);
|
mLookupKey.setVisibility(View.GONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mSignatureLayout.setVisibility(View.VISIBLE);
|
mSignatureLayout.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
@ -733,7 +752,7 @@ public class DecryptActivity extends DrawerActivity {
|
|||||||
Messenger messenger = new Messenger(saveHandler);
|
Messenger messenger = new Messenger(saveHandler);
|
||||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||||
|
|
||||||
// show progress dialog
|
// show progressDialogUpdater dialog
|
||||||
saveHandler.showProgressDialog(this);
|
saveHandler.showProgressDialog(this);
|
||||||
|
|
||||||
// start service with intent
|
// start service with intent
|
||||||
|
Loading…
Reference in New Issue
Block a user