diff options
Diffstat (limited to 'OpenKeychain/src')
2 files changed, 87 insertions, 75 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 0218b457b..1bc47fa7c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -187,9 +187,9 @@ public class ProviderHelper {                  KeyRings.PUBKEY_DATA              }, KeyRings.HAS_ANY_SECRET + " = 1", null, null); -        LongSparseArray<WrappedPublicKey> result = -                new LongSparseArray<WrappedPublicKey>(cursor.getCount());          try { +            LongSparseArray<WrappedPublicKey> result = new LongSparseArray<WrappedPublicKey>(); +              if (cursor != null && cursor.moveToFirst()) do {                  long masterKeyId = cursor.getLong(0);                  boolean hasAnySecret = cursor.getInt(1) > 0; @@ -200,13 +200,15 @@ public class ProviderHelper {                              new WrappedPublicKeyRing(blob, hasAnySecret, verified).getSubkey());                  }              } while (cursor.moveToNext()); + +            return result; +          } finally {              if (cursor != null) {                  cursor.close();              }          } -        return result;      }      public CachedPublicKeyRing getCachedPublicKeyRing(Uri queryUri) { @@ -260,32 +262,18 @@ public class ProviderHelper {          }      } -    public SaveKeyringResult savePublicKeyRing(UncachedKeyRing keyRing) { -        return savePublicKeyRing(keyRing, new Progressable() { -            @Override -            public void setProgress(String message, int current, int total) { -                return; -            } - -            @Override -            public void setProgress(int resourceId, int current, int total) { -                return; -            } - -            @Override -            public void setProgress(int current, int total) { -                return; -            } -        }); -    } -    /** -     * Saves PGPPublicKeyRing with its keys and userIds in DB +    /** Saves an UncachedKeyRing of the public variant into the db. +     * +     * This method will not delete all previous data for this masterKeyId from the database prior +     * to inserting. All public data is effectively re-inserted, secret keyrings are left deleted +     * and need to be saved externally to be preserved past the operation.       */      @SuppressWarnings("unchecked") -    public SaveKeyringResult savePublicKeyRing(UncachedKeyRing keyRing, Progressable progress) { +    private int internalSavePublicKeyRing(UncachedKeyRing keyRing, +                Progressable progress, boolean selfCertsAreTrusted) {          if (keyRing.isSecret()) {              log(LogLevel.ERROR, LogType.MSG_IP_BAD_TYPE_SECRET); -            return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); +            return SaveKeyringResult.RESULT_ERROR;          }          // start with ok result @@ -299,21 +287,11 @@ public class ProviderHelper {          // Canonicalize this key, to assert a number of assumptions made about it.          keyRing = keyRing.canonicalize(mLog, mIndent);          if (keyRing == null) { -            return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); +            return SaveKeyringResult.RESULT_ERROR;          }          UncachedPublicKey masterKey = keyRing.getPublicKey(); -        // IF there is a secret key, preserve it! -        UncachedKeyRing secretRing; -        try { -            secretRing = getWrappedSecretKeyRing(masterKeyId).getUncached(); -            log(LogLevel.DEBUG, LogType.MSG_IP_PRESERVING_SECRET); -            progress.setProgress(LogType.MSG_IP_PRESERVING_SECRET.getMsgId(), 30, 100); -        } catch (NotFoundException e) { -            secretRing = null; -        } -          ArrayList<ContentProviderOperation> operations;          try { @@ -331,7 +309,7 @@ public class ProviderHelper {                      values.put(KeyRingData.KEY_RING_DATA, keyRing.getEncoded());                  } catch (IOException e) {                      log(LogLevel.ERROR, LogType.MSG_IP_ENCODE_FAIL); -                    return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); +                    return SaveKeyringResult.RESULT_ERROR;                  }                  Uri uri = KeyRingData.buildPublicKeyRingUri(Long.toString(masterKeyId)); @@ -500,7 +478,7 @@ public class ProviderHelper {              }              mIndent -= 1; -            progress.setProgress(LogType.MSG_IP_UID_REORDER.getMsgId(), 80, 100); +            progress.setProgress(LogType.MSG_IP_UID_REORDER.getMsgId(), 65, 100);              log(LogLevel.DEBUG, LogType.MSG_IP_UID_REORDER);              // primary before regular before revoked (see UserIdItem.compareTo)              // this is a stable sort, so the order of keys is otherwise preserved. @@ -511,7 +489,7 @@ public class ProviderHelper {                  operations.add(buildUserIdOperations(masterKeyId, item, userIdRank));                  if (item.selfCert != null) {                      operations.add(buildCertOperations(masterKeyId, userIdRank, item.selfCert, -                            secretRing != null ? Certs.VERIFIED_SECRET : Certs.VERIFIED_SELF)); +                            selfCertsAreTrusted ? Certs.VERIFIED_SECRET : Certs.VERIFIED_SELF));                  }                  // don't bother with trusted certs if the uid is revoked, anyways                  if (item.isRevoked) { @@ -529,7 +507,7 @@ public class ProviderHelper {              log(LogLevel.ERROR, LogType.MSG_IP_FAIL_IO_EXC);              Log.e(Constants.TAG, "IOException during import", e);              mIndent -= 1; -            return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); +            return SaveKeyringResult.RESULT_ERROR;          }          try { @@ -544,33 +522,24 @@ public class ProviderHelper {              }              log(LogLevel.DEBUG, LogType.MSG_IP_APPLY_BATCH); -            progress.setProgress(LogType.MSG_IP_APPLY_BATCH.getMsgId(), 90, 100); +            progress.setProgress(LogType.MSG_IP_APPLY_BATCH.getMsgId(), 75, 100);              mContentResolver.applyBatch(KeychainContract.CONTENT_AUTHORITY, operations); -            // Save the saved keyring (if any) -            if (secretRing != null) { -                log(LogLevel.DEBUG, LogType.MSG_IP_REINSERT_SECRET); -                mIndent += 1; -                saveSecretKeyRing(secretRing); -                result |= SaveKeyringResult.SAVED_SECRET; -                mIndent -= 1; -            } - -            mIndent -= 1;              log(LogLevel.OK, LogType.MSG_IP_SUCCESS); -            progress.setProgress(LogType.MSG_IP_SUCCESS.getMsgId(), 100, 100); -            return new SaveKeyringResult(result, mLog); +            mIndent -= 1; +            progress.setProgress(LogType.MSG_IP_SUCCESS.getMsgId(), 90, 100); +            return result;          } catch (RemoteException e) {              log(LogLevel.ERROR, LogType.MSG_IP_FAIL_REMOTE_EX);              Log.e(Constants.TAG, "RemoteException during import", e);              mIndent -= 1; -            return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); +            return SaveKeyringResult.RESULT_ERROR;          } catch (OperationApplicationException e) {              log(LogLevel.ERROR, LogType.MSG_IP_FAIL_OP_EX);              Log.e(Constants.TAG, "OperationApplicationException during import", e);              mIndent -= 1; -            return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); +            return SaveKeyringResult.RESULT_ERROR;          }      } @@ -596,30 +565,27 @@ public class ProviderHelper {          }      } -    /** -     * Saves a PGPSecretKeyRing in the DB. This will only work if a corresponding public keyring -     * is already in the database! -     * -     * TODO allow adding secret keys where no public key exists (ie, consolidate keys) +    /** Saves an UncachedKeyRing of the secret variant into the db. +     * This method will fail if no corresponding public keyring is in the database!       */ -    public SaveKeyringResult saveSecretKeyRing(UncachedKeyRing keyRing) { +    private SaveKeyringResult internalSaveSecretKeyRing(UncachedKeyRing keyRing) {          if (!keyRing.isSecret()) {              log(LogLevel.ERROR, LogType.MSG_IS_BAD_TYPE_PUBLIC);              return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog);          } +        long masterKeyId = keyRing.getMasterKeyId(); +        log(LogLevel.START, LogType.MSG_IS, +                new String[]{ PgpKeyHelper.convertKeyIdToHex(masterKeyId) }); +        mIndent += 1; +          // Canonicalize this key, to assert a number of assumptions made about it.          keyRing = keyRing.canonicalize(mLog, mIndent);          if (keyRing == null) {              return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog);          } -        long masterKeyId = keyRing.getMasterKeyId(); -        log(LogLevel.START, LogType.MSG_IS, -                new String[]{ PgpKeyHelper.convertKeyIdToHex(masterKeyId) }); -        mIndent += 1; -          // IF this is successful, it's a secret key          int result = SaveKeyringResult.SAVED_SECRET; @@ -685,18 +651,67 @@ public class ProviderHelper {      } + +    public SaveKeyringResult savePublicKeyRing(UncachedKeyRing keyRing) { +        return savePublicKeyRing(keyRing, new Progressable() { +            @Override +            public void setProgress(String message, int current, int total) { +            } + +            @Override +            public void setProgress(int resourceId, int current, int total) { +            } + +            @Override +            public void setProgress(int current, int total) { +            } +        }); +    } + +    public SaveKeyringResult savePublicKeyRing(UncachedKeyRing keyRing, Progressable progress) { + +        // IF there is a secret key, preserve it! +        UncachedKeyRing secretRing; +        try { +            secretRing = getWrappedSecretKeyRing(keyRing.getMasterKeyId()).getUncached(); +            log(LogLevel.DEBUG, LogType.MSG_IP_PRESERVING_SECRET); +            progress.setProgress(LogType.MSG_IP_PRESERVING_SECRET.getMsgId(), 10, 100); +        } catch (NotFoundException e) { +            secretRing = null; +        } + +        int result = internalSavePublicKeyRing(keyRing, progress, secretRing != null); + +        // Save the saved keyring (if any) +        if (secretRing != null) { +            log(LogLevel.DEBUG, LogType.MSG_IP_REINSERT_SECRET); +            progress.setProgress(LogType.MSG_IP_REINSERT_SECRET.getMsgId(), 90, 100); +            mIndent += 1; +            internalSaveSecretKeyRing(secretRing); +            result |= SaveKeyringResult.SAVED_SECRET; +            mIndent -= 1; +        } + +        return new SaveKeyringResult(result, mLog); + +    } + +    public SaveKeyringResult saveSecretKeyRing(UncachedKeyRing keyRing) { +        return internalSaveSecretKeyRing(keyRing); +    } +      /**       * Saves (or updates) a pair of public and secret KeyRings in the database       */ -    public void saveKeyRing(UncachedKeyRing pubRing, UncachedKeyRing secRing) throws IOException { -        long masterKeyId = pubRing.getPublicKey().getKeyId(); +    public void savePairedKeyRing(UncachedKeyRing pubRing, UncachedKeyRing secRing) throws IOException { +        long masterKeyId = pubRing.getMasterKeyId();          // delete secret keyring (so it isn't unnecessarily saved by public-savePublicKeyRing below)          mContentResolver.delete(KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId)), null, null);          // save public keyring -        savePublicKeyRing(pubRing); -        saveSecretKeyRing(secRing); +        internalSavePublicKeyRing(pubRing, null, true); +        internalSaveSecretKeyRing(secRing);      }      /** @@ -812,9 +827,6 @@ public class ProviderHelper {      /**       * Must be an uri pointing to an account -     * -     * @param uri -     * @return       */      public AppSettings getApiAppSettings(Uri uri) {          AppSettings settings = null; 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 3ddcdfcf4..e30d48ce5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -524,13 +524,13 @@ public class KeychainIntentService extends IntentService                          PgpKeyOperation.Pair<UncachedKeyRing,UncachedKeyRing> pair =                                  keyOperations.buildSecretKey(seckey, pubkey, saveParcel); // edit existing                          setProgress(R.string.progress_saving_key_ring, 90, 100); -                        providerHelper.saveKeyRing(pair.first, pair.second); +                        providerHelper.savePairedKeyRing(pair.first, pair.second);                      } catch (ProviderHelper.NotFoundException e) {                          PgpKeyOperation.Pair<UncachedKeyRing,UncachedKeyRing> pair =                                  keyOperations.buildNewSecretKey(saveParcel); //new Keyring                          // save the pair                          setProgress(R.string.progress_saving_key_ring, 90, 100); -                        providerHelper.saveKeyRing(pair.first, pair.second); +                        providerHelper.savePairedKeyRing(pair.first, pair.second);                      }                      setProgress(R.string.progress_done, 100, 100);  | 
