Big error screen if signature is invalid or key is revoked/expired, also fixes signature status for expired and revoked keys

This commit is contained in:
Dominik Schürmann
2014-10-08 18:31:31 +02:00
parent 2eb776594f
commit 0d6d4653b4
6 changed files with 188 additions and 96 deletions

View File

@@ -25,6 +25,7 @@ import org.sufficientlysecure.keychain.util.IterableIterator;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
/** A generic wrapped PGPKeyRing object.
*
@@ -76,6 +77,16 @@ public abstract class CanonicalizedKeyRing extends KeyRing {
return getRing().getPublicKey().isRevoked();
}
public boolean isExpired() throws PgpGeneralException {
// Is the master key expired?
Date creationDate = getRing().getPublicKey().getCreationTime();
Date expiryDate = getRing().getPublicKey().getValidSeconds() > 0
? new Date(creationDate.getTime() + getRing().getPublicKey().getValidSeconds() * 1000) : null;
Date now = new Date();
return creationDate.after(now) || (expiryDate != null && expiryDate.before(now));
}
public boolean canCertify() throws PgpGeneralException {
return getRing().getPublicKey().isEncryptionKey();
}

View File

@@ -103,9 +103,14 @@ public class OpenPgpSignatureResultBuilder {
Log.d(Constants.TAG, "signingRing.getUnorderedUserIds(): " + signingRing.getUnorderedUserIds());
setUserIds(signingRing.getUnorderedUserIds());
// from KEY
setKeyExpired(signingKey.isExpired());
setKeyRevoked(signingKey.isRevoked());
// either master key is expired/revoked or this specific subkey is expired/revoked
try {
setKeyExpired(signingRing.isExpired() || signingKey.isExpired());
setKeyRevoked(signingRing.isRevoked() || signingKey.isRevoked());
} catch (PgpGeneralException e) {
Log.e(Constants.TAG, "shouldn't happen!");
setKeyRevoked(true);
}
}
public OpenPgpSignatureResult build() {

View File

@@ -112,9 +112,15 @@ public abstract class DecryptFragment extends Fragment {
startActivityForResult(intent, REQUEST_CODE_NFC_DECRYPT);
}
protected void onResult(DecryptVerifyResult decryptVerifyResult) {
/**
*
* @return returns false if signature is invalid, key is revoked or expired.
*/
protected boolean onResult(DecryptVerifyResult decryptVerifyResult) {
final OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult();
boolean valid = false;
mSignatureKeyId = 0;
mResultLayout.setVisibility(View.VISIBLE);
if (signatureResult != null) {
@@ -147,14 +153,9 @@ public abstract class DecryptFragment extends Fragment {
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_VERIFIED);
setSignatureLayoutVisibility(View.VISIBLE);
mSignatureAction.setText(R.string.decrypt_result_action_show);
mSignatureAction.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_action_accounts, 0);
mSignatureLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showKey(mSignatureKeyId);
}
});
setShowAction(mSignatureKeyId);
valid = true;
break;
}
@@ -163,25 +164,9 @@ public abstract class DecryptFragment extends Fragment {
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_UNVERIFIED);
setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(mSignatureAction, mSignatureKeyId);
break;
}
setShowAction(mSignatureKeyId);
case OpenPgpSignatureResult.SIGNATURE_KEY_EXPIRED: {
mSignatureText.setText(R.string.decrypt_result_signature_expired_key);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_EXPIRED);
setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(mSignatureAction, mSignatureKeyId);
break;
}
case OpenPgpSignatureResult.SIGNATURE_KEY_REVOKED: {
mSignatureText.setText(R.string.decrypt_result_signature_revoked_key);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_REVOKED);
setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(mSignatureAction, mSignatureKeyId);
valid = true;
break;
}
@@ -198,6 +183,30 @@ public abstract class DecryptFragment extends Fragment {
lookupUnknownKey(mSignatureKeyId);
}
});
valid = true;
break;
}
case OpenPgpSignatureResult.SIGNATURE_KEY_EXPIRED: {
mSignatureText.setText(R.string.decrypt_result_signature_expired_key);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_EXPIRED);
setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(mSignatureKeyId);
valid = false;
break;
}
case OpenPgpSignatureResult.SIGNATURE_KEY_REVOKED: {
mSignatureText.setText(R.string.decrypt_result_signature_revoked_key);
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_REVOKED);
setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(mSignatureKeyId);
valid = false;
break;
}
@@ -206,6 +215,8 @@ public abstract class DecryptFragment extends Fragment {
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_INVALID);
setSignatureLayoutVisibility(View.GONE);
valid = false;
break;
}
}
@@ -216,7 +227,11 @@ public abstract class DecryptFragment extends Fragment {
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_NOT_SIGNED);
mEncryptionText.setText(R.string.decrypt_result_encrypted);
KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, KeyFormattingUtils.STATE_ENCRYPTED);
valid = true;
}
return valid;
}
private void setSignatureLayoutVisibility(int visibility) {
@@ -225,10 +240,10 @@ public abstract class DecryptFragment extends Fragment {
mSignatureDivider2.setVisibility(visibility);
}
private void setShowAction(TextView signatureAction, final long signatureKeyId) {
signatureAction.setText(R.string.decrypt_result_action_show);
signatureAction.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_action_accounts, 0);
signatureAction.setOnClickListener(new View.OnClickListener() {
private void setShowAction(final long signatureKeyId) {
mSignatureAction.setText(R.string.decrypt_result_action_show);
mSignatureAction.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_action_accounts, 0);
mSignatureLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showKey(signatureKeyId);

View File

@@ -27,6 +27,8 @@ import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.openintents.openpgp.util.OpenPgpApi;
@@ -44,6 +46,9 @@ public class DecryptTextFragment extends DecryptFragment {
public static final String ARG_CIPHERTEXT = "ciphertext";
// view
private LinearLayout mValidLayout;
private LinearLayout mInvalidLayout;
private Button mInvalidButton;
private TextView mText;
private View mShareButton;
private View mCopyButton;
@@ -71,7 +76,9 @@ public class DecryptTextFragment extends DecryptFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.decrypt_text_fragment, container, false);
mValidLayout = (LinearLayout) view.findViewById(R.id.decrypt_text_valid);
mInvalidLayout = (LinearLayout) view.findViewById(R.id.decrypt_text_invalid);
mInvalidButton = (Button) view.findViewById(R.id.decrypt_text_invalid_button);
mText = (TextView) view.findViewById(R.id.decrypt_text_plaintext);
mShareButton = view.findViewById(R.id.action_decrypt_share_plaintext);
mCopyButton = view.findViewById(R.id.action_decrypt_copy_plaintext);
@@ -87,6 +94,13 @@ public class DecryptTextFragment extends DecryptFragment {
copyToClipboard(mText.getText().toString());
}
});
mInvalidButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mInvalidLayout.setVisibility(View.GONE);
mValidLayout.setVisibility(View.VISIBLE);
}
});
return view;
}
@@ -186,9 +200,18 @@ public class DecryptTextFragment extends DecryptFragment {
pgpResult.createNotify(getActivity()).show();
// display signature result in activity
onResult(pgpResult);
boolean valid = onResult(pgpResult);
if (valid) {
mInvalidLayout.setVisibility(View.GONE);
mValidLayout.setVisibility(View.VISIBLE);
} else {
mInvalidLayout.setVisibility(View.VISIBLE);
mValidLayout.setVisibility(View.GONE);
}
} else {
pgpResult.createNotify(getActivity()).show();
// TODO: show also invalid layout with different text?
}
}
}