tls-psk: use ascii armor block delimiter

This commit is contained in:
Vincent Breitmoser
2017-06-12 12:56:58 +02:00
parent e2c3f5b6f8
commit db3210e67c
2 changed files with 49 additions and 24 deletions

View File

@@ -80,28 +80,42 @@ public class KeyTransferInteractor {
private static final int CONNECTION_ERROR_CONNECT = 6; private static final int CONNECTION_ERROR_CONNECT = 6;
private static final int CONNECTION_ERROR_LISTEN = 7; private static final int CONNECTION_ERROR_LISTEN = 7;
private static final int TIMEOUT_RECEIVING = 2000;
private static final int TIMEOUT_WAITING = 500;
private final String delimiterStart;
private final String delimiterEnd;
private TransferThread transferThread; private TransferThread transferThread;
public KeyTransferInteractor(String delimiterStart, String delimiterEnd) {
this.delimiterStart = delimiterStart;
this.delimiterEnd = delimiterEnd;
}
public void connectToServer(String connectionDetails, KeyTransferCallback callback) { public void connectToServer(String connectionDetails, KeyTransferCallback callback) {
Uri uri = Uri.parse(connectionDetails); Uri uri = Uri.parse(connectionDetails);
final byte[] presharedKey = Hex.decode(uri.getUserInfo()); final byte[] presharedKey = Hex.decode(uri.getUserInfo());
final String host = uri.getHost(); final String host = uri.getHost();
final int port = uri.getPort(); final int port = uri.getPort();
transferThread = TransferThread.createClientTransferThread(callback, presharedKey, host, port); transferThread = TransferThread.createClientTransferThread(delimiterStart, delimiterEnd, callback, presharedKey, host, port);
transferThread.start(); transferThread.start();
} }
public void startServer(KeyTransferCallback callback) { public void startServer(KeyTransferCallback callback) {
byte[] presharedKey = generatePresharedKey(); byte[] presharedKey = generatePresharedKey();
transferThread = TransferThread.createServerTransferThread(callback, presharedKey); transferThread = TransferThread.createServerTransferThread(delimiterStart, delimiterEnd, callback, presharedKey);
transferThread.start(); transferThread.start();
} }
private static class TransferThread extends Thread { private static class TransferThread extends Thread {
private final String delimiterStart;
private final String delimiterEnd;
private final Handler handler; private final Handler handler;
private final byte[] presharedKey; private final byte[] presharedKey;
private final boolean isServer; private final boolean isServer;
@@ -113,17 +127,24 @@ public class KeyTransferInteractor {
private byte[] dataToSend; private byte[] dataToSend;
private String sendPassthrough; private String sendPassthrough;
static TransferThread createClientTransferThread(KeyTransferCallback callback, byte[] presharedKey, static TransferThread createClientTransferThread(String delimiterStart, String delimiterEnd,
String host, int port) { KeyTransferCallback callback, byte[] presharedKey, String host, int port) {
return new TransferThread(callback, presharedKey, false, host, port); return new TransferThread(delimiterStart, delimiterEnd, callback, presharedKey, false, host, port);
} }
static TransferThread createServerTransferThread(KeyTransferCallback callback, byte[] presharedKey) { static TransferThread createServerTransferThread(String delimiterStart, String delimiterEnd,
return new TransferThread(callback, presharedKey, true, null, null); KeyTransferCallback callback, byte[] presharedKey) {
return new TransferThread(delimiterStart, delimiterEnd, callback, presharedKey, true, null, null);
} }
private TransferThread(KeyTransferCallback callback, byte[] presharedKey, boolean isServer, private TransferThread(String delimiterStart, String delimiterEnd,
KeyTransferCallback callback, byte[] presharedKey, boolean isServer,
String clientHost, Integer clientPort) { String clientHost, Integer clientPort) {
super("TLS-PSK Key Transfer Thread");
this.delimiterStart = delimiterStart;
this.delimiterEnd = delimiterEnd;
this.callback = callback; this.callback = callback;
this.presharedKey = presharedKey; this.presharedKey = presharedKey;
this.clientHost = clientHost; this.clientHost = clientHost;
@@ -217,7 +238,7 @@ public class KeyTransferInteractor {
invokeListener(CONNECTION_ESTABLISHED, socket.getInetAddress().toString()); invokeListener(CONNECTION_ESTABLISHED, socket.getInetAddress().toString());
socket.setSoTimeout(500); socket.setSoTimeout(TIMEOUT_WAITING);
while (!isInterrupted() && socket.isConnected() && !socket.isClosed()) { while (!isInterrupted() && socket.isConnected() && !socket.isClosed()) {
sendDataIfAvailable(socket, outputStream); sendDataIfAvailable(socket, outputStream);
boolean connectionTerminated = receiveDataIfAvailable(socket, bufferedReader); boolean connectionTerminated = receiveDataIfAvailable(socket, bufferedReader);
@@ -241,9 +262,15 @@ public class KeyTransferInteractor {
return true; return true;
} }
socket.setSoTimeout(2000); boolean lineIsDelimiter = delimiterStart.equals(firstLine);
String receivedData = receiveAfterFirstLineAndClose(bufferedReader, firstLine); if (!lineIsDelimiter) {
socket.setSoTimeout(500); Log.d(Constants.TAG, "bad beginning of key block?");
return false;
}
socket.setSoTimeout(TIMEOUT_RECEIVING);
String receivedData = receiveLinesUntilEndDelimiter(bufferedReader, firstLine);
socket.setSoTimeout(TIMEOUT_WAITING);
invokeListener(CONNECTION_RECEIVE_OK, receivedData); invokeListener(CONNECTION_RECEIVE_OK, receivedData);
return false; return false;
@@ -254,12 +281,10 @@ public class KeyTransferInteractor {
byte[] data = dataToSend; byte[] data = dataToSend;
dataToSend = null; dataToSend = null;
socket.setSoTimeout(2000); socket.setSoTimeout(TIMEOUT_RECEIVING);
outputStream.write(data); outputStream.write(data);
outputStream.write('\n');
outputStream.write('\n');
outputStream.flush(); outputStream.flush();
socket.setSoTimeout(500); socket.setSoTimeout(TIMEOUT_WAITING);
invokeListener(CONNECTION_SEND_OK, sendPassthrough); invokeListener(CONNECTION_SEND_OK, sendPassthrough);
sendPassthrough = null; sendPassthrough = null;
@@ -268,19 +293,17 @@ public class KeyTransferInteractor {
return false; return false;
} }
private String receiveAfterFirstLineAndClose(BufferedReader bufferedReader, String line) throws IOException { private String receiveLinesUntilEndDelimiter(BufferedReader bufferedReader, String line) throws IOException {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
boolean lastLineWasEmpty = "".equals(line);
do { do {
boolean lineIsEmpty = "".equals(line); boolean lineIsDelimiter = delimiterEnd.equals(line);
if (lastLineWasEmpty && lineIsEmpty) { if (lineIsDelimiter) {
break; break;
} }
builder.append(line).append('\n'); builder.append(line).append('\n');
line = bufferedReader.readLine(); line = bufferedReader.readLine();
lastLineWasEmpty = lineIsEmpty;
} while (line != null); } while (line != null);
return builder.toString(); return builder.toString();
@@ -363,7 +386,7 @@ public class KeyTransferInteractor {
void onConnectionLost(); void onConnectionLost();
void onDataReceivedOk(String receivedData); void onDataReceivedOk(String receivedData);
void onDataSentOk(String arg); void onDataSentOk(String passthrough);
void onConnectionErrorConnect(); void onConnectionErrorConnect();
void onConnectionErrorListen(); void onConnectionErrorListen();

View File

@@ -65,6 +65,8 @@ import org.sufficientlysecure.keychain.util.Log;
@RequiresApi(api = VERSION_CODES.LOLLIPOP) @RequiresApi(api = VERSION_CODES.LOLLIPOP)
public class TransferPresenter implements KeyTransferCallback, LoaderCallbacks<List<SecretKeyItem>>, public class TransferPresenter implements KeyTransferCallback, LoaderCallbacks<List<SecretKeyItem>>,
OnClickTransferKeyListener, OnClickImportKeyListener { OnClickTransferKeyListener, OnClickImportKeyListener {
private static final String DELIMITER_START = "-----BEGIN PGP PRIVATE KEY BLOCK-----";
private static final String DELIMITER_END = "-----END PGP PRIVATE KEY BLOCK-----";
private static final String BACKSTACK_TAG_TRANSFER = "transfer"; private static final String BACKSTACK_TAG_TRANSFER = "transfer";
private final Context context; private final Context context;
@@ -278,7 +280,7 @@ public class TransferPresenter implements KeyTransferCallback, LoaderCallbacks<L
private void connectionStartConnect(String qrCodeContent) { private void connectionStartConnect(String qrCodeContent) {
connectionClear(); connectionClear();
keyTransferClientInteractor = new KeyTransferInteractor(); keyTransferClientInteractor = new KeyTransferInteractor(DELIMITER_START, DELIMITER_END);
keyTransferClientInteractor.connectToServer(qrCodeContent, this); keyTransferClientInteractor.connectToServer(qrCodeContent, this);
} }
@@ -298,7 +300,7 @@ public class TransferPresenter implements KeyTransferCallback, LoaderCallbacks<L
sentData = false; sentData = false;
connectionClear(); connectionClear();
keyTransferServerInteractor = new KeyTransferInteractor(); keyTransferServerInteractor = new KeyTransferInteractor(DELIMITER_START, DELIMITER_END);
keyTransferServerInteractor.startServer(this); keyTransferServerInteractor.startServer(this);
view.showWaitingForConnection(); view.showWaitingForConnection();