aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp
diff options
context:
space:
mode:
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java9
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpCertifyOperation.java149
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java1
4 files changed, 158 insertions, 5 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;