diff options
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java')
-rw-r--r-- | OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java | 247 |
1 files changed, 227 insertions, 20 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java index 3d98034d2..284c17e7a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java @@ -24,9 +24,12 @@ import android.graphics.PorterDuff; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.style.ForegroundColorSpan; +import android.view.View; import android.widget.ImageView; import android.widget.TextView; +import org.openintents.openpgp.OpenPgpDecryptionResult; +import org.openintents.openpgp.OpenPgpSignatureResult; import org.spongycastle.asn1.ASN1ObjectIdentifier; import org.spongycastle.asn1.nist.NISTNamedCurves; import org.spongycastle.asn1.teletrust.TeleTrusTNamedCurves; @@ -34,6 +37,8 @@ import org.spongycastle.bcpg.PublicKeyAlgorithmTags; import org.spongycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; +import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Curve; import org.sufficientlysecure.keychain.util.Log; @@ -218,14 +223,11 @@ public class KeyFormattingUtils { public static String convertFingerprintToHex(byte[] fingerprint) { // NOTE: Even though v3 keys are not imported we need to support both fingerprints for // display/comparison before import - // Also better cut of unneeded parts, e.g., for fingerprints returned from YubiKeys - if (fingerprint.length < 20) { - // v3 key fingerprint with 128 bit (MD5) - return Hex.toHexString(fingerprint, 0, 16).toLowerCase(Locale.ENGLISH); - } else { - // v4 key fingerprint with 160 bit (SHA1) - return Hex.toHexString(fingerprint, 0, 20).toLowerCase(Locale.ENGLISH); + if (fingerprint.length != 16 && fingerprint.length != 20) { + throw new IllegalArgumentException("No valid v3 or v4 fingerprint!"); } + + return Hex.toHexString(fingerprint).toLowerCase(Locale.ENGLISH); } public static long getKeyIdFromFingerprint(byte[] fingerprint) { @@ -383,7 +385,6 @@ public class KeyFormattingUtils { /** * Converts the given bytes to a unique RGB color using SHA1 algorithm * - * @param bytes * @return an integer array containing 3 numeric color representations (Red, Green, Black) * @throws java.security.NoSuchAlgorithmException * @throws java.security.DigestException @@ -401,7 +402,7 @@ public class KeyFormattingUtils { public static final int DEFAULT_COLOR = -1; - public static enum State { + public enum State { REVOKED, EXPIRED, VERIFIED, @@ -411,7 +412,8 @@ public class KeyFormattingUtils { UNVERIFIED, UNKNOWN_KEY, INVALID, - NOT_SIGNED + NOT_SIGNED, + INSECURE } public static void setStatusImage(Context context, ImageView statusIcon, State state) { @@ -427,9 +429,196 @@ public class KeyFormattingUtils { setStatusImage(context, statusIcon, statusText, state, color, false); } + public interface StatusHolder { + ImageView getEncryptionStatusIcon(); + TextView getEncryptionStatusText(); + + ImageView getSignatureStatusIcon(); + TextView getSignatureStatusText(); + + View getSignatureLayout(); + TextView getSignatureUserName(); + TextView getSignatureUserEmail(); + TextView getSignatureAction(); + + boolean hasEncrypt(); + + } + + @SuppressWarnings("deprecation") // context.getDrawable is api lvl 21, need to use deprecated + public static void setStatus(Context context, StatusHolder holder, DecryptVerifyResult result) { + + if (holder.hasEncrypt()) { + OpenPgpDecryptionResult decryptionResult = result.getDecryptionResult(); + + int encText, encIcon, encColor; + + switch (decryptionResult.getResult()) { + case OpenPgpDecryptionResult.RESULT_ENCRYPTED: { + encText = R.string.decrypt_result_encrypted; + encIcon = R.drawable.status_lock_closed_24dp; + encColor = R.color.key_flag_green; + break; + } + + case OpenPgpDecryptionResult.RESULT_INSECURE: { + encText = R.string.decrypt_result_insecure; + encIcon = R.drawable.status_signature_invalid_cutout_24dp; + encColor = R.color.key_flag_red; + break; + } + + default: + case OpenPgpDecryptionResult.RESULT_NOT_ENCRYPTED: { + encText = R.string.decrypt_result_not_encrypted; + encIcon = R.drawable.status_lock_open_24dp; + encColor = R.color.key_flag_red; + break; + } + } + + int encColorRes = context.getResources().getColor(encColor); + holder.getEncryptionStatusIcon().setColorFilter(encColorRes, PorterDuff.Mode.SRC_IN); + holder.getEncryptionStatusIcon().setImageDrawable(context.getResources().getDrawable(encIcon)); + holder.getEncryptionStatusText().setText(encText); + holder.getEncryptionStatusText().setTextColor(encColorRes); + } + + OpenPgpSignatureResult signatureResult = result.getSignatureResult(); + + int sigText, sigIcon, sigColor; + int sigActionText, sigActionIcon; + + switch (signatureResult.getResult()) { + + case OpenPgpSignatureResult.RESULT_NO_SIGNATURE: { + // no signature + + sigText = R.string.decrypt_result_no_signature; + sigIcon = R.drawable.status_signature_invalid_cutout_24dp; + sigColor = R.color.key_flag_gray; + + // won't be used, but makes compiler happy + sigActionText = 0; + sigActionIcon = 0; + break; + } + + case OpenPgpSignatureResult.RESULT_VALID_CONFIRMED: { + sigText = R.string.decrypt_result_signature_certified; + sigIcon = R.drawable.status_signature_verified_cutout_24dp; + sigColor = R.color.key_flag_green; + + sigActionText = R.string.decrypt_result_action_show; + sigActionIcon = R.drawable.ic_vpn_key_grey_24dp; + break; + } + + case OpenPgpSignatureResult.RESULT_VALID_UNCONFIRMED: { + sigText = R.string.decrypt_result_signature_uncertified; + sigIcon = R.drawable.status_signature_unverified_cutout_24dp; + sigColor = R.color.key_flag_orange; + + sigActionText = R.string.decrypt_result_action_show; + sigActionIcon = R.drawable.ic_vpn_key_grey_24dp; + break; + } + + case OpenPgpSignatureResult.RESULT_INVALID_KEY_REVOKED: { + sigText = R.string.decrypt_result_signature_revoked_key; + sigIcon = R.drawable.status_signature_revoked_cutout_24dp; + sigColor = R.color.key_flag_red; + + sigActionText = R.string.decrypt_result_action_show; + sigActionIcon = R.drawable.ic_vpn_key_grey_24dp; + break; + } + + case OpenPgpSignatureResult.RESULT_INVALID_KEY_EXPIRED: { + sigText = R.string.decrypt_result_signature_expired_key; + sigIcon = R.drawable.status_signature_expired_cutout_24dp; + sigColor = R.color.key_flag_red; + + sigActionText = R.string.decrypt_result_action_show; + sigActionIcon = R.drawable.ic_vpn_key_grey_24dp; + break; + } + + case OpenPgpSignatureResult.RESULT_KEY_MISSING: { + sigText = R.string.decrypt_result_signature_missing_key; + sigIcon = R.drawable.status_signature_unknown_cutout_24dp; + sigColor = R.color.key_flag_red; + + sigActionText = R.string.decrypt_result_action_Lookup; + sigActionIcon = R.drawable.ic_file_download_grey_24dp; + break; + } + + case OpenPgpSignatureResult.RESULT_INVALID_INSECURE: { + sigText = R.string.decrypt_result_insecure_cryptography; + sigIcon = R.drawable.status_signature_invalid_cutout_24dp; + sigColor = R.color.key_flag_red; + + sigActionText = R.string.decrypt_result_action_show; + sigActionIcon = R.drawable.ic_vpn_key_grey_24dp; + break; + } + + default: + case OpenPgpSignatureResult.RESULT_INVALID_SIGNATURE: { + sigText = R.string.decrypt_result_invalid_signature; + sigIcon = R.drawable.status_signature_invalid_cutout_24dp; + sigColor = R.color.key_flag_red; + + sigActionText = R.string.decrypt_result_action_show; + sigActionIcon = R.drawable.ic_vpn_key_grey_24dp; + break; + } + + } + + int sigColorRes = context.getResources().getColor(sigColor); + holder.getSignatureStatusIcon().setColorFilter(sigColorRes, PorterDuff.Mode.SRC_IN); + holder.getSignatureStatusIcon().setImageDrawable(context.getResources().getDrawable(sigIcon)); + holder.getSignatureStatusText().setText(sigText); + holder.getSignatureStatusText().setTextColor(sigColorRes); + + if (signatureResult.getResult() != OpenPgpSignatureResult.RESULT_NO_SIGNATURE) { + // has a signature, thus display layouts + + holder.getSignatureLayout().setVisibility(View.VISIBLE); + + holder.getSignatureAction().setText(sigActionText); + holder.getSignatureAction().setCompoundDrawablesWithIntrinsicBounds( + 0, 0, sigActionIcon, 0); + + String userId = result.getSignatureResult().getPrimaryUserId(); + KeyRing.UserId userIdSplit = KeyRing.splitUserId(userId); + if (userIdSplit.name != null) { + holder.getSignatureUserName().setText(userIdSplit.name); + } else { + holder.getSignatureUserName().setText(R.string.user_id_no_name); + } + if (userIdSplit.email != null) { + holder.getSignatureUserEmail().setVisibility(View.VISIBLE); + holder.getSignatureUserEmail().setText(userIdSplit.email); + } else { + holder.getSignatureUserEmail().setVisibility(View.GONE); + } + + } else { + + holder.getSignatureLayout().setVisibility(View.GONE); + + } + + + } + /** * Sets status image based on constant */ + @SuppressWarnings("deprecation") // context.getDrawable is api lvl 21 public static void setStatusImage(Context context, ImageView statusIcon, TextView statusText, State state, int color, boolean big) { switch (state) { @@ -443,7 +632,7 @@ public class KeyFormattingUtils { context.getResources().getDrawable(R.drawable.status_signature_verified_cutout_24dp)); } if (color == KeyFormattingUtils.DEFAULT_COLOR) { - color = R.color.android_green_light; + color = R.color.key_flag_green; } statusIcon.setColorFilter(context.getResources().getColor(color), PorterDuff.Mode.SRC_IN); @@ -456,7 +645,7 @@ public class KeyFormattingUtils { statusIcon.setImageDrawable( context.getResources().getDrawable(R.drawable.status_lock_closed_24dp)); if (color == KeyFormattingUtils.DEFAULT_COLOR) { - color = R.color.android_green_light; + color = R.color.key_flag_green; } statusIcon.setColorFilter(context.getResources().getColor(color), PorterDuff.Mode.SRC_IN); @@ -475,7 +664,7 @@ public class KeyFormattingUtils { context.getResources().getDrawable(R.drawable.status_signature_unverified_cutout_24dp)); } if (color == KeyFormattingUtils.DEFAULT_COLOR) { - color = R.color.android_orange_light; + color = R.color.key_flag_orange; } statusIcon.setColorFilter(context.getResources().getColor(color), PorterDuff.Mode.SRC_IN); @@ -488,7 +677,7 @@ public class KeyFormattingUtils { statusIcon.setImageDrawable( context.getResources().getDrawable(R.drawable.status_signature_unknown_cutout_24dp)); if (color == KeyFormattingUtils.DEFAULT_COLOR) { - color = R.color.android_red_light; + color = R.color.key_flag_red; } statusIcon.setColorFilter(context.getResources().getColor(color), PorterDuff.Mode.SRC_IN); @@ -507,7 +696,7 @@ public class KeyFormattingUtils { context.getResources().getDrawable(R.drawable.status_signature_revoked_cutout_24dp)); } if (color == KeyFormattingUtils.DEFAULT_COLOR) { - color = R.color.android_red_light; + color = R.color.key_flag_red; } statusIcon.setColorFilter(context.getResources().getColor(color), PorterDuff.Mode.SRC_IN); @@ -525,7 +714,25 @@ public class KeyFormattingUtils { context.getResources().getDrawable(R.drawable.status_signature_expired_cutout_24dp)); } if (color == KeyFormattingUtils.DEFAULT_COLOR) { - color = R.color.android_red_light; + color = R.color.key_flag_red; + } + statusIcon.setColorFilter(context.getResources().getColor(color), + PorterDuff.Mode.SRC_IN); + if (statusText != null) { + statusText.setTextColor(context.getResources().getColor(color)); + } + break; + } + case INSECURE: { + if (big) { + statusIcon.setImageDrawable( + context.getResources().getDrawable(R.drawable.status_signature_invalid_cutout_96dp)); + } else { + statusIcon.setImageDrawable( + context.getResources().getDrawable(R.drawable.status_signature_invalid_cutout_24dp)); + } + if (color == KeyFormattingUtils.DEFAULT_COLOR) { + color = R.color.key_flag_red; } statusIcon.setColorFilter(context.getResources().getColor(color), PorterDuff.Mode.SRC_IN); @@ -538,7 +745,7 @@ public class KeyFormattingUtils { statusIcon.setImageDrawable( context.getResources().getDrawable(R.drawable.status_lock_open_24dp)); if (color == KeyFormattingUtils.DEFAULT_COLOR) { - color = R.color.android_red_light; + color = R.color.key_flag_red; } statusIcon.setColorFilter(context.getResources().getColor(color), PorterDuff.Mode.SRC_IN); @@ -551,7 +758,7 @@ public class KeyFormattingUtils { statusIcon.setImageDrawable( context.getResources().getDrawable(R.drawable.status_signature_unknown_cutout_24dp)); if (color == KeyFormattingUtils.DEFAULT_COLOR) { - color = R.color.android_red_light; + color = R.color.key_flag_red; } statusIcon.setColorFilter(context.getResources().getColor(color), PorterDuff.Mode.SRC_IN); @@ -564,7 +771,7 @@ public class KeyFormattingUtils { statusIcon.setImageDrawable( context.getResources().getDrawable(R.drawable.status_signature_invalid_cutout_24dp)); if (color == KeyFormattingUtils.DEFAULT_COLOR) { - color = R.color.android_red_light; + color = R.color.key_flag_red; } statusIcon.setColorFilter(context.getResources().getColor(color), PorterDuff.Mode.SRC_IN); @@ -578,7 +785,7 @@ public class KeyFormattingUtils { statusIcon.setImageDrawable( context.getResources().getDrawable(R.drawable.status_signature_invalid_cutout_24dp)); if (color == KeyFormattingUtils.DEFAULT_COLOR) { - color = R.color.bg_gray; + color = R.color.key_flag_gray; } statusIcon.setColorFilter(context.getResources().getColor(color), PorterDuff.Mode.SRC_IN); |