tls-psk: extract skt uri handling, and use new qr code format
This commit is contained in:
@@ -27,8 +27,10 @@ import java.io.OutputStream;
|
|||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.NetworkInterface;
|
import java.net.NetworkInterface;
|
||||||
|
import java.net.NoRouteToHostException;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
@@ -36,11 +38,9 @@ import java.util.Arrays;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import android.net.PskKeyManager;
|
import android.net.PskKeyManager;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Build.VERSION_CODES;
|
import android.os.Build.VERSION_CODES;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
@@ -56,7 +56,6 @@ import javax.net.ssl.SSLHandshakeException;
|
|||||||
import javax.net.ssl.SSLServerSocket;
|
import javax.net.ssl.SSLServerSocket;
|
||||||
import javax.net.ssl.SSLSocket;
|
import javax.net.ssl.SSLSocket;
|
||||||
import javax.net.ssl.TrustManager;
|
import javax.net.ssl.TrustManager;
|
||||||
import org.bouncycastle.util.encoders.Hex;
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
@@ -78,11 +77,11 @@ public class KeyTransferInteractor {
|
|||||||
private static final int CONNECTION_SEND_OK = 3;
|
private static final int CONNECTION_SEND_OK = 3;
|
||||||
private static final int CONNECTION_RECEIVE_OK = 4;
|
private static final int CONNECTION_RECEIVE_OK = 4;
|
||||||
private static final int CONNECTION_LOST = 5;
|
private static final int CONNECTION_LOST = 5;
|
||||||
private static final int CONNECTION_ERROR_CONNECT = 6;
|
private static final int CONNECTION_ERROR_NO_ROUTE_TO_HOST = 6;
|
||||||
private static final int CONNECTION_ERROR_WHILE_CONNECTED = 7;
|
private static final int CONNECTION_ERROR_CONNECT = 7;
|
||||||
private static final int CONNECTION_ERROR_LISTEN = 8;
|
private static final int CONNECTION_ERROR_WHILE_CONNECTED = 8;
|
||||||
|
private static final int CONNECTION_ERROR_LISTEN = 0;
|
||||||
|
|
||||||
private static final String QRCODE_URI_FORMAT = "PGP+TRANSFER://%s@%s:%s";
|
|
||||||
private static final int TIMEOUT_CONNECTING = 1500;
|
private static final int TIMEOUT_CONNECTING = 1500;
|
||||||
private static final int TIMEOUT_RECEIVING = 2000;
|
private static final int TIMEOUT_RECEIVING = 2000;
|
||||||
private static final int TIMEOUT_WAITING = 500;
|
private static final int TIMEOUT_WAITING = 500;
|
||||||
@@ -100,20 +99,18 @@ public class KeyTransferInteractor {
|
|||||||
this.delimiterEnd = delimiterEnd;
|
this.delimiterEnd = delimiterEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connectToServer(String connectionDetails, KeyTransferCallback callback) {
|
public void connectToServer(String qrCodeContent, KeyTransferCallback callback) throws URISyntaxException {
|
||||||
Uri uri = Uri.parse(connectionDetails);
|
SktUri sktUri = SktUri.parse(qrCodeContent);
|
||||||
final byte[] presharedKey = Hex.decode(uri.getUserInfo());
|
|
||||||
final String host = uri.getHost();
|
|
||||||
final int port = uri.getPort();
|
|
||||||
|
|
||||||
transferThread = TransferThread.createClientTransferThread(delimiterStart, delimiterEnd, callback, presharedKey, host, port);
|
transferThread = TransferThread.createClientTransferThread(delimiterStart, delimiterEnd, callback,
|
||||||
|
sktUri.getPresharedKey(), sktUri.getHost(), sktUri.getPort(), sktUri.getWifiSsid());
|
||||||
transferThread.start();
|
transferThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startServer(KeyTransferCallback callback) {
|
public void startServer(KeyTransferCallback callback, String wifiSsid) {
|
||||||
byte[] presharedKey = generatePresharedKey();
|
byte[] presharedKey = generatePresharedKey();
|
||||||
|
|
||||||
transferThread = TransferThread.createServerTransferThread(delimiterStart, delimiterEnd, callback, presharedKey);
|
transferThread = TransferThread.createServerTransferThread(delimiterStart, delimiterEnd, callback, presharedKey, wifiSsid);
|
||||||
transferThread.start();
|
transferThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,6 +123,7 @@ public class KeyTransferInteractor {
|
|||||||
private final boolean isServer;
|
private final boolean isServer;
|
||||||
private final String clientHost;
|
private final String clientHost;
|
||||||
private final Integer clientPort;
|
private final Integer clientPort;
|
||||||
|
private final String wifiSsid;
|
||||||
|
|
||||||
private KeyTransferCallback callback;
|
private KeyTransferCallback callback;
|
||||||
private SSLServerSocket serverSocket;
|
private SSLServerSocket serverSocket;
|
||||||
@@ -133,18 +131,18 @@ public class KeyTransferInteractor {
|
|||||||
private String sendPassthrough;
|
private String sendPassthrough;
|
||||||
|
|
||||||
static TransferThread createClientTransferThread(String delimiterStart, String delimiterEnd,
|
static TransferThread createClientTransferThread(String delimiterStart, String delimiterEnd,
|
||||||
KeyTransferCallback callback, byte[] presharedKey, String host, int port) {
|
KeyTransferCallback callback, byte[] presharedKey, String host, int port, String wifiSsid) {
|
||||||
return new TransferThread(delimiterStart, delimiterEnd, callback, presharedKey, false, host, port);
|
return new TransferThread(delimiterStart, delimiterEnd, callback, presharedKey, false, host, port, wifiSsid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TransferThread createServerTransferThread(String delimiterStart, String delimiterEnd,
|
static TransferThread createServerTransferThread(String delimiterStart, String delimiterEnd,
|
||||||
KeyTransferCallback callback, byte[] presharedKey) {
|
KeyTransferCallback callback, byte[] presharedKey, String wifiSsid) {
|
||||||
return new TransferThread(delimiterStart, delimiterEnd, callback, presharedKey, true, null, null);
|
return new TransferThread(delimiterStart, delimiterEnd, callback, presharedKey, true, null, null, wifiSsid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TransferThread(String delimiterStart, String delimiterEnd,
|
private TransferThread(String delimiterStart, String delimiterEnd,
|
||||||
KeyTransferCallback callback, byte[] presharedKey, boolean isServer,
|
KeyTransferCallback callback, byte[] presharedKey, boolean isServer,
|
||||||
String clientHost, Integer clientPort) {
|
String clientHost, Integer clientPort, String wifiSsid) {
|
||||||
super("TLS-PSK Key Transfer Thread");
|
super("TLS-PSK Key Transfer Thread");
|
||||||
|
|
||||||
this.delimiterStart = delimiterStart;
|
this.delimiterStart = delimiterStart;
|
||||||
@@ -154,6 +152,7 @@ public class KeyTransferInteractor {
|
|||||||
this.presharedKey = presharedKey;
|
this.presharedKey = presharedKey;
|
||||||
this.clientHost = clientHost;
|
this.clientHost = clientHost;
|
||||||
this.clientPort = clientPort;
|
this.clientPort = clientPort;
|
||||||
|
this.wifiSsid = wifiSsid;
|
||||||
this.isServer = isServer;
|
this.isServer = isServer;
|
||||||
|
|
||||||
handler = new Handler(Looper.getMainLooper());
|
handler = new Handler(Looper.getMainLooper());
|
||||||
@@ -196,11 +195,8 @@ public class KeyTransferInteractor {
|
|||||||
String[] enabledCipherSuites = intersectArrays(supportedCipherSuites, ALLOWED_CIPHERSUITES);
|
String[] enabledCipherSuites = intersectArrays(supportedCipherSuites, ALLOWED_CIPHERSUITES);
|
||||||
serverSocket.setEnabledCipherSuites(enabledCipherSuites);
|
serverSocket.setEnabledCipherSuites(enabledCipherSuites);
|
||||||
|
|
||||||
String presharedKeyEncoded = Hex.toHexString(presharedKey);
|
SktUri sktUri = SktUri.create(getIPAddress(true), serverSocket.getLocalPort(), presharedKey, wifiSsid);
|
||||||
String qrCodeData = String.format(
|
invokeListener(CONNECTION_LISTENING, sktUri.toUriString());
|
||||||
QRCODE_URI_FORMAT, presharedKeyEncoded, getIPAddress(true), serverSocket.getLocalPort());
|
|
||||||
qrCodeData = qrCodeData.toUpperCase(Locale.getDefault());
|
|
||||||
invokeListener(CONNECTION_LISTENING, qrCodeData);
|
|
||||||
|
|
||||||
socket = serverSocket.accept();
|
socket = serverSocket.accept();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -219,7 +215,11 @@ public class KeyTransferInteractor {
|
|||||||
socket.connect(new InetSocketAddress(InetAddress.getByName(clientHost), clientPort), TIMEOUT_CONNECTING);
|
socket.connect(new InetSocketAddress(InetAddress.getByName(clientHost), clientPort), TIMEOUT_CONNECTING);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.e(Constants.TAG, "error while connecting!", e);
|
Log.e(Constants.TAG, "error while connecting!", e);
|
||||||
invokeListener(CONNECTION_ERROR_CONNECT, null);
|
if (e instanceof NoRouteToHostException) {
|
||||||
|
invokeListener(CONNECTION_ERROR_NO_ROUTE_TO_HOST, wifiSsid);
|
||||||
|
} else {
|
||||||
|
invokeListener(CONNECTION_ERROR_CONNECT, null);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -345,6 +345,9 @@ public class KeyTransferInteractor {
|
|||||||
case CONNECTION_ERROR_WHILE_CONNECTED:
|
case CONNECTION_ERROR_WHILE_CONNECTED:
|
||||||
callback.onConnectionError(arg);
|
callback.onConnectionError(arg);
|
||||||
break;
|
break;
|
||||||
|
case CONNECTION_ERROR_NO_ROUTE_TO_HOST:
|
||||||
|
callback.onConnectionErrorNoRouteToHost(wifiSsid);
|
||||||
|
break;
|
||||||
case CONNECTION_ERROR_CONNECT:
|
case CONNECTION_ERROR_CONNECT:
|
||||||
callback.onConnectionErrorConnect();
|
callback.onConnectionErrorConnect();
|
||||||
break;
|
break;
|
||||||
@@ -398,6 +401,7 @@ public class KeyTransferInteractor {
|
|||||||
void onDataSentOk(String passthrough);
|
void onDataSentOk(String passthrough);
|
||||||
|
|
||||||
void onConnectionErrorConnect();
|
void onConnectionErrorConnect();
|
||||||
|
void onConnectionErrorNoRouteToHost(String wifiSsid);
|
||||||
void onConnectionErrorListen();
|
void onConnectionErrorListen();
|
||||||
void onConnectionError(String arg);
|
void onConnectionError(String arg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package org.sufficientlysecure.keychain.network;
|
||||||
|
|
||||||
|
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.auto.value.AutoValue;
|
||||||
|
import org.bouncycastle.util.encoders.DecoderException;
|
||||||
|
import org.bouncycastle.util.encoders.Hex;
|
||||||
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
|
|
||||||
|
@AutoValue
|
||||||
|
abstract class SktUri {
|
||||||
|
private static final String SKT_SCHEME = "OPGPSKT";
|
||||||
|
private static final String QRCODE_URI_FORMAT = SKT_SCHEME + ":%s/%d/%s";
|
||||||
|
private static final String QRCODE_URI_FORMAT_SSID = SKT_SCHEME + ":%s/%d/%s/SSID:%s";
|
||||||
|
|
||||||
|
|
||||||
|
public abstract String getHost();
|
||||||
|
public abstract int getPort();
|
||||||
|
public abstract byte[] getPresharedKey();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public abstract String getWifiSsid();
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static SktUri parse(String input) throws URISyntaxException {
|
||||||
|
if (!input.startsWith(SKT_SCHEME + ":")) {
|
||||||
|
throw new URISyntaxException(input, "invalid scheme");
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] pieces = input.substring(input.indexOf(":") +1).split("/");
|
||||||
|
if (pieces.length < 3) {
|
||||||
|
throw new URISyntaxException(input, "invalid syntax");
|
||||||
|
}
|
||||||
|
|
||||||
|
String address = pieces[0];
|
||||||
|
int port;
|
||||||
|
try {
|
||||||
|
port = Integer.parseInt(pieces[1]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new URISyntaxException(input, "error parsing port");
|
||||||
|
}
|
||||||
|
byte[] psk;
|
||||||
|
try {
|
||||||
|
psk = Hex.decode(pieces[2]);
|
||||||
|
} catch (DecoderException e) {
|
||||||
|
throw new URISyntaxException(input, "error parsing hex psk");
|
||||||
|
}
|
||||||
|
|
||||||
|
String wifiSsid = null;
|
||||||
|
for (int i = 3; i < pieces.length; i++) {
|
||||||
|
String[] optarg = pieces[i].split(":", 2);
|
||||||
|
if (optarg.length == 2 && "SSID".equals(optarg[0])) {
|
||||||
|
try {
|
||||||
|
wifiSsid = new String(Hex.decode(optarg[1]));
|
||||||
|
} catch (DecoderException e) {
|
||||||
|
Log.d(Constants.TAG, "error parsing ssid in skt uri, ignoring: " + input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new AutoValue_SktUri(address, port, psk, wifiSsid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("DefaultLocale")
|
||||||
|
String toUriString() {
|
||||||
|
String sktHex = Hex.toHexString(getPresharedKey());
|
||||||
|
String wifiSsid = getWifiSsid();
|
||||||
|
|
||||||
|
String result;
|
||||||
|
if (wifiSsid != null) {
|
||||||
|
String encodedWifiSsid = Hex.toHexString(getWifiSsid().getBytes(Charset.defaultCharset()));
|
||||||
|
result = String.format(QRCODE_URI_FORMAT_SSID, getHost(), getPort(), sktHex, encodedWifiSsid);
|
||||||
|
} else {
|
||||||
|
result = String.format(QRCODE_URI_FORMAT, getHost(), getPort(), sktHex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
static SktUri create(String host, int port, byte[] presharedKey, @Nullable String wifiSsid) {
|
||||||
|
return new AutoValue_SktUri(host, port, presharedKey, wifiSsid);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.ui.transfer.presenter;
|
|||||||
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -298,6 +299,13 @@ public class TransferPresenter implements KeyTransferCallback, LoaderCallbacks<L
|
|||||||
resetAndStartListen();
|
resetAndStartListen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnectionErrorNoRouteToHost(String wifiSsid) {
|
||||||
|
view.showErrorConnectionFailed();
|
||||||
|
|
||||||
|
resetAndStartListen();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConnectionErrorListen() {
|
public void onConnectionErrorListen() {
|
||||||
view.showErrorListenFailed();
|
view.showErrorListenFailed();
|
||||||
@@ -320,7 +328,11 @@ public class TransferPresenter implements KeyTransferCallback, LoaderCallbacks<L
|
|||||||
view.showEstablishingConnection();
|
view.showEstablishingConnection();
|
||||||
|
|
||||||
keyTransferClientInteractor = new KeyTransferInteractor(DELIMITER_START, DELIMITER_END);
|
keyTransferClientInteractor = new KeyTransferInteractor(DELIMITER_START, DELIMITER_END);
|
||||||
keyTransferClientInteractor.connectToServer(qrCodeContent, TransferPresenter.this);
|
try {
|
||||||
|
keyTransferClientInteractor.connectToServer(qrCodeContent, TransferPresenter.this);
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
view.showErrorConnectionFailed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkWifiResetAndStartListen() {
|
private void checkWifiResetAndStartListen() {
|
||||||
@@ -340,7 +352,7 @@ public class TransferPresenter implements KeyTransferCallback, LoaderCallbacks<L
|
|||||||
connectionClear();
|
connectionClear();
|
||||||
|
|
||||||
keyTransferServerInteractor = new KeyTransferInteractor(DELIMITER_START, DELIMITER_END);
|
keyTransferServerInteractor = new KeyTransferInteractor(DELIMITER_START, DELIMITER_END);
|
||||||
keyTransferServerInteractor.startServer(this);
|
keyTransferServerInteractor.startServer(this, null);
|
||||||
|
|
||||||
view.showWaitingForConnection();
|
view.showWaitingForConnection();
|
||||||
view.setShowDoneIcon(false);
|
view.setShowDoneIcon(false);
|
||||||
|
|||||||
@@ -1,19 +1,14 @@
|
|||||||
package org.sufficientlysecure.keychain.network;
|
package org.sufficientlysecure.keychain.network;
|
||||||
|
|
||||||
|
|
||||||
import java.security.Security;
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
import android.os.Build.VERSION_CODES;
|
import android.os.Build.VERSION_CODES;
|
||||||
import android.support.annotation.RequiresApi;
|
import android.support.annotation.RequiresApi;
|
||||||
|
|
||||||
import junit.framework.Assert;
|
import junit.framework.Assert;
|
||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.robolectric.shadows.ShadowLog;
|
import org.robolectric.shadows.ShadowLog;
|
||||||
import org.robolectric.shadows.ShadowLooper;
|
import org.robolectric.shadows.ShadowLooper;
|
||||||
import org.sufficientlysecure.keychain.KeychainTestRunner;
|
|
||||||
import org.sufficientlysecure.keychain.network.KeyTransferInteractor.KeyTransferCallback;
|
import org.sufficientlysecure.keychain.network.KeyTransferInteractor.KeyTransferCallback;
|
||||||
|
|
||||||
import static junit.framework.Assert.assertTrue;
|
import static junit.framework.Assert.assertTrue;
|
||||||
@@ -38,7 +33,7 @@ public class KeyTransferInteractorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Test
|
// @Test
|
||||||
public void testServerShouldGiveSuccessCallback() {
|
public void testServerShouldGiveSuccessCallback() throws URISyntaxException {
|
||||||
KeyTransferInteractor serverKeyTransferInteractor = new KeyTransferInteractor(DELIM_START, DELIM_END);
|
KeyTransferInteractor serverKeyTransferInteractor = new KeyTransferInteractor(DELIM_START, DELIM_END);
|
||||||
|
|
||||||
serverKeyTransferInteractor.startServer(new SimpleKeyTransferCallback() {
|
serverKeyTransferInteractor.startServer(new SimpleKeyTransferCallback() {
|
||||||
@@ -51,7 +46,7 @@ public class KeyTransferInteractorTest {
|
|||||||
public void onConnectionEstablished(String otherName) {
|
public void onConnectionEstablished(String otherName) {
|
||||||
serverConnectionEstablished = true;
|
serverConnectionEstablished = true;
|
||||||
}
|
}
|
||||||
});
|
}, null);
|
||||||
waitForLooperCallback();
|
waitForLooperCallback();
|
||||||
Assert.assertNotNull(receivedQrCodeData);
|
Assert.assertNotNull(receivedQrCodeData);
|
||||||
|
|
||||||
@@ -103,6 +98,11 @@ public class KeyTransferInteractorTest {
|
|||||||
fail("unexpected callback: onDataSentOk");
|
fail("unexpected callback: onDataSentOk");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnectionErrorNoRouteToHost(String wifiSsid) {
|
||||||
|
fail("unexpected callback: onConnectionErrorNoRouteToHost");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConnectionErrorConnect() {
|
public void onConnectionErrorConnect() {
|
||||||
fail("unexpected callback: onConnectionErrorConnect");
|
fail("unexpected callback: onConnectionErrorConnect");
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package org.sufficientlysecure.keychain.network;
|
||||||
|
|
||||||
|
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
|
||||||
|
import org.bouncycastle.util.encoders.Hex;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
@SuppressLint("DefaultLocale")
|
||||||
|
public class SktUriTest {
|
||||||
|
static final String HOST = "127.0.0.1";
|
||||||
|
static final int PORT = 1234;
|
||||||
|
static final byte[] PRESHARED_KEY = { 1, 2 };
|
||||||
|
static final String SSID = "ssid";
|
||||||
|
|
||||||
|
static final String ENCODED_SKT = String.format("OPGPSKT:%s/%d/%s/SSID:%s",
|
||||||
|
HOST, PORT, Hex.toHexString(PRESHARED_KEY), Hex.toHexString(SSID.getBytes()));
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreate() {
|
||||||
|
SktUri sktUri = SktUri.create(HOST, PORT, PRESHARED_KEY, null);
|
||||||
|
|
||||||
|
assertEquals(HOST, sktUri.getHost());
|
||||||
|
assertEquals(PORT, sktUri.getPort());
|
||||||
|
assertArrayEquals(PRESHARED_KEY, sktUri.getPresharedKey());
|
||||||
|
assertEquals(null, sktUri.getWifiSsid());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateWithSsid() {
|
||||||
|
SktUri sktUri = SktUri.create(HOST, PORT, PRESHARED_KEY, SSID);
|
||||||
|
|
||||||
|
assertEquals(HOST, sktUri.getHost());
|
||||||
|
assertEquals(PORT, sktUri.getPort());
|
||||||
|
assertArrayEquals(PRESHARED_KEY, sktUri.getPresharedKey());
|
||||||
|
assertEquals(SSID, sktUri.getWifiSsid());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreate_isAllUppercase() {
|
||||||
|
SktUri sktUri = SktUri.create(HOST, PORT, PRESHARED_KEY, SSID);
|
||||||
|
|
||||||
|
String encodedSktUri = sktUri.toUriString();
|
||||||
|
assertEquals(encodedSktUri.toUpperCase(), encodedSktUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParse() throws URISyntaxException {
|
||||||
|
SktUri sktUri = SktUri.parse(ENCODED_SKT);
|
||||||
|
|
||||||
|
assertNotNull(sktUri);
|
||||||
|
assertEquals(HOST, sktUri.getHost());
|
||||||
|
assertEquals(PORT, sktUri.getPort());
|
||||||
|
assertArrayEquals(PRESHARED_KEY, sktUri.getPresharedKey());
|
||||||
|
assertEquals(SSID, sktUri.getWifiSsid());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBackAndForth() throws URISyntaxException {
|
||||||
|
SktUri sktUri = SktUri.create(HOST, PORT, PRESHARED_KEY, null);
|
||||||
|
String encodedSktUri = sktUri.toUriString();
|
||||||
|
SktUri decodedSktUri = SktUri.parse(encodedSktUri);
|
||||||
|
|
||||||
|
assertEquals(sktUri, decodedSktUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBackAndForthWithSsid() throws URISyntaxException {
|
||||||
|
SktUri sktUri = SktUri.create(HOST, PORT, PRESHARED_KEY, SSID);
|
||||||
|
String encodedSktUri = sktUri.toUriString();
|
||||||
|
SktUri decodedSktUri = SktUri.parse(encodedSktUri);
|
||||||
|
|
||||||
|
assertEquals(sktUri, decodedSktUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = URISyntaxException.class)
|
||||||
|
public void testParse_withBadScheme_shouldFail() throws URISyntaxException {
|
||||||
|
SktUri.parse(String.format("XXXGPSKT:%s/%d/%s/SSID:%s",
|
||||||
|
HOST, PORT, Hex.toHexString(PRESHARED_KEY), Hex.toHexString(SSID.getBytes())));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = URISyntaxException.class)
|
||||||
|
public void testParse_withBadPsk_shouldFail() throws URISyntaxException {
|
||||||
|
SktUri.parse(String.format("OPGPSKT:%s/%d/xx%s/SSID:%s",
|
||||||
|
HOST, PORT, Hex.toHexString(PRESHARED_KEY), Hex.toHexString(SSID.getBytes())));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = URISyntaxException.class)
|
||||||
|
public void testParse_withBadPort_shouldFail() throws URISyntaxException {
|
||||||
|
SktUri.parse(String.format("OPGPSKT:%s/x%d/%s/SSID:%s",
|
||||||
|
HOST, PORT, Hex.toHexString(PRESHARED_KEY), Hex.toHexString(SSID.getBytes())));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user