Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 837aa704 authored by Vincent Breitmoser's avatar Vincent Breitmoser
Browse files

messageview: match signature user id with sender address

parent 2e9184f8
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.util.Log;
import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.crypto.MessageDecryptVerifier;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Body;
import com.fsck.k9.mail.BodyPart;
import com.fsck.k9.mail.Flag;
@@ -214,6 +215,7 @@ public class MessageCryptoHelper {

                    @Override
                    public void onError(Exception e) {
                        // TODO actually handle (hand to ui, offer retry?)
                        Log.e(K9.LOG_TAG, "Couldn't connect to OpenPgpService", e);
                    }
                });
@@ -232,6 +234,10 @@ public class MessageCryptoHelper {

    private void decryptVerify(Intent intent) {
        intent.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY);
        Address[] from = currentMessage.getFrom();
        if (from.length > 0) {
            intent.putExtra(OpenPgpApi.EXTRA_SENDER_ADDRESS, from[0].getAddress());
        }

        try {
            CryptoPartType cryptoPartType = currentCryptoPart.type;
+34 −17
Original line number Diff line number Diff line
@@ -227,10 +227,11 @@ public enum MessageCryptoDisplayStatus {
            CryptoResultAnnotation encapsulatedResult = cryptoResult.getEncapsulatedResult();
            if (encapsulatedResult.isOpenPgpResult()) {
                signatureResult = encapsulatedResult.getOpenPgpSignatureResult();
                if (signatureResult == null) {
                    throw new AssertionError("OpenPGP must contain signature result at this point!");
                }
            }
        }

        // TODO handle mismatched user id

        switch (decryptionResult.getResult()) {
            case OpenPgpDecryptionResult.RESULT_NOT_ENCRYPTED:
@@ -253,11 +254,19 @@ public enum MessageCryptoDisplayStatus {
            case OpenPgpSignatureResult.RESULT_NO_SIGNATURE:
                return ENCRYPTED_UNSIGNED;

            case OpenPgpSignatureResult.RESULT_VALID_CONFIRMED:
            case OpenPgpSignatureResult.RESULT_VALID_KEY_CONFIRMED:
            case OpenPgpSignatureResult.RESULT_VALID_KEY_UNCONFIRMED:
                switch (signatureResult.getSenderResult()) {
                    case OpenPgpSignatureResult.SENDER_RESULT_UID_CONFIRMED:
                        return ENCRYPTED_SIGN_VERIFIED;

            case OpenPgpSignatureResult.RESULT_VALID_UNCONFIRMED:
                    case OpenPgpSignatureResult.SENDER_RESULT_UID_UNCONFIRMED:
                        return ENCRYPTED_SIGN_UNVERIFIED;
                    case OpenPgpSignatureResult.SENDER_RESULT_UID_MISSING:
                        return ENCRYPTED_SIGN_MISMATCH;
                    case OpenPgpSignatureResult.SENDER_RESULT_NO_SENDER:
                        return ENCRYPTED_SIGN_UNVERIFIED;
                }
                throw new IllegalStateException("unhandled encrypted result case!");

            case OpenPgpSignatureResult.RESULT_KEY_MISSING:
                return ENCRYPTED_SIGN_UNKNOWN;
@@ -271,11 +280,11 @@ public enum MessageCryptoDisplayStatus {
            case OpenPgpSignatureResult.RESULT_INVALID_KEY_REVOKED:
                return ENCRYPTED_SIGN_REVOKED;

            case OpenPgpSignatureResult.RESULT_INVALID_INSECURE:
            case OpenPgpSignatureResult.RESULT_INVALID_KEY_INSECURE:
                return ENCRYPTED_SIGN_INSECURE;

            default:
                throw new AssertionError("all cases must be handled, this is a bug!");
                throw new IllegalStateException("unhandled encrypted result case!");
        }
    }

@@ -285,11 +294,19 @@ public enum MessageCryptoDisplayStatus {
            case OpenPgpSignatureResult.RESULT_NO_SIGNATURE:
                return DISABLED;

            case OpenPgpSignatureResult.RESULT_VALID_CONFIRMED:
            case OpenPgpSignatureResult.RESULT_VALID_KEY_CONFIRMED:
            case OpenPgpSignatureResult.RESULT_VALID_KEY_UNCONFIRMED:
                switch (signatureResult.getSenderResult()) {
                    case OpenPgpSignatureResult.SENDER_RESULT_UID_CONFIRMED:
                        return UNENCRYPTED_SIGN_VERIFIED;

            case OpenPgpSignatureResult.RESULT_VALID_UNCONFIRMED:
                    case OpenPgpSignatureResult.SENDER_RESULT_UID_UNCONFIRMED:
                        return UNENCRYPTED_SIGN_UNVERIFIED;
                    case OpenPgpSignatureResult.SENDER_RESULT_UID_MISSING:
                        return UNENCRYPTED_SIGN_MISMATCH;
                    case OpenPgpSignatureResult.SENDER_RESULT_NO_SENDER:
                        return UNENCRYPTED_SIGN_UNVERIFIED;
                }
                throw new IllegalStateException("unhandled encrypted result case!");

            case OpenPgpSignatureResult.RESULT_KEY_MISSING:
                return UNENCRYPTED_SIGN_UNKNOWN;
@@ -303,11 +320,11 @@ public enum MessageCryptoDisplayStatus {
            case OpenPgpSignatureResult.RESULT_INVALID_KEY_REVOKED:
                return UNENCRYPTED_SIGN_REVOKED;

            case OpenPgpSignatureResult.RESULT_INVALID_INSECURE:
            case OpenPgpSignatureResult.RESULT_INVALID_KEY_INSECURE:
                return UNENCRYPTED_SIGN_INSECURE;

            default:
                throw new AssertionError("all cases must be handled, this is a bug!");
                throw new IllegalStateException("unhandled encrypted result case!");
        }
    }

+95 −63
Original line number Diff line number Diff line
@@ -16,107 +16,115 @@

package org.openintents.openpgp;


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import android.os.Parcel;
import android.os.Parcelable;

import org.openintents.openpgp.util.OpenPgpUtils;

import java.util.ArrayList;

@SuppressWarnings("unused")
public class OpenPgpSignatureResult implements Parcelable {
    /**
     * Since there might be a case where new versions of the client using the library getting
     * old versions of the protocol (and thus old versions of this class), we need a versioning
     * system for the parcels sent between the clients and the providers.
     */
    public static final int PARCELABLE_VERSION = 2;
    public static final int PARCELABLE_VERSION = 3;

    // content not signed
    public static final int RESULT_NO_SIGNATURE = -1;
    // invalid signature!
    public static final int RESULT_INVALID_SIGNATURE = 0;
    // successfully verified signature, with confirmed key
    @Deprecated
    public static final int RESULT_VALID_CONFIRMED = 1;
    public static final int RESULT_VALID_KEY_CONFIRMED = 1;
    // no key was found for this signature verification
    public static final int RESULT_KEY_MISSING = 2;
    // successfully verified signature, but with unconfirmed key
    @Deprecated
    public static final int RESULT_VALID_UNCONFIRMED = 3;
    public static final int RESULT_VALID_KEY_UNCONFIRMED = 3;
    // key has been revoked -> invalid signature!
    public static final int RESULT_INVALID_KEY_REVOKED = 4;
    // key is expired -> invalid signature!
    public static final int RESULT_INVALID_KEY_EXPIRED = 5;
    // insecure cryptographic algorithms/protocol -> invalid signature!
    @Deprecated
    public static final int RESULT_INVALID_INSECURE = 6;
    public static final int RESULT_INVALID_KEY_INSECURE = 6;

    public static final int SENDER_RESULT_NO_SENDER = 0;
    public static final int SENDER_RESULT_UID_CONFIRMED = 1;
    public static final int SENDER_RESULT_UID_UNCONFIRMED = 2;
    public static final int SENDER_RESULT_UID_MISSING = 3;

    private final int result;
    private final long keyId;
    private final String primaryUserId;
    private final ArrayList<String> userIds;
    private final ArrayList<String> confirmedUserIds;
    private final int senderResult;

    private OpenPgpSignatureResult(int signatureStatus, String signatureUserId, long keyId,
            ArrayList<String> userIds, ArrayList<String> confirmedUserIds, int senderResult, Boolean signatureOnly) {
        this.result = signatureStatus;
        this.primaryUserId = signatureUserId;
        this.keyId = keyId;
        this.userIds = userIds;
        this.confirmedUserIds = confirmedUserIds;
        this.senderResult = senderResult;
    }

    int result;
    boolean signatureOnly;
    String primaryUserId;
    ArrayList<String> userIds;
    long keyId;
    private OpenPgpSignatureResult(Parcel source, int version) {
        this.result = source.readInt();
        // we dropped support for signatureOnly, but need to skip the value for compatibility
        source.readByte();
        this.primaryUserId = source.readString();
        this.keyId = source.readLong();

    public int getResult() {
        return result;
        if (version > 1) {
            this.userIds = source.createStringArrayList();
        } else {
            this.userIds = null;
        }
        if (version > 2) {
            this.senderResult = source.readInt();
            this.confirmedUserIds = source.createStringArrayList();
        } else {
            this.senderResult = SENDER_RESULT_NO_SENDER;
            this.confirmedUserIds = null;
        }

    public void setResult(int result) {
        this.result = result;
    }

    /** @deprecated This information should be obtained from OpenPgpDecryptionResult! */
    public boolean isSignatureOnly() {
        return signatureOnly;
    public int getResult() {
        return result;
    }

    /** @deprecated This information should be obtained from OpenPgpDecryptionResult! */
    public void setSignatureOnly(boolean signatureOnly) {
        this.signatureOnly = signatureOnly;
    public int getSenderResult() {
        return senderResult;
    }

    public String getPrimaryUserId() {
        return primaryUserId;
    }

    public void setPrimaryUserId(String primaryUserId) {
        this.primaryUserId = primaryUserId;
    public List<String> getUserIds() {
        return Collections.unmodifiableList(userIds);
    }

    public ArrayList<String> getUserIds() {
        return userIds;
    }

    public void setUserIds(ArrayList<String> userIds) {
        this.userIds = userIds;
    public List<String> getConfirmedUserIds() {
        return Collections.unmodifiableList(confirmedUserIds);
    }

    public long getKeyId() {
        return keyId;
    }

    public void setKeyId(long keyId) {
        this.keyId = keyId;
    }

    public OpenPgpSignatureResult() {

    }

    public OpenPgpSignatureResult(int signatureStatus, String signatureUserId,
                                  boolean signatureOnly, long keyId, ArrayList<String> userIds) {
        this.result = signatureStatus;
        this.signatureOnly = signatureOnly;
        this.primaryUserId = signatureUserId;
        this.keyId = keyId;
        this.userIds = userIds;
    }

    public OpenPgpSignatureResult(OpenPgpSignatureResult b) {
        this.result = b.result;
        this.primaryUserId = b.primaryUserId;
        this.signatureOnly = b.signatureOnly;
        this.keyId = b.keyId;
        this.userIds = b.userIds;
    }

    public int describeContents() {
        return 0;
    }
@@ -134,11 +142,15 @@ public class OpenPgpSignatureResult implements Parcelable {
        int startPosition = dest.dataPosition();
        // version 1
        dest.writeInt(result);
        dest.writeByte((byte) (signatureOnly ? 1 : 0));
        // this is deprecated since version 3. we pass a dummy value for compatibility
        dest.writeByte((byte) 0);
        dest.writeString(primaryUserId);
        dest.writeLong(keyId);
        // version 2
        dest.writeStringList(userIds);
        // version 3
        dest.writeInt(senderResult);
        dest.writeStringList(confirmedUserIds);
        // Go back and write the size
        int parcelableSize = dest.dataPosition() - startPosition;
        dest.setDataPosition(sizePosition);
@@ -148,17 +160,11 @@ public class OpenPgpSignatureResult implements Parcelable {

    public static final Creator<OpenPgpSignatureResult> CREATOR = new Creator<OpenPgpSignatureResult>() {
        public OpenPgpSignatureResult createFromParcel(final Parcel source) {
            source.readInt(); // parcelableVersion
            int version = source.readInt(); // parcelableVersion
            int parcelableSize = source.readInt();
            int startPosition = source.dataPosition();

            OpenPgpSignatureResult vr = new OpenPgpSignatureResult();
            vr.result = source.readInt();
            vr.signatureOnly = source.readByte() == 1;
            vr.primaryUserId = source.readString();
            vr.keyId = source.readLong();
            vr.userIds = new ArrayList<String>();
            source.readStringList(vr.userIds);
            OpenPgpSignatureResult vr = new OpenPgpSignatureResult(source, version);

            // skip over all fields added in future versions of this parcel
            source.setDataPosition(startPosition + parcelableSize);
@@ -176,9 +182,35 @@ public class OpenPgpSignatureResult implements Parcelable {
        String out = "\nresult: " + result;
        out += "\nprimaryUserId: " + primaryUserId;
        out += "\nuserIds: " + userIds;
        out += "\nsignatureOnly: " + signatureOnly;
        out += "\nkeyId: " + OpenPgpUtils.convertKeyIdToHex(keyId);
        return out;
    }

    public static OpenPgpSignatureResult createWithValidSignature(int signatureStatus, String primaryUserId,
            long keyId, ArrayList<String> userIds, ArrayList<String> confirmedUserIds, int senderStatus) {
        if (signatureStatus == RESULT_NO_SIGNATURE || signatureStatus == RESULT_KEY_MISSING ||
                signatureStatus == RESULT_INVALID_SIGNATURE) {
            throw new IllegalArgumentException("can only use this method for valid types of signatures");
        }
        return new OpenPgpSignatureResult(
                signatureStatus, primaryUserId, keyId, userIds, confirmedUserIds, senderStatus, null);
    }

    public static OpenPgpSignatureResult createWithNoSignature() {
        return new OpenPgpSignatureResult(RESULT_NO_SIGNATURE, null, 0L, null, null, 0, null);
    }

    public static OpenPgpSignatureResult createWithKeyMissing(long keyId) {
        return new OpenPgpSignatureResult(RESULT_KEY_MISSING, null, keyId, null, null, 0, null);
    }

    public static OpenPgpSignatureResult createWithInvalidSignature() {
        return new OpenPgpSignatureResult(RESULT_INVALID_SIGNATURE, null, 0L, null, null, 0, null);
    }

    @Deprecated
    public OpenPgpSignatureResult withSignatureOnlyFlag(boolean signatureOnly) {
        return new OpenPgpSignatureResult(
                result, primaryUserId, keyId, userIds, confirmedUserIds, senderResult, signatureOnly);
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -261,6 +261,7 @@ public class OpenPgpApi {
    public static final String EXTRA_DETACHED_SIGNATURE = "detached_signature";
    public static final String EXTRA_PROGRESS_MESSENGER = "progress_messenger";
    public static final String EXTRA_DATA_LENGTH = "data_length";
    public static final String EXTRA_SENDER_ADDRESS = "sender_address";
    public static final String RESULT_SIGNATURE = "signature";
    public static final String RESULT_DECRYPTION = "decryption";
    public static final String RESULT_METADATA = "metadata";