diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java
index 905cae17e..b1e7eaeb5 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java
@@ -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();
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java
index 3d41c928b..c7241c723 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java
@@ -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() {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
index 3bd028da4..b7d204851 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
@@ -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);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java
index 4f25126ee..78345e11c 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java
@@ -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?
}
}
}
diff --git a/OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml b/OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml
index 3bd144fbf..c58e2d7e6 100644
--- a/OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml
+++ b/OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml
@@ -6,73 +6,109 @@
-
-
-
-
-
-
-
-
+ android:layout_height="match_parent"
+ android:orientation="vertical">
-
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml
index 19a259cbb..847dfffb5 100644
--- a/OpenKeychain/src/main/res/values/strings.xml
+++ b/OpenKeychain/src/main/res/values/strings.xml
@@ -277,6 +277,8 @@
"Not Encrypted"
"Show"
"Lookup"
+ "Either the signature is invalid or the key has been revoked/is expired. You can not be sure who wrote the text. Do you still want to display it?"
+ "I understand the risks, display it!"
"Exchange"