From 3bffe4da559d0ee45c44df1afee6d5b4de9b89d1 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 18 Jun 2014 20:55:44 +0200 Subject: generate public keyring from secret if not available --- .../keychain/pgp/UncachedKeyRing.java | 16 ++++++++++ .../keychain/provider/ProviderHelper.java | 36 +++++++++++----------- .../keychain/service/OperationResultParcel.java | 5 +-- OpenKeychain/src/main/res/values/strings.xml | 3 +- extern/spongycastle | 2 +- 5 files changed, 40 insertions(+), 22 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index a1c6b158b..e1ce62bdf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -27,6 +27,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.ArrayList; import java.util.Comparator; import java.util.Date; import java.util.HashSet; @@ -759,6 +760,21 @@ public class UncachedKeyRing { } + public UncachedKeyRing extractPublicKeyRing() { + if(!isSecret()) { + throw new RuntimeException("Tried to extract public keyring from non-secret keyring. " + + "This is a programming error and should never happen!"); + } + + ArrayList keys = new ArrayList(); + Iterator it = mRing.getPublicKeys(); + while (it.hasNext()) { + keys.add(it.next()); + } + + return new UncachedKeyRing(new PGPPublicKeyRing(keys)); + } + /** This method replaces a public key in a keyring. * * This method essentially wraps PGP*KeyRing.insertPublicKey, where the keyring may be of either 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 79bd5777c..955fb90ba 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -804,37 +804,37 @@ public class ProviderHelper { } // Merge new data into public keyring as well, if there is any + UncachedKeyRing publicRing; try { UncachedKeyRing oldPublicRing = getWrappedPublicKeyRing(masterKeyId).getUncached(); // Merge data from new public ring into secret one - UncachedKeyRing publicRing = oldPublicRing.merge(secretRing, mLog, mIndent); + publicRing = oldPublicRing.merge(secretRing, mLog, mIndent); if (publicRing == null) { return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); } - // If anything changed, reinsert + // If nothing changed, never mind if (Arrays.hashCode(publicRing.getEncoded()) - != Arrays.hashCode(oldPublicRing.getEncoded())) { - - log(LogLevel.OK, LogType.MSG_IS, - new String[]{ PgpKeyHelper.convertKeyIdToHex(masterKeyId) }); - - publicRing = publicRing.canonicalize(mLog, mIndent); - if (publicRing == null) { - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); - } + == Arrays.hashCode(oldPublicRing.getEncoded())) { + publicRing = null; + } - int result = internalSavePublicKeyRing(publicRing, progress, true); - if ((result & SaveKeyringResult.RESULT_ERROR) == SaveKeyringResult.RESULT_ERROR) { - return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); - } + } catch (NotFoundException e) { + log(LogLevel.DEBUG, LogType.MSG_IS_PUBRING_GENERATE, null); + publicRing = secretRing.extractPublicKeyRing(); + } + if (publicRing != null) { + publicRing = publicRing.canonicalize(mLog, mIndent); + if (publicRing == null) { + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); } - } catch (NotFoundException e) { - // TODO, this WILL error out later because secret rings cannot be inserted without - // public ones + int result = internalSavePublicKeyRing(publicRing, progress, true); + if ((result & SaveKeyringResult.RESULT_ERROR) == SaveKeyringResult.RESULT_ERROR) { + return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog); + } } progress.setProgress(LogType.MSG_IP_REINSERT_SECRET.getMsgId(), 90, 100); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index 48eb39a39..cfb977911 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -174,13 +174,14 @@ public class OperationResultParcel implements Parcelable { MSG_IS(R.string.msg_is), MSG_IS_BAD_TYPE_PUBLIC (R.string.msg_is_bad_type_public), MSG_IS_DB_EXCEPTION (R.string.msg_is_db_exception), - MSG_IS_IMPORTING_SUBKEYS (R.string.msg_is_importing_subkeys), MSG_IS_FAIL_IO_EXC (R.string.msg_is_io_exc), + MSG_IS_IMPORTING_SUBKEYS (R.string.msg_is_importing_subkeys), + MSG_IS_PUBRING_GENERATE (R.string.msg_is_pubring_generate), MSG_IS_SUBKEY_NONEXISTENT (R.string.msg_is_subkey_nonexistent), MSG_IS_SUBKEY_OK (R.string.msg_is_subkey_ok), MSG_IS_SUBKEY_STRIPPED (R.string.msg_is_subkey_stripped), - MSG_IS_SUCCESS (R.string.msg_is_success), MSG_IS_SUCCESS_IDENTICAL (R.string.msg_is_success_identical), + MSG_IS_SUCCESS (R.string.msg_is_success), // keyring canonicalization MSG_KC_PUBLIC (R.string.msg_kc_public), diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index ed9093194..6b921b681 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -553,11 +553,12 @@ Database error! Processing secret subkeys Error encoding keyring + Generating public keyring from secret keyring Subkey %s unavailable in public key Marked %s as available Marked %s as stripped - Successfully imported secret keyring Keyring contains no new data, nothing to do + Successfully imported secret keyring Canonicalizing public keyring %s diff --git a/extern/spongycastle b/extern/spongycastle index 2c47e5fca..09d85b7d7 160000 --- a/extern/spongycastle +++ b/extern/spongycastle @@ -1 +1 @@ -Subproject commit 2c47e5fca2a820a4fd584066871bed993f1c3919 +Subproject commit 09d85b7d7a64b3003210d065c4210ff7fb7a8c6d -- cgit v1.2.3