mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-12-25 08:28:50 -05:00
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:
parent
2eb776594f
commit
0d6d4653b4
@ -25,6 +25,7 @@ import org.sufficientlysecure.keychain.util.IterableIterator;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/** A generic wrapped PGPKeyRing object.
|
/** A generic wrapped PGPKeyRing object.
|
||||||
*
|
*
|
||||||
@ -76,6 +77,16 @@ public abstract class CanonicalizedKeyRing extends KeyRing {
|
|||||||
return getRing().getPublicKey().isRevoked();
|
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 {
|
public boolean canCertify() throws PgpGeneralException {
|
||||||
return getRing().getPublicKey().isEncryptionKey();
|
return getRing().getPublicKey().isEncryptionKey();
|
||||||
}
|
}
|
||||||
|
@ -103,9 +103,14 @@ public class OpenPgpSignatureResultBuilder {
|
|||||||
Log.d(Constants.TAG, "signingRing.getUnorderedUserIds(): " + signingRing.getUnorderedUserIds());
|
Log.d(Constants.TAG, "signingRing.getUnorderedUserIds(): " + signingRing.getUnorderedUserIds());
|
||||||
setUserIds(signingRing.getUnorderedUserIds());
|
setUserIds(signingRing.getUnorderedUserIds());
|
||||||
|
|
||||||
// from KEY
|
// either master key is expired/revoked or this specific subkey is expired/revoked
|
||||||
setKeyExpired(signingKey.isExpired());
|
try {
|
||||||
setKeyRevoked(signingKey.isRevoked());
|
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() {
|
public OpenPgpSignatureResult build() {
|
||||||
|
@ -112,9 +112,15 @@ public abstract class DecryptFragment extends Fragment {
|
|||||||
startActivityForResult(intent, REQUEST_CODE_NFC_DECRYPT);
|
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();
|
final OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult();
|
||||||
|
|
||||||
|
boolean valid = false;
|
||||||
|
|
||||||
mSignatureKeyId = 0;
|
mSignatureKeyId = 0;
|
||||||
mResultLayout.setVisibility(View.VISIBLE);
|
mResultLayout.setVisibility(View.VISIBLE);
|
||||||
if (signatureResult != null) {
|
if (signatureResult != null) {
|
||||||
@ -147,14 +153,9 @@ public abstract class DecryptFragment extends Fragment {
|
|||||||
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_VERIFIED);
|
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_VERIFIED);
|
||||||
|
|
||||||
setSignatureLayoutVisibility(View.VISIBLE);
|
setSignatureLayoutVisibility(View.VISIBLE);
|
||||||
mSignatureAction.setText(R.string.decrypt_result_action_show);
|
setShowAction(mSignatureKeyId);
|
||||||
mSignatureAction.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_action_accounts, 0);
|
|
||||||
mSignatureLayout.setOnClickListener(new View.OnClickListener() {
|
valid = true;
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
showKey(mSignatureKeyId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,25 +164,9 @@ public abstract class DecryptFragment extends Fragment {
|
|||||||
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_UNVERIFIED);
|
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_UNVERIFIED);
|
||||||
|
|
||||||
setSignatureLayoutVisibility(View.VISIBLE);
|
setSignatureLayoutVisibility(View.VISIBLE);
|
||||||
setShowAction(mSignatureAction, mSignatureKeyId);
|
setShowAction(mSignatureKeyId);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OpenPgpSignatureResult.SIGNATURE_KEY_EXPIRED: {
|
valid = true;
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,6 +183,30 @@ public abstract class DecryptFragment extends Fragment {
|
|||||||
lookupUnknownKey(mSignatureKeyId);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,6 +215,8 @@ public abstract class DecryptFragment extends Fragment {
|
|||||||
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_INVALID);
|
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_INVALID);
|
||||||
|
|
||||||
setSignatureLayoutVisibility(View.GONE);
|
setSignatureLayoutVisibility(View.GONE);
|
||||||
|
|
||||||
|
valid = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,7 +227,11 @@ public abstract class DecryptFragment extends Fragment {
|
|||||||
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_NOT_SIGNED);
|
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, KeyFormattingUtils.STATE_NOT_SIGNED);
|
||||||
mEncryptionText.setText(R.string.decrypt_result_encrypted);
|
mEncryptionText.setText(R.string.decrypt_result_encrypted);
|
||||||
KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, KeyFormattingUtils.STATE_ENCRYPTED);
|
KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, KeyFormattingUtils.STATE_ENCRYPTED);
|
||||||
|
|
||||||
|
valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setSignatureLayoutVisibility(int visibility) {
|
private void setSignatureLayoutVisibility(int visibility) {
|
||||||
@ -225,10 +240,10 @@ public abstract class DecryptFragment extends Fragment {
|
|||||||
mSignatureDivider2.setVisibility(visibility);
|
mSignatureDivider2.setVisibility(visibility);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setShowAction(TextView signatureAction, final long signatureKeyId) {
|
private void setShowAction(final long signatureKeyId) {
|
||||||
signatureAction.setText(R.string.decrypt_result_action_show);
|
mSignatureAction.setText(R.string.decrypt_result_action_show);
|
||||||
signatureAction.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_action_accounts, 0);
|
mSignatureAction.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_action_accounts, 0);
|
||||||
signatureAction.setOnClickListener(new View.OnClickListener() {
|
mSignatureLayout.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
showKey(signatureKeyId);
|
showKey(signatureKeyId);
|
||||||
|
@ -27,6 +27,8 @@ import android.text.method.ScrollingMovementMethod;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.openintents.openpgp.util.OpenPgpApi;
|
import org.openintents.openpgp.util.OpenPgpApi;
|
||||||
@ -44,6 +46,9 @@ public class DecryptTextFragment extends DecryptFragment {
|
|||||||
public static final String ARG_CIPHERTEXT = "ciphertext";
|
public static final String ARG_CIPHERTEXT = "ciphertext";
|
||||||
|
|
||||||
// view
|
// view
|
||||||
|
private LinearLayout mValidLayout;
|
||||||
|
private LinearLayout mInvalidLayout;
|
||||||
|
private Button mInvalidButton;
|
||||||
private TextView mText;
|
private TextView mText;
|
||||||
private View mShareButton;
|
private View mShareButton;
|
||||||
private View mCopyButton;
|
private View mCopyButton;
|
||||||
@ -71,7 +76,9 @@ public class DecryptTextFragment extends DecryptFragment {
|
|||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.decrypt_text_fragment, container, false);
|
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);
|
mText = (TextView) view.findViewById(R.id.decrypt_text_plaintext);
|
||||||
mShareButton = view.findViewById(R.id.action_decrypt_share_plaintext);
|
mShareButton = view.findViewById(R.id.action_decrypt_share_plaintext);
|
||||||
mCopyButton = view.findViewById(R.id.action_decrypt_copy_plaintext);
|
mCopyButton = view.findViewById(R.id.action_decrypt_copy_plaintext);
|
||||||
@ -87,6 +94,13 @@ public class DecryptTextFragment extends DecryptFragment {
|
|||||||
copyToClipboard(mText.getText().toString());
|
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;
|
return view;
|
||||||
}
|
}
|
||||||
@ -186,9 +200,18 @@ public class DecryptTextFragment extends DecryptFragment {
|
|||||||
pgpResult.createNotify(getActivity()).show();
|
pgpResult.createNotify(getActivity()).show();
|
||||||
|
|
||||||
// display signature result in activity
|
// 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 {
|
} else {
|
||||||
pgpResult.createNotify(getActivity()).show();
|
pgpResult.createNotify(getActivity()).show();
|
||||||
|
// TODO: show also invalid layout with different text?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,13 @@
|
|||||||
|
|
||||||
<include layout="@layout/decrypt_result_include" />
|
<include layout="@layout/decrypt_result_include" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:visibility="gone"
|
||||||
|
android:id="@+id/decrypt_text_valid"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<ScrollView
|
<ScrollView
|
||||||
android:fillViewport="true"
|
android:fillViewport="true"
|
||||||
android:paddingTop="8dp"
|
android:paddingTop="8dp"
|
||||||
@ -75,4 +82,33 @@
|
|||||||
style="@style/SelectableItem" />
|
style="@style/SelectableItem" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:visibility="gone"
|
||||||
|
android:id="@+id/decrypt_text_invalid"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:text="@string/decrypt_invalid_text"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:textColor="@color/android_red_dark" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/decrypt_text_invalid_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/button_edgy"
|
||||||
|
android:textColor="@color/android_red_dark"
|
||||||
|
android:text="@string/decrypt_invalid_button"
|
||||||
|
android:layout_gravity="center_horizontal" />
|
||||||
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -277,6 +277,8 @@
|
|||||||
<string name="decrypt_result_not_encrypted">"Not Encrypted"</string>
|
<string name="decrypt_result_not_encrypted">"Not Encrypted"</string>
|
||||||
<string name="decrypt_result_action_show">"Show"</string>
|
<string name="decrypt_result_action_show">"Show"</string>
|
||||||
<string name="decrypt_result_action_Lookup">"Lookup"</string>
|
<string name="decrypt_result_action_Lookup">"Lookup"</string>
|
||||||
|
<string name="decrypt_invalid_text">"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?"</string>
|
||||||
|
<string name="decrypt_invalid_button">"I understand the risks, display it!"</string>
|
||||||
|
|
||||||
<!-- Add keys -->
|
<!-- Add keys -->
|
||||||
<string name="add_keys_section_secure_exchange">"Exchange"</string>
|
<string name="add_keys_section_secure_exchange">"Exchange"</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user