hack to make PskKeyManager work on newer Android
This commit is contained in:
parent
54eb1efa13
commit
938081f125
2 changed files with 78 additions and 49 deletions
|
@ -31,8 +31,6 @@ import java.net.NoRouteToHostException;
|
|||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
@ -40,22 +38,16 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import android.net.PskKeyManager;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.RequiresApi;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
import javax.net.ssl.SSLServerSocket;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import timber.log.Timber;
|
||||
|
||||
|
||||
|
@ -159,7 +151,7 @@ public class KeyTransferInteractor {
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
SSLContext sslContext = createTlsPskSslContext(presharedKey);
|
||||
SSLContext sslContext = TlsPskCompat.createTlsPskSslContext(presharedKey);
|
||||
|
||||
Socket socket = null;
|
||||
try {
|
||||
|
@ -225,18 +217,6 @@ public class KeyTransferInteractor {
|
|||
return socket;
|
||||
}
|
||||
|
||||
private static SSLContext createTlsPskSslContext(byte[] presharedKey) {
|
||||
try {
|
||||
PresharedKeyManager pskKeyManager = new PresharedKeyManager(presharedKey);
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(new KeyManager[] { pskKeyManager }, new TrustManager[0], null);
|
||||
|
||||
return sslContext;
|
||||
} catch (KeyManagementException | NoSuchAlgorithmException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleOpenConnection(Socket socket) throws IOException {
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||
OutputStream outputStream = new BufferedOutputStream(socket.getOutputStream());
|
||||
|
@ -443,34 +423,6 @@ public class KeyTransferInteractor {
|
|||
return "";
|
||||
}
|
||||
|
||||
private static class PresharedKeyManager extends PskKeyManager implements KeyManager {
|
||||
byte[] presharedKey;
|
||||
|
||||
private PresharedKeyManager(byte[] presharedKey) {
|
||||
this.presharedKey = presharedKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String chooseClientKeyIdentity(String identityHint, Socket socket) {
|
||||
return identityHint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String chooseClientKeyIdentity(String identityHint, SSLEngine engine) {
|
||||
return identityHint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecretKey getKey(String identityHint, String identity, Socket socket) {
|
||||
return new SecretKeySpec(presharedKey, "AES");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecretKey getKey(String identityHint, String identity, SSLEngine engine) {
|
||||
return new SecretKeySpec(presharedKey, "AES");
|
||||
}
|
||||
}
|
||||
|
||||
private static void closeQuietly(Closeable closeable) {
|
||||
try {
|
||||
if (closeable != null) {
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
package org.sufficientlysecure.keychain.network;
|
||||
|
||||
|
||||
import java.net.Socket;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import android.os.Build.VERSION_CODES;
|
||||
import android.support.annotation.RequiresApi;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import javax.net.ssl.TrustManager;
|
||||
|
||||
|
||||
@RequiresApi(api = VERSION_CODES.LOLLIPOP)
|
||||
class TlsPskCompat {
|
||||
|
||||
static SSLContext createTlsPskSslContext(byte[] presharedKey) {
|
||||
try {
|
||||
PresharedKeyManager pskKeyManager = new PresharedKeyManager(presharedKey);
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(new KeyManager[] { pskKeyManager }, new TrustManager[0], null);
|
||||
|
||||
return sslContext;
|
||||
} catch (KeyManagementException | NoSuchAlgorithmException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
/* This class is a KeyManager that is compatible to TlsPskManager.
|
||||
*
|
||||
* Due to the way conscrypt works internally, this class will be internally duck typed to
|
||||
* PSKKeyManager. This is quite a hack, and relies on conscrypt internals to work - but it
|
||||
* works.
|
||||
*
|
||||
* see also:
|
||||
* https://github.com/google/conscrypt/blob/b23e9353ed4e3256379d660cb09491a69b21affb/common/src/main/java/org/conscrypt/SSLParametersImpl.java#L494
|
||||
* https://github.com/google/conscrypt/blob/29916ef38dc9cb4e4c6e3fdb87d4e921546d3ef4/common/src/main/java/org/conscrypt/DuckTypedPSKKeyManager.java#L51
|
||||
*
|
||||
*/
|
||||
private static class PresharedKeyManager implements KeyManager {
|
||||
byte[] presharedKey;
|
||||
|
||||
private PresharedKeyManager(byte[] presharedKey) {
|
||||
this.presharedKey = presharedKey;
|
||||
}
|
||||
|
||||
public String chooseServerKeyIdentityHint(Socket socket) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String chooseServerKeyIdentityHint(SSLEngine engine) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String chooseClientKeyIdentity(String identityHint, Socket socket) {
|
||||
return identityHint;
|
||||
}
|
||||
|
||||
public String chooseClientKeyIdentity(String identityHint, SSLEngine engine) {
|
||||
return identityHint;
|
||||
}
|
||||
|
||||
public SecretKey getKey(String identityHint, String identity, Socket socket) {
|
||||
return new SecretKeySpec(presharedKey, "AES");
|
||||
}
|
||||
|
||||
public SecretKey getKey(String identityHint, String identity, SSLEngine engine) {
|
||||
return new SecretKeySpec(presharedKey, "AES");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue