From 97b2178a29db00258d90d59d6c05a517afc4124f Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 28 Sep 2015 17:41:11 +0200 Subject: upload: re-add upload by bytes --- .../keychain/operations/CertifyOperation.java | 22 +++---------- .../keychain/operations/EditKeyOperation.java | 27 ++++++++-------- .../keychain/operations/UploadOperation.java | 33 +++++++++++++++---- .../keychain/pgp/UncachedKeyRing.java | 37 +++++++++++----------- .../keychain/service/UploadKeyringParcel.java | 22 +++++++++++-- .../keychain/ui/BackupActivity.java | 1 + 6 files changed, 83 insertions(+), 59 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java index d97acd77c..e1daac874 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java @@ -45,6 +45,7 @@ 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.ContactSyncAdapterService; +import org.sufficientlysecure.keychain.service.UploadKeyringParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.NfcSignOperationsBuilder; @@ -205,23 +206,9 @@ public class CertifyOperation extends BaseOperation { } // these variables are used inside the following loop, but they need to be created only once - HkpKeyserver keyServer = null; UploadOperation uploadOperation = null; - Proxy proxy = null; if (parcel.keyServerUri != null) { - keyServer = new HkpKeyserver(parcel.keyServerUri); uploadOperation = new UploadOperation(mContext, mProviderHelper, mProgressable); - if (cryptoInput.getParcelableProxy() == null) { - // explicit proxy not set - if (!OrbotHelper.isOrbotInRequiredState(mContext)) { - return new CertifyResult(null, - RequiredInputParcel.createOrbotRequiredOperation(), cryptoInput); - } - proxy = Preferences.getPreferences(mContext).getProxyPrefs() - .parcelableProxy.getProxy(); - } else { - proxy = cryptoInput.getParcelableProxy().getProxy(); - } } // Write all certified keys into the database @@ -241,10 +228,9 @@ public class CertifyOperation extends BaseOperation { SaveKeyringResult result = mProviderHelper.savePublicKeyRing(certifiedKey); if (uploadOperation != null) { - UploadResult uploadResult = uploadOperation.uploadKeyRingToServer( - keyServer, - certifiedKey, - proxy); + UploadKeyringParcel uploadInput = + new UploadKeyringParcel(parcel.keyServerUri, certifiedKey.getMasterKeyId()); + UploadResult uploadResult = uploadOperation.execute(uploadInput, cryptoInput); log.add(uploadResult, 2); if (uploadResult.success()) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java index 2e9fa9bc2..cf8928768 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java @@ -134,27 +134,18 @@ public class EditKeyOperation extends BaseOperation { // It's a success, so this must be non-null now UncachedKeyRing ring = modifyResult.getRing(); - // Save the new keyring. - SaveKeyringResult saveResult = mProviderHelper - .saveSecretKeyRing(ring, new ProgressScaler(mProgressable, 60, 95, 100)); - log.add(saveResult, 1); - - // If the save operation didn't succeed, exit here - if (!saveResult.success()) { - return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); - } - if (saveParcel.isUpload()) { - UncachedKeyRing publicKeyRing; + byte[] keyringBytes; try { - publicKeyRing = ring.extractPublicKeyRing(); + UncachedKeyRing publicKeyRing = ring.extractPublicKeyRing(); + keyringBytes = publicKeyRing.getEncoded(); } catch (IOException e) { log.add(LogType.MSG_ED_ERROR_EXTRACTING_PUBLIC_UPLOAD, 1); return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); } UploadKeyringParcel exportKeyringParcel = - new UploadKeyringParcel(saveParcel.getUploadKeyserver(), ring.getMasterKeyId()); + new UploadKeyringParcel(saveParcel.getUploadKeyserver(), keyringBytes); UploadResult uploadResult = new UploadOperation(mContext, mProviderHelper, mProgressable) @@ -173,6 +164,16 @@ public class EditKeyOperation extends BaseOperation { } } + // Save the new keyring. + SaveKeyringResult saveResult = mProviderHelper + .saveSecretKeyRing(ring, new ProgressScaler(mProgressable, 60, 95, 100)); + log.add(saveResult, 1); + + // If the save operation didn't succeed, exit here + if (!saveResult.success()) { + return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); + } + // There is a new passphrase - cache it if (saveParcel.mNewUnlock != null && cryptoInput.mCachePassphrase) { log.add(LogType.MSG_ED_CACHING_NEW, 1); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/UploadOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/UploadOperation.java index ec4602703..499f592cf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/UploadOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/UploadOperation.java @@ -36,9 +36,11 @@ import org.sufficientlysecure.keychain.keyimport.Keyserver.AddKeyException; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.UploadResult; +import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.UploadKeyringParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; @@ -71,7 +73,7 @@ public class UploadOperation extends BaseOperation { } @NonNull - public UploadResult execute(UploadKeyringParcel exportInput, CryptoInputParcel cryptoInput) { + public UploadResult execute(UploadKeyringParcel uploadInput, CryptoInputParcel cryptoInput) { Proxy proxy; if (cryptoInput.getParcelableProxy() == null) { // explicit proxy not set @@ -83,18 +85,37 @@ public class UploadOperation extends BaseOperation { proxy = cryptoInput.getParcelableProxy().getProxy(); } - HkpKeyserver hkpKeyserver = new HkpKeyserver(exportInput.mKeyserver); + HkpKeyserver hkpKeyserver = new HkpKeyserver(uploadInput.mKeyserver); try { - CanonicalizedPublicKeyRing keyring = mProviderHelper.getCanonicalizedPublicKeyRing( - exportInput.mMasterKeyId); - return uploadKeyRingToServer(hkpKeyserver, keyring.getUncachedKeyRing(), proxy); + CanonicalizedPublicKeyRing keyring; + if (uploadInput.mMasterKeyId != null) { + keyring = mProviderHelper.getCanonicalizedPublicKeyRing( + uploadInput.mMasterKeyId); + } else if (uploadInput.mUncachedKeyringBytes != null) { + CanonicalizedKeyRing canonicalizedRing = + UncachedKeyRing.decodeFromData(uploadInput.mUncachedKeyringBytes) + .canonicalize(new OperationLog(), 0, true); + if ( ! CanonicalizedPublicKeyRing.class.isInstance(canonicalizedRing)) { + throw new AssertionError("keyring bytes must contain public key ring!"); + } + keyring = (CanonicalizedPublicKeyRing) canonicalizedRing; + } else { + throw new AssertionError("key id or bytes must be non-null!"); + } + return uploadKeyRingToServer(hkpKeyserver, keyring, proxy); } catch (ProviderHelper.NotFoundException e) { Log.e(Constants.TAG, "error uploading key", e); return new UploadResult(UploadResult.RESULT_ERROR, new OperationLog()); + } catch (IOException e) { + e.printStackTrace(); + return new UploadResult(UploadResult.RESULT_ERROR, new OperationLog()); + } catch (PgpGeneralException e) { + e.printStackTrace(); + return new UploadResult(UploadResult.RESULT_ERROR, new OperationLog()); } } - public UploadResult uploadKeyRingToServer(HkpKeyserver server, UncachedKeyRing keyring, Proxy proxy) { + UploadResult uploadKeyRingToServer(HkpKeyserver server, CanonicalizedPublicKeyRing keyring, Proxy proxy) { mProgressable.setProgress(R.string.progress_uploading, 0, 1); 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 ca98882d8..5acf6dd41 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -18,6 +18,23 @@ package org.sufficientlysecure.keychain.pgp; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Comparator; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.TimeZone; +import java.util.TreeSet; + import org.spongycastle.bcpg.ArmoredOutputStream; import org.spongycastle.bcpg.PublicKeyAlgorithmTags; import org.spongycastle.bcpg.SignatureSubpacketTags; @@ -43,23 +60,6 @@ import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Utf8Util; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Comparator; -import java.util.Date; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; -import java.util.TimeZone; -import java.util.TreeSet; - /** Wrapper around PGPKeyRing class, to be constructed from bytes. * * This class and its relatives UncachedPublicKey and UncachedSecretKey are @@ -78,8 +78,7 @@ import java.util.TreeSet; * @see org.sufficientlysecure.keychain.pgp.UncachedSecretKey * */ -@SuppressWarnings("unchecked") -public class UncachedKeyRing implements Serializable { +public class UncachedKeyRing { final PGPKeyRing mRing; final boolean mIsSecret; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/UploadKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/UploadKeyringParcel.java index 724792b70..0a14f3dc6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/UploadKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/UploadKeyringParcel.java @@ -26,16 +26,26 @@ import android.os.Parcelable; public class UploadKeyringParcel implements Parcelable { public String mKeyserver; - public long mMasterKeyId; + + public final Long mMasterKeyId; + public final byte[] mUncachedKeyringBytes; public UploadKeyringParcel(String keyserver, long masterKeyId) { mKeyserver = keyserver; mMasterKeyId = masterKeyId; + mUncachedKeyringBytes = null; + } + + public UploadKeyringParcel(String keyserver, byte[] uncachedKeyringBytes) { + mKeyserver = keyserver; + mMasterKeyId = null; + mUncachedKeyringBytes = uncachedKeyringBytes; } protected UploadKeyringParcel(Parcel in) { mKeyserver = in.readString(); - mMasterKeyId = in.readLong(); + mMasterKeyId = in.readInt() != 0 ? in.readLong() : null; + mUncachedKeyringBytes = in.createByteArray(); } @Override @@ -46,7 +56,13 @@ public class UploadKeyringParcel implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(mKeyserver); - dest.writeValue(mMasterKeyId); + if (mMasterKeyId != null) { + dest.writeInt(1); + dest.writeLong(mMasterKeyId); + } else { + dest.writeInt(0); + } + dest.writeByteArray(mUncachedKeyringBytes); } public static final Creator CREATOR = new Creator() { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupActivity.java index 3be1a9f6a..0e502baa2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupActivity.java @@ -39,6 +39,7 @@ public class BackupActivity extends BaseActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + // noinspection ConstantConditions, we know this activity has an action bar getSupportActionBar().setDisplayHomeAsUpEnabled(true); if (savedInstanceState == null) { -- cgit v1.2.3