diff options
Diffstat (limited to 'OpenKeychain')
10 files changed, 389 insertions, 43 deletions
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 f43cbbeef..905cae17e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java @@ -51,6 +51,10 @@ public abstract class CanonicalizedKeyRing extends KeyRing {          return mVerified;      } +    public byte[] getFingerprint() { +        return getRing().getPublicKey().getFingerprint(); +    } +      public String getPrimaryUserId() throws PgpGeneralException {          return getPublicKey().getPrimaryUserId();      } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java index bec07ce21..595f37872 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java @@ -278,13 +278,12 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {       * Certify the given pubkeyid with the given masterkeyid.       *       * @param publicKeyRing Keyring to add certification to. -     * @param userIds       User IDs to certify, must not be null or empty +     * @param userIds       User IDs to certify, or all if null       * @return A keyring with added certifications       */      public UncachedKeyRing certifyUserIds(CanonicalizedPublicKeyRing publicKeyRing, List<String> userIds,                                            byte[] nfcSignedHash, Date nfcCreationTimestamp) -            throws PgpGeneralMsgIdException, NoSuchAlgorithmException, NoSuchProviderException, -            PGPException, SignatureException { +            throws PGPException {          if (mPrivateKeyState == PRIVATE_KEY_STATE_LOCKED) {              throw new PrivateKeyNotUnlockedException();          } @@ -314,7 +313,9 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {          PGPPublicKey publicKey = publicKeyRing.getPublicKey().getPublicKey();          // fetch public key ring, add the certification and return it -        for (String userId : new IterableIterator<String>(userIds.iterator())) { +        Iterable<String> it = userIds != null ? userIds +                : new IterableIterator<String>(publicKey.getUserIDs()); +        for (String userId : it) {              PGPSignature sig = signatureGenerator.generateCertification(userId, publicKey);              publicKey = PGPPublicKey.addCertification(publicKey, userId, sig);          } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpCertifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpCertifyOperation.java new file mode 100644 index 000000000..ffa2181e1 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpCertifyOperation.java @@ -0,0 +1,149 @@ +package org.sufficientlysecure.keychain.pgp; + +import android.content.Context; + +import org.spongycastle.openpgp.PGPException; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException; +import org.sufficientlysecure.keychain.service.CertifyActionsParcel; +import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction; +import org.sufficientlysecure.keychain.service.results.CertifyResult; +import org.sufficientlysecure.keychain.service.results.EditKeyResult; +import org.sufficientlysecure.keychain.service.results.OperationResult.LogType; +import org.sufficientlysecure.keychain.service.results.OperationResult.OperationLog; +import org.sufficientlysecure.keychain.service.results.SaveKeyringResult; +import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; +import org.sufficientlysecure.keychain.util.Log; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.concurrent.atomic.AtomicBoolean; + +public class PgpCertifyOperation { + +    private AtomicBoolean mCancelled; + +    private ProviderHelper mProviderHelper; + +    public PgpCertifyOperation(ProviderHelper providerHelper, AtomicBoolean cancelled) { +        mProviderHelper = providerHelper; + +        mCancelled = cancelled; +    } + +    private boolean checkCancelled() { +        return mCancelled != null && mCancelled.get(); +    } + +    public CertifyResult certify(CertifyActionsParcel parcel, String passphrase) { + +        OperationLog log = new OperationLog(); +        log.add(LogType.MSG_CRT, 0); + +        // Retrieve and unlock secret key +        CanonicalizedSecretKey certificationKey; +        try { +            log.add(LogType.MSG_CRT_MASTER_FETCH, 1); +            CanonicalizedSecretKeyRing secretKeyRing = +                    mProviderHelper.getCanonicalizedSecretKeyRing(parcel.mMasterKeyId); +            log.add(LogType.MSG_CRT_UNLOCK, 1); +            certificationKey = secretKeyRing.getSecretKey(); +            if (!certificationKey.unlock(passphrase)) { +                log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2); +                return new CertifyResult(CertifyResult.RESULT_ERROR, log); +            } +        } catch (PgpGeneralException e) { +            log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2); +            return new CertifyResult(CertifyResult.RESULT_ERROR, log); +        } catch (NotFoundException e) { +            log.add(LogType.MSG_CRT_ERROR_MASTER_NOT_FOUND, 2); +            return new CertifyResult(CertifyResult.RESULT_ERROR, log); +        } + +        ArrayList<UncachedKeyRing> certifiedKeys = new ArrayList<UncachedKeyRing>(); + +        log.add(LogType.MSG_CRT_CERTIFYING, 1); + +        int certifyOk = 0, certifyError = 0; + +        // Work through all requested certifications +        for (CertifyAction action : parcel.mCertifyActions) { + +            // Check if we were cancelled +            if (checkCancelled()) { +                log.add(LogType.MSG_OPERATION_CANCELLED, 0); +                return new CertifyResult(CertifyResult.RESULT_CANCELLED, log); +            } + +            try { + +                if (action.mUserIds == null) { +                    log.add(LogType.MSG_CRT_CERTIFY_ALL, 2, +                            KeyFormattingUtils.convertKeyIdToHex(action.mMasterKeyId)); +                } else { +                    log.add(LogType.MSG_CRT_CERTIFY_SOME, 2, action.mUserIds.size(), +                            KeyFormattingUtils.convertKeyIdToHex(action.mMasterKeyId)); +                } + +                CanonicalizedPublicKeyRing publicRing = +                        mProviderHelper.getCanonicalizedPublicKeyRing(action.mMasterKeyId); +                if ( ! Arrays.equals(publicRing.getFingerprint(), action.mFingerprint)) { +                    log.add(LogType.MSG_CRT_FP_MISMATCH, 3); +                    certifyError += 1; +                    continue; +                } + +                UncachedKeyRing certifiedKey = certificationKey.certifyUserIds(publicRing, action.mUserIds, null, null); +                certifiedKeys.add(certifiedKey); + +            } catch (NotFoundException e) { +                certifyError += 1; +                log.add(LogType.MSG_CRT_WARN_NOT_FOUND, 3); +            } catch (PGPException e) { +                certifyError += 1; +                log.add(LogType.MSG_CRT_WARN_CERT_FAILED, 3); +                Log.e(Constants.TAG, "Encountered PGPException during certification", e); +            } + +        } + +        log.add(LogType.MSG_CRT_SAVING, 1); + +        // Check if we were cancelled +        if (checkCancelled()) { +            log.add(LogType.MSG_OPERATION_CANCELLED, 0); +            return new CertifyResult(CertifyResult.RESULT_CANCELLED, log); +        } + +        // Write all certified keys into the database +        for (UncachedKeyRing certifiedKey : certifiedKeys) { + +            // Check if we were cancelled +            if (checkCancelled()) { +                log.add(LogType.MSG_OPERATION_CANCELLED, 0); +                return new CertifyResult(CertifyResult.RESULT_CANCELLED, log, certifyOk, certifyError); +            } + +            log.add(LogType.MSG_CRT_SAVE, 2, +                    KeyFormattingUtils.convertKeyIdToHex(certifiedKey.getMasterKeyId())); +            // store the signed key in our local cache +            SaveKeyringResult result = mProviderHelper.savePublicKeyRing(certifiedKey); + +            if (result.success()) { +                certifyOk += 1; +            } else { +                log.add(LogType.MSG_CRT_WARN_SAVE_FAILED, 3); +            } + +            // TODO do something with import results + +        } + +        log.add(LogType.MSG_CRT_SUCCESS, 0); +        return new CertifyResult(CertifyResult.RESULT_OK, log, certifyOk, certifyError); + +    } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java index dd0549adc..c3320ed6a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java @@ -38,7 +38,6 @@ import org.sufficientlysecure.keychain.service.results.OperationResult.Operation  import org.sufficientlysecure.keychain.service.results.ImportKeyResult;  import org.sufficientlysecure.keychain.service.results.SaveKeyringResult;  import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; -import org.sufficientlysecure.keychain.util.IterableIterator;  import org.sufficientlysecure.keychain.util.Log;  import org.sufficientlysecure.keychain.util.ProgressScaler; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java new file mode 100644 index 000000000..d2562d728 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> + * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.service; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.io.Serializable; +import java.util.ArrayList; + +/** + * This class is a a transferable representation for a number of keyrings to + * be certified. + */ +public class CertifyActionsParcel implements Parcelable { + +    // the master key id to certify with +    final public long mMasterKeyId; +    public CertifyLevel mLevel; + +    public ArrayList<CertifyAction> mCertifyActions = new ArrayList<CertifyAction>(); + +    public CertifyActionsParcel(long masterKeyId) { +        mMasterKeyId = masterKeyId; +        mLevel = CertifyLevel.DEFAULT; +    } + +    public CertifyActionsParcel(Parcel source) { +        mMasterKeyId = source.readLong(); +        // just like parcelables, this is meant for ad-hoc IPC only and is NOT portable! +        mLevel = CertifyLevel.values()[source.readInt()]; + +        mCertifyActions = (ArrayList<CertifyAction>) source.readSerializable(); +    } + +    public void add(CertifyAction action) { +        mCertifyActions.add(action); +    } + +    @Override +    public void writeToParcel(Parcel destination, int flags) { +        destination.writeLong(mMasterKeyId); +        destination.writeInt(mLevel.ordinal()); + +        destination.writeSerializable(mCertifyActions); +    } + +    public static final Creator<CertifyActionsParcel> CREATOR = new Creator<CertifyActionsParcel>() { +        public CertifyActionsParcel createFromParcel(final Parcel source) { +            return new CertifyActionsParcel(source); +        } + +        public CertifyActionsParcel[] newArray(final int size) { +            return new CertifyActionsParcel[size]; +        } +    }; + +    // TODO make this parcelable +    public static class CertifyAction implements Serializable { +        final public long mMasterKeyId; +        final public byte[] mFingerprint; + +        final public ArrayList<String> mUserIds; + +        public CertifyAction(long masterKeyId, byte[] fingerprint) { +            this(masterKeyId, fingerprint, null); +        } + +        public CertifyAction(long masterKeyId, byte[] fingerprint, ArrayList<String> userIds) { +            mMasterKeyId = masterKeyId; +            mFingerprint = fingerprint; +            mUserIds = userIds; +        } +    } + +    @Override +    public int describeContents() { +        return 0; +    } + +    @Override +    public String toString() { +        String out = "mMasterKeyId: " + mMasterKeyId + "\n"; +        out += "mLevel: " + mLevel + "\n"; +        out += "mCertifyActions: " + mCertifyActions + "\n"; + +        return out; +    } + +    // All supported algorithms +    public enum CertifyLevel { +        DEFAULT, NONE, CASUAL, POSITIVE +    } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index c131430cf..f5e6dedc2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -29,7 +29,9 @@ import android.os.RemoteException;  import org.sufficientlysecure.keychain.Constants;  import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.PgpCertifyOperation;  import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException; +import org.sufficientlysecure.keychain.service.results.CertifyResult;  import org.sufficientlysecure.keychain.util.FileHelper;  import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;  import org.sufficientlysecure.keychain.util.Preferences; @@ -39,7 +41,6 @@ import org.sufficientlysecure.keychain.keyimport.KeybaseKeyserver;  import org.sufficientlysecure.keychain.keyimport.Keyserver;  import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;  import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; -import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;  import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;  import org.sufficientlysecure.keychain.pgp.PassphraseCacheInterface;  import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; @@ -80,7 +81,6 @@ import java.io.OutputStream;  import java.util.ArrayList;  import java.util.Date;  import java.util.Iterator; -import java.util.List;  import java.util.concurrent.atomic.AtomicBoolean;  /** @@ -183,10 +183,8 @@ public class KeychainIntentService extends IntentService implements Progressable      public static final String DOWNLOAD_KEY_SERVER = "query_key_server";      public static final String DOWNLOAD_KEY_LIST = "query_key_id"; -    // sign key -    public static final String CERTIFY_KEY_MASTER_KEY_ID = "sign_key_master_key_id"; -    public static final String CERTIFY_KEY_PUB_KEY_ID = "sign_key_pub_key_id"; -    public static final String CERTIFY_KEY_UIDS = "sign_key_uids"; +    // certify key +    public static final String CERTIFY_PARCEL = "certify_parcel";      // consolidate      public static final String CONSOLIDATE_RECOVERY = "consolidate_recovery"; @@ -258,30 +256,21 @@ public class KeychainIntentService extends IntentService implements Progressable              try {                  /* Input */ -                long masterKeyId = data.getLong(CERTIFY_KEY_MASTER_KEY_ID); -                long pubKeyId = data.getLong(CERTIFY_KEY_PUB_KEY_ID); -                ArrayList<String> userIds = data.getStringArrayList(CERTIFY_KEY_UIDS); +                CertifyActionsParcel parcel = data.getParcelable(CERTIFY_PARCEL);                  /* Operation */ -                String signaturePassphrase = PassphraseCacheService.getCachedPassphrase(this, -                        masterKeyId, masterKeyId); -                if (signaturePassphrase == null) { +                String passphrase = PassphraseCacheService.getCachedPassphrase(this, +                        // certification is always with the master key id, so use that one +                        parcel.mMasterKeyId, parcel.mMasterKeyId); +                if (passphrase == null) {                      throw new PgpGeneralException("Unable to obtain passphrase");                  }                  ProviderHelper providerHelper = new ProviderHelper(this); -                CanonicalizedPublicKeyRing publicRing = providerHelper.getCanonicalizedPublicKeyRing(pubKeyId); -                CanonicalizedSecretKeyRing secretKeyRing = providerHelper.getCanonicalizedSecretKeyRing(masterKeyId); -                CanonicalizedSecretKey certificationKey = secretKeyRing.getSecretKey(); -                if (!certificationKey.unlock(signaturePassphrase)) { -                    throw new PgpGeneralException("Error extracting key (bad passphrase?)"); -                } -                // TODO: supply nfc stuff -                UncachedKeyRing newRing = certificationKey.certifyUserIds(publicRing, userIds, null, null); +                PgpCertifyOperation op = new PgpCertifyOperation(providerHelper, mActionCanceled); +                CertifyResult result = op.certify(parcel, passphrase); -                // store the signed key in our local cache -                providerHelper.savePublicKeyRing(newRing); -                sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY); +                sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result);              } catch (Exception e) {                  sendErrorToHandler(e); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/CertifyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/CertifyResult.java new file mode 100644 index 000000000..cf54238ec --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/CertifyResult.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> + * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.service.results; + +import android.os.Parcel; + +public class CertifyResult extends OperationResult { + +    int mCertifyOk, mCertifyError; + +    public CertifyResult(int result, OperationLog log) { +        super(result, log); +    } + +    public CertifyResult(int result, OperationLog log, int certifyOk, int certifyError) { +        this(result, log); +        mCertifyOk = certifyOk; +        mCertifyError = certifyError; +    } + +    /** Construct from a parcel - trivial because we have no extra data. */ +    public CertifyResult(Parcel source) { +        super(source); +    } + +    @Override +    public void writeToParcel(Parcel dest, int flags) { +        super.writeToParcel(dest, flags); +    } + +    public static Creator<CertifyResult> CREATOR = new Creator<CertifyResult>() { +        public CertifyResult createFromParcel(final Parcel source) { +            return new CertifyResult(source); +        } + +        public CertifyResult[] newArray(final int size) { +            return new CertifyResult[size]; +        } +    }; + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/OperationResult.java index 29924ee5d..90e1d0037 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/OperationResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/OperationResult.java @@ -517,8 +517,23 @@ public abstract class OperationResult implements Parcelable {          MSG_SE_SIGCRYPTING (LogLevel.DEBUG, R.string.msg_se_sigcrypting),          MSG_SE_SYMMETRIC (LogLevel.INFO, R.string.msg_se_symmetric), -        MSG_CRT_UPLOAD_SUCCESS (LogLevel.OK, R.string.msg_crt_upload_success), +        MSG_CRT_CERTIFYING (LogLevel.DEBUG, R.string.msg_crt_certifying), +        MSG_CRT_CERTIFY_ALL (LogLevel.DEBUG, R.string.msg_crt_certify_all), +        MSG_CRT_CERTIFY_SOME (LogLevel.DEBUG, R.plurals.msg_crt_certify_some), +        MSG_CRT_ERROR_MASTER_NOT_FOUND (LogLevel.ERROR, R.string.msg_crt_error_master_not_found), +        MSG_CRT_ERROR_UNLOCK (LogLevel.ERROR, R.string.msg_crt_error_unlock), +        MSG_CRT_FP_MISMATCH (LogLevel.WARN, R.string.msg_crt_fp_mismatch), +        MSG_CRT (LogLevel.START, R.string.msg_crt), +        MSG_CRT_MASTER_FETCH (LogLevel.DEBUG, R.string.msg_crt_master_fetch), +        MSG_CRT_SAVE (LogLevel.DEBUG, R.string.msg_crt_save), +        MSG_CRT_SAVING (LogLevel.DEBUG, R.string.msg_crt_saving),          MSG_CRT_SUCCESS (LogLevel.OK, R.string.msg_crt_success), +        MSG_CRT_UNLOCK (LogLevel.DEBUG, R.string.msg_crt_unlock), +        MSG_CRT_WARN_NOT_FOUND (LogLevel.WARN, R.string.msg_crt_warn_not_found), +        MSG_CRT_WARN_CERT_FAILED (LogLevel.WARN, R.string.msg_crt_warn_cert_failed), +        MSG_CRT_WARN_SAVE_FAILED (LogLevel.WARN, R.string.msg_crt_warn_save_failed), + +        MSG_CRT_UPLOAD_SUCCESS (LogLevel.OK, R.string.msg_crt_upload_success),          MSG_ACC_SAVED (LogLevel.INFO, R.string.api_settings_save_msg), diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java index 5eec8454a..685581be7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java @@ -48,6 +48,10 @@ import android.widget.TextView;  import org.sufficientlysecure.keychain.Constants;  import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.service.CertifyActionsParcel; +import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction; +import org.sufficientlysecure.keychain.service.results.CertifyResult; +import org.sufficientlysecure.keychain.service.results.SingletonResult;  import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;  import org.sufficientlysecure.keychain.util.Preferences;  import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; @@ -55,9 +59,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;  import org.sufficientlysecure.keychain.service.KeychainIntentService;  import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;  import org.sufficientlysecure.keychain.service.PassphraseCacheService; -import org.sufficientlysecure.keychain.service.results.OperationResult.LogLevel;  import org.sufficientlysecure.keychain.service.results.OperationResult.LogType; -import org.sufficientlysecure.keychain.service.results.SingletonResult;  import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter;  import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;  import org.sufficientlysecure.keychain.ui.widget.CertifyKeySpinner; @@ -83,6 +85,7 @@ public class CertifyKeyFragment extends LoaderFragment      private Uri mDataUri;      private long mPubKeyId = Constants.key.none; +    private byte[] mPubFingerprint;      private long mMasterKeyId = Constants.key.none;      private UserIdsAdapter mUserIdsAdapter; @@ -243,8 +246,8 @@ public class CertifyKeyFragment extends LoaderFragment                      String mainUserId = data.getString(INDEX_USER_ID);                      mInfoPrimaryUserId.setText(mainUserId); -                    byte[] fingerprintBlob = data.getBlob(INDEX_FINGERPRINT); -                    String fingerprint = KeyFormattingUtils.convertFingerprintToHex(fingerprintBlob); +                    mPubFingerprint = data.getBlob(INDEX_FINGERPRINT); +                    String fingerprint = KeyFormattingUtils.convertFingerprintToHex(mPubFingerprint);                      mInfoFingerprint.setText(KeyFormattingUtils.colorizeFingerprint(fingerprint));                  }                  break; @@ -312,27 +315,27 @@ public class CertifyKeyFragment extends LoaderFragment          intent.setAction(KeychainIntentService.ACTION_CERTIFY_KEYRING);          // fill values for this action -        Bundle data = new Bundle(); - -        data.putLong(KeychainIntentService.CERTIFY_KEY_MASTER_KEY_ID, mMasterKeyId); -        data.putLong(KeychainIntentService.CERTIFY_KEY_PUB_KEY_ID, mPubKeyId); -        data.putStringArrayList(KeychainIntentService.CERTIFY_KEY_UIDS, userIds); +        CertifyActionsParcel parcel = new CertifyActionsParcel(mMasterKeyId); +        parcel.add(new CertifyAction(mPubKeyId, mPubFingerprint, userIds)); +        Bundle data = new Bundle(); +        data.putParcelable(KeychainIntentService.CERTIFY_PARCEL, parcel);          intent.putExtra(KeychainIntentService.EXTRA_DATA, data);          // Message is received after signing is done in KeychainIntentService          KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(mActivity, -                getString(R.string.progress_certifying), ProgressDialog.STYLE_SPINNER) { +                getString(R.string.progress_certifying), ProgressDialog.STYLE_SPINNER, true) {              public void handleMessage(Message message) {                  // handle messages by standard KeychainIntentServiceHandler first                  super.handleMessage(message);                  if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { -                    SingletonResult result = new SingletonResult( -                            SingletonResult.RESULT_OK, LogType.MSG_CRT_SUCCESS); +                    Bundle data = message.getData(); +                    CertifyResult result = data.getParcelable(CertifyResult.EXTRA_RESULT); +                      Intent intent = new Intent(); -                    intent.putExtra(SingletonResult.EXTRA_RESULT, result); +                    intent.putExtra(CertifyResult.EXTRA_RESULT, result);                      mActivity.setResult(CertifyKeyActivity.RESULT_OK, intent);                      // check if we need to send the key to the server or not diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 9f5d3f535..28933ac89 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -875,8 +875,26 @@      <string name="msg_se">"Starting sign and/or encrypt operation"</string>      <string name="msg_se_symmetric">"Preparing symmetric encryption"</string> -    <string name="msg_crt_upload_success">"Successfully uploaded key to server"</string> +    <string name="msg_crt_certifying">"Generating certifications"</string> +    <string name="msg_crt_certify_all">"Certifying all user ids for key %s"</string> +    <plurals name="msg_crt_certify_some"> +        <item quantity="one">"Certifying one user id for key %2$s"</item> +        <item quantity="other">"Certifying %1$d user ids for key %2$s"</item> +    </plurals> +    <string name="msg_crt_error_master_not_found">"Master key not found!"</string> +    <string name="msg_crt_error_unlock">"Error unlocking master key!"</string> +    <string name="msg_crt_fp_mismatch">"Fingerprint mismatch, not certifying!"</string> +    <string name="msg_crt">"Certifying keyrings"</string> +    <string name="msg_crt_master_fetch">"Fetching certifying master key"</string> +    <string name="msg_crt_save">"Saving certified key %s"</string> +    <string name="msg_crt_saving">"Saving keyrings"</string> +    <string name="msg_crt_unlock">"Unlocking master key"</string>      <string name="msg_crt_success">"Successfully certified identities"</string> +    <string name="msg_crt_warn_not_found">"Key not found!"</string> +    <string name="msg_crt_warn_cert_failed">"Certificate generation failed!"</string> +    <string name="msg_crt_warn_save_failed">"Save operation failed!"</string> + +    <string name="msg_crt_upload_success">"Successfully uploaded key to server"</string>      <string name="msg_acc_saved">"Account saved"</string>  | 
