tls-psk: actual import of keys
This commit is contained in:
parent
e44d668e27
commit
703603782f
|
@ -124,7 +124,7 @@ public class KeyTransferInteractor {
|
|||
serverSocket = (SSLServerSocket) sslContext.getServerSocketFactory().createServerSocket(port);
|
||||
|
||||
String presharedKeyEncoded = Base64.encodeToString(presharedKey, Base64.URL_SAFE | Base64.NO_PADDING);
|
||||
String qrCodeData = presharedKeyEncoded + "@" + getIPAddress(true) + ":" + port;
|
||||
String qrCodeData = "pgp+transfer://" + presharedKeyEncoded + "@" + getIPAddress(true) + ":" + port;
|
||||
invokeListener(CONNECTION_LISTENING, qrCodeData);
|
||||
|
||||
socket = serverSocket.accept();
|
||||
|
@ -135,8 +135,8 @@ public class KeyTransferInteractor {
|
|||
}
|
||||
|
||||
handleOpenConnection(socket);
|
||||
Log.d(Constants.TAG, "connection closed ok!");
|
||||
} catch (IOException e) {
|
||||
invokeListener(CONNECTION_LOST, null);
|
||||
Log.e(Constants.TAG, "error!", e);
|
||||
} finally {
|
||||
try {
|
||||
|
@ -176,13 +176,8 @@ public class KeyTransferInteractor {
|
|||
socket.setSoTimeout(500);
|
||||
while (!isInterrupted() && socket.isConnected()) {
|
||||
sendDataIfAvailable(socket, outputStream);
|
||||
|
||||
boolean connectionClosed = receiveDataIfAvailable(socket, bufferedReader);
|
||||
if (connectionClosed) {
|
||||
break;
|
||||
}
|
||||
receiveDataIfAvailable(socket, bufferedReader);
|
||||
}
|
||||
|
||||
Log.d(Constants.TAG, "disconnected");
|
||||
invokeListener(CONNECTION_LOST, null);
|
||||
}
|
||||
|
@ -196,6 +191,7 @@ public class KeyTransferInteractor {
|
|||
}
|
||||
|
||||
if (firstLine == null) {
|
||||
invokeListener(CONNECTION_LOST, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -204,7 +200,7 @@ public class KeyTransferInteractor {
|
|||
socket.setSoTimeout(500);
|
||||
|
||||
invokeListener(CONNECTION_RECEIVE_OK, receivedData);
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean sendDataIfAvailable(Socket socket, OutputStream outputStream) throws IOException {
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.sufficientlysecure.keychain.operations;
|
|||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorCompletionService;
|
||||
|
@ -477,7 +478,7 @@ public class ImportOperation extends BaseReadWriteOperation<ImportKeyringParcel>
|
|||
@NonNull
|
||||
@Override
|
||||
public ImportKeyResult execute(ImportKeyringParcel importInput, CryptoInputParcel cryptoInput) {
|
||||
ArrayList<ParcelableKeyRing> keyList = importInput.getKeyList();
|
||||
List<ParcelableKeyRing> keyList = importInput.getKeyList();
|
||||
HkpKeyserverAddress keyServer = importInput.getKeyserver();
|
||||
boolean skipSave = importInput.isSkipSave();
|
||||
|
||||
|
@ -510,7 +511,7 @@ public class ImportOperation extends BaseReadWriteOperation<ImportKeyringParcel>
|
|||
}
|
||||
|
||||
@NonNull
|
||||
private ImportKeyResult multiThreadedKeyImport(ArrayList<ParcelableKeyRing> keyList,
|
||||
private ImportKeyResult multiThreadedKeyImport(List<ParcelableKeyRing> keyList,
|
||||
final HkpKeyserverAddress keyServer, final ParcelableProxy proxy,
|
||||
final boolean skipSave) {
|
||||
Log.d(Constants.TAG, "Multi-threaded key import starting");
|
||||
|
|
|
@ -20,6 +20,8 @@ package org.sufficientlysecure.keychain.service;
|
|||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.Nullable;
|
||||
|
@ -31,21 +33,25 @@ import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
|||
@AutoValue
|
||||
public abstract class ImportKeyringParcel implements Parcelable {
|
||||
@Nullable // If null, keys are expected to be read from a cache file in ImportExportOperations
|
||||
public abstract ArrayList<ParcelableKeyRing> getKeyList();
|
||||
public abstract List<ParcelableKeyRing> getKeyList();
|
||||
@Nullable // must be set if keys are to be imported from a keyserver
|
||||
public abstract HkpKeyserverAddress getKeyserver();
|
||||
public abstract boolean isSkipSave();
|
||||
|
||||
public static ImportKeyringParcel createImportKeyringParcel(ArrayList<ParcelableKeyRing> keyList,
|
||||
public static ImportKeyringParcel createImportKeyringParcel(List<ParcelableKeyRing> keyList,
|
||||
HkpKeyserverAddress keyserver) {
|
||||
return new AutoValue_ImportKeyringParcel(keyList, keyserver, false);
|
||||
}
|
||||
|
||||
public static ImportKeyringParcel createWithSkipSave(ArrayList<ParcelableKeyRing> keyList,
|
||||
public static ImportKeyringParcel createWithSkipSave(List<ParcelableKeyRing> keyList,
|
||||
HkpKeyserverAddress keyserver) {
|
||||
return new AutoValue_ImportKeyringParcel(keyList, keyserver, true);
|
||||
}
|
||||
|
||||
public static ImportKeyringParcel createImportKeyringParcel(ParcelableKeyRing key) {
|
||||
return new AutoValue_ImportKeyringParcel(Collections.singletonList(key), null, false);
|
||||
}
|
||||
|
||||
public static ImportKeyringParcel createFromFileCacheWithSkipSave() {
|
||||
return new AutoValue_ImportKeyringParcel(null, null, true);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import android.net.Uri;
|
|||
import android.os.Build.VERSION_CODES;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
|
@ -37,12 +38,18 @@ import android.view.LayoutInflater;
|
|||
import org.openintents.openpgp.util.OpenPgpUtils;
|
||||
import org.openintents.openpgp.util.OpenPgpUtils.UserId;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
||||
import org.sufficientlysecure.keychain.network.KeyTransferInteractor;
|
||||
import org.sufficientlysecure.keychain.network.KeyTransferInteractor.KeyTransferCallback;
|
||||
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||
import org.sufficientlysecure.keychain.provider.KeyRepository;
|
||||
import org.sufficientlysecure.keychain.provider.KeyRepository.NotFoundException;
|
||||
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
|
||||
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper.Callback;
|
||||
import org.sufficientlysecure.keychain.ui.transfer.loader.SecretKeyLoader.SecretKeyItem;
|
||||
import org.sufficientlysecure.keychain.ui.transfer.view.ReceivedSecretKeyList.OnClickImportKeyListener;
|
||||
import org.sufficientlysecure.keychain.ui.transfer.view.ReceivedSecretKeyList.ReceivedKeyAdapter;
|
||||
|
@ -61,11 +68,14 @@ public class TransferPresenter implements KeyTransferCallback, LoaderCallbacks<L
|
|||
private final LoaderManager loaderManager;
|
||||
private final int loaderId;
|
||||
|
||||
private KeyTransferInteractor keyTransferClientInteractor;
|
||||
private KeyTransferInteractor keyTransferServerInteractor;
|
||||
private final TransferKeyAdapter secretKeyAdapter;
|
||||
private final ReceivedKeyAdapter receivedKeyAdapter;
|
||||
|
||||
private KeyTransferInteractor keyTransferClientInteractor;
|
||||
private KeyTransferInteractor keyTransferServerInteractor;
|
||||
|
||||
private boolean wasConnected = false;
|
||||
|
||||
public TransferPresenter(Context context, LoaderManager loaderManager, int loaderId, TransferMvpView view) {
|
||||
this.context = context;
|
||||
this.view = view;
|
||||
|
@ -83,7 +93,7 @@ public class TransferPresenter implements KeyTransferCallback, LoaderCallbacks<L
|
|||
public void onUiStart() {
|
||||
loaderManager.restartLoader(loaderId, null, this);
|
||||
|
||||
if (keyTransferServerInteractor == null && keyTransferClientInteractor == null) {
|
||||
if (keyTransferServerInteractor == null && keyTransferClientInteractor == null && !wasConnected) {
|
||||
connectionStartListen();
|
||||
}
|
||||
}
|
||||
|
@ -115,26 +125,72 @@ public class TransferPresenter implements KeyTransferCallback, LoaderCallbacks<L
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onUiClickImportKey(String keyData) {
|
||||
public void onUiClickImportKey(final long masterKeyId, String keyData) {
|
||||
receivedKeyAdapter.focusItem(masterKeyId);
|
||||
|
||||
final ImportKeyringParcel importKeyringParcel = ImportKeyringParcel.createImportKeyringParcel(
|
||||
ParcelableKeyRing.createFromEncodedBytes(keyData.getBytes()));
|
||||
|
||||
CryptoOperationHelper<ImportKeyringParcel,ImportKeyResult> op =
|
||||
view.createCryptoOperationHelper(new Callback<ImportKeyringParcel,ImportKeyResult>() {
|
||||
@Override
|
||||
public ImportKeyringParcel createOperationInput() {
|
||||
return importKeyringParcel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCryptoOperationSuccess(ImportKeyResult result) {
|
||||
receivedKeyAdapter.focusItem(null);
|
||||
receivedKeyAdapter.addToFinishedItems(masterKeyId);
|
||||
view.releaseCryptoOperationHelper();
|
||||
view.showResultNotification(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCryptoOperationCancelled() {
|
||||
view.releaseCryptoOperationHelper();
|
||||
receivedKeyAdapter.focusItem(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCryptoOperationError(ImportKeyResult result) {
|
||||
receivedKeyAdapter.focusItem(null);
|
||||
view.releaseCryptoOperationHelper();
|
||||
view.showResultNotification(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCryptoSetProgress(String msg, int progress, int max) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
op.cryptoOperation();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onServerStarted(String qrCodeData) {
|
||||
Bitmap qrCodeBitmap = QrCodeUtils.getQRCodeBitmap(Uri.parse("pgp+transfer://" + qrCodeData));
|
||||
Bitmap qrCodeBitmap = QrCodeUtils.getQRCodeBitmap(Uri.parse(qrCodeData));
|
||||
view.setQrImage(qrCodeBitmap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionEstablished(String otherName) {
|
||||
wasConnected = true;
|
||||
|
||||
secretKeyAdapter.clearFinishedItems();
|
||||
view.showConnectionEstablished(otherName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionLost() {
|
||||
connectionStartListen();
|
||||
if (!wasConnected) {
|
||||
// display connection error?
|
||||
connectionStartListen();
|
||||
view.showErrorConnectionFailed();
|
||||
}
|
||||
// TODO handle error?
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -152,7 +208,8 @@ public class TransferPresenter implements KeyTransferCallback, LoaderCallbacks<L
|
|||
uncachedKeyRing.getCreationTime(), userId.name, userId.email);
|
||||
receivedKeyAdapter.addItem(receivedKeyItem);
|
||||
} catch (PgpGeneralException | IOException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(Constants.TAG, "error parsing incoming key", e);
|
||||
view.showErrorBadKey();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,7 +288,15 @@ public class TransferPresenter implements KeyTransferCallback, LoaderCallbacks<L
|
|||
void scanQrCode();
|
||||
void setQrImage(Bitmap qrCode);
|
||||
|
||||
void releaseCryptoOperationHelper();
|
||||
|
||||
void showErrorBadKey();
|
||||
void showErrorConnectionFailed();
|
||||
void showResultNotification(ImportKeyResult result);
|
||||
|
||||
void setSecretKeyAdapter(Adapter adapter);
|
||||
void setReceivedKeyAdapter(Adapter secretKeyAdapter);
|
||||
|
||||
<T extends Parcelable, S extends OperationResult> CryptoOperationHelper<T,S> createCryptoOperationHelper(Callback<T, S> callback);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,6 +87,11 @@ public class ReceivedSecretKeyList extends RecyclerView {
|
|||
return data.get(position).masterKeyId;
|
||||
}
|
||||
|
||||
public void addToFinishedItems(long masterKeyId) {
|
||||
finishedItems.add(masterKeyId);
|
||||
// doeesn't notify, because it's non-trivial and this is called in conjunction with other refreshing things!
|
||||
}
|
||||
|
||||
public void focusItem(Long masterKeyId) {
|
||||
focusedMasterKeyId = masterKeyId;
|
||||
notifyItemRangeChanged(0, getItemCount());
|
||||
|
@ -154,7 +159,7 @@ public class ReceivedSecretKeyList extends RecyclerView {
|
|||
vImportButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onClickReceiveKeyListener.onUiClickImportKey(item.keyData);
|
||||
onClickReceiveKeyListener.onUiClickImportKey(item.masterKeyId, item.keyData);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
@ -164,7 +169,7 @@ public class ReceivedSecretKeyList extends RecyclerView {
|
|||
}
|
||||
|
||||
public interface OnClickImportKeyListener {
|
||||
void onUiClickImportKey(String keyData);
|
||||
void onUiClickImportKey(long masterKeyId, String keyData);
|
||||
}
|
||||
|
||||
public static class ReceivedKeyItem {
|
||||
|
|
|
@ -18,16 +18,12 @@
|
|||
package org.sufficientlysecure.keychain.ui.transfer.view;
|
||||
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.v4.app.Fragment;
|
||||
|
@ -44,8 +40,12 @@ import android.widget.ViewAnimator;
|
|||
|
||||
import com.google.zxing.client.android.Intents;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.ui.QrCodeCaptureActivity;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
|
||||
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper.Callback;
|
||||
import org.sufficientlysecure.keychain.ui.transfer.presenter.TransferPresenter;
|
||||
import org.sufficientlysecure.keychain.ui.transfer.presenter.TransferPresenter.TransferMvpView;
|
||||
|
||||
|
@ -54,8 +54,7 @@ import org.sufficientlysecure.keychain.ui.transfer.presenter.TransferPresenter.T
|
|||
public class TransferFragment extends Fragment implements TransferMvpView {
|
||||
public static final int VIEW_WAITING = 0;
|
||||
public static final int VIEW_CONNECTED = 1;
|
||||
public static final int VIEW_SEND_OK = 2;
|
||||
public static final int VIEW_RECEIVING = 3;
|
||||
public static final int VIEW_RECEIVING = 2;
|
||||
|
||||
public static final int REQUEST_CODE_SCAN = 1;
|
||||
public static final int LOADER_ID = 1;
|
||||
|
@ -68,6 +67,8 @@ public class TransferFragment extends Fragment implements TransferMvpView {
|
|||
private RecyclerView vTransferKeyList;
|
||||
private RecyclerView vReceivedKeyList;
|
||||
|
||||
private CryptoOperationHelper currentCryptoOperationHelper;
|
||||
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
|
@ -90,15 +91,9 @@ public class TransferFragment extends Fragment implements TransferMvpView {
|
|||
}
|
||||
});
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
presenter = new TransferPresenter(getContext(), getLoaderManager(), LOADER_ID, this);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -162,8 +157,40 @@ public class TransferFragment extends Fragment implements TransferMvpView {
|
|||
vReceivedKeyList.setAdapter(adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Parcelable, S extends OperationResult> CryptoOperationHelper<T,S> createCryptoOperationHelper(Callback<T, S> callback) {
|
||||
CryptoOperationHelper<T,S> cryptoOperationHelper = new CryptoOperationHelper<>(1, this, callback, null);
|
||||
currentCryptoOperationHelper = cryptoOperationHelper;
|
||||
return cryptoOperationHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseCryptoOperationHelper() {
|
||||
currentCryptoOperationHelper = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showErrorBadKey() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showErrorConnectionFailed() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showResultNotification(ImportKeyResult result) {
|
||||
result.createNotify(getActivity()).show(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (currentCryptoOperationHelper != null &&
|
||||
currentCryptoOperationHelper.handleActivityResult(requestCode, resultCode, data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (requestCode) {
|
||||
case REQUEST_CODE_SCAN:
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
|
|
|
@ -87,30 +87,6 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:text="Key transfer ok!"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="Finish"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
|
Loading…
Reference in a new issue