do not attempt unique/exporter channel binding on non conscrypt sockets
This commit is contained in:
parent
e5cffa11be
commit
9ad5b68d57
|
@ -10,15 +10,15 @@ import com.google.common.collect.BiMap;
|
|||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.utils.SSLSockets;
|
||||
import eu.siacs.conversations.xml.Element;
|
||||
import eu.siacs.conversations.xml.Namespace;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public enum ChannelBinding {
|
||||
NONE,
|
||||
TLS_EXPORTER,
|
||||
|
@ -104,22 +104,17 @@ public enum ChannelBinding {
|
|||
}
|
||||
|
||||
private static String shortName(final ChannelBinding channelBinding) {
|
||||
switch (channelBinding) {
|
||||
case TLS_UNIQUE:
|
||||
return "UNIQ";
|
||||
case TLS_EXPORTER:
|
||||
return "EXPR";
|
||||
case TLS_SERVER_END_POINT:
|
||||
return "ENDP";
|
||||
case NONE:
|
||||
return "NONE";
|
||||
default:
|
||||
throw new AssertionError("Missing short name for " + channelBinding);
|
||||
}
|
||||
return switch (channelBinding) {
|
||||
case TLS_UNIQUE -> "UNIQ";
|
||||
case TLS_EXPORTER -> "EXPR";
|
||||
case TLS_SERVER_END_POINT -> "ENDP";
|
||||
case NONE -> "NONE";
|
||||
default -> throw new AssertionError("Missing short name for " + channelBinding);
|
||||
};
|
||||
}
|
||||
|
||||
public static int priority(final ChannelBinding channelBinding) {
|
||||
if (Arrays.asList(TLS_EXPORTER,TLS_UNIQUE).contains(channelBinding)) {
|
||||
if (Arrays.asList(TLS_EXPORTER, TLS_UNIQUE).contains(channelBinding)) {
|
||||
return 2;
|
||||
} else if (channelBinding == ChannelBinding.TLS_SERVER_END_POINT) {
|
||||
return 1;
|
||||
|
|
|
@ -20,12 +20,18 @@ public interface ChannelBindingMechanism {
|
|||
|
||||
ChannelBinding getChannelBinding();
|
||||
|
||||
static byte[] getChannelBindingData(final SSLSocket sslSocket, final ChannelBinding channelBinding)
|
||||
static byte[] getChannelBindingData(
|
||||
final SSLSocket sslSocket, final ChannelBinding channelBinding)
|
||||
throws SaslMechanism.AuthenticationException {
|
||||
if (sslSocket == null) {
|
||||
throw new SaslMechanism.AuthenticationException("Channel binding attempt on non secure socket");
|
||||
throw new SaslMechanism.AuthenticationException(
|
||||
"Channel binding attempt on non secure socket");
|
||||
}
|
||||
if (channelBinding == ChannelBinding.TLS_EXPORTER) {
|
||||
if (!Conscrypt.isConscrypt(sslSocket)) {
|
||||
throw new SaslMechanism.AuthenticationException(
|
||||
"Channel binding attempt on non supporting socket");
|
||||
}
|
||||
final byte[] keyingMaterial;
|
||||
try {
|
||||
keyingMaterial =
|
||||
|
@ -39,6 +45,10 @@ public interface ChannelBindingMechanism {
|
|||
}
|
||||
return keyingMaterial;
|
||||
} else if (channelBinding == ChannelBinding.TLS_UNIQUE) {
|
||||
if (!Conscrypt.isConscrypt(sslSocket)) {
|
||||
throw new SaslMechanism.AuthenticationException(
|
||||
"Channel binding attempt on non supporting socket");
|
||||
}
|
||||
final byte[] unique = Conscrypt.getTlsUnique(sslSocket);
|
||||
if (unique == null) {
|
||||
throw new SaslMechanism.AuthenticationException(
|
||||
|
@ -99,8 +109,7 @@ public interface ChannelBindingMechanism {
|
|||
}
|
||||
|
||||
static int getPriority(final SaslMechanism mechanism) {
|
||||
if (mechanism instanceof ChannelBindingMechanism) {
|
||||
final ChannelBindingMechanism channelBindingMechanism = (ChannelBindingMechanism) mechanism;
|
||||
if (mechanism instanceof ChannelBindingMechanism channelBindingMechanism) {
|
||||
return ChannelBinding.priority(channelBindingMechanism.getChannelBinding());
|
||||
} else {
|
||||
return 0;
|
||||
|
|
|
@ -7,6 +7,9 @@ import androidx.annotation.RequiresApi;
|
|||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
|
||||
import org.conscrypt.Conscrypt;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
@ -24,22 +27,19 @@ import javax.net.ssl.SSLParameters;
|
|||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
|
||||
public class SSLSockets {
|
||||
|
||||
public static void setSecurity(final SSLSocket sslSocket) {
|
||||
final String[] supportProtocols;
|
||||
final Collection<String> supportedProtocols = new LinkedList<>(
|
||||
Arrays.asList(sslSocket.getSupportedProtocols()));
|
||||
final Collection<String> supportedProtocols =
|
||||
new LinkedList<>(Arrays.asList(sslSocket.getSupportedProtocols()));
|
||||
supportedProtocols.remove("SSLv3");
|
||||
supportProtocols = supportedProtocols.toArray(new String[0]);
|
||||
|
||||
sslSocket.setEnabledProtocols(supportProtocols);
|
||||
|
||||
final String[] cipherSuites = CryptoHelper.getOrderedCipherSuites(
|
||||
sslSocket.getSupportedCipherSuites());
|
||||
final String[] cipherSuites =
|
||||
CryptoHelper.getOrderedCipherSuites(sslSocket.getSupportedCipherSuites());
|
||||
if (cipherSuites.length > 0) {
|
||||
sslSocket.setEnabledCipherSuites(cipherSuites);
|
||||
}
|
||||
|
@ -70,7 +70,8 @@ public class SSLSockets {
|
|||
socket.setSSLParameters(parameters);
|
||||
}
|
||||
|
||||
private static void setApplicationProtocolReflection(final SSLSocket socket, final String protocol) {
|
||||
private static void setApplicationProtocolReflection(
|
||||
final SSLSocket socket, final String protocol) {
|
||||
try {
|
||||
final Method method = socket.getClass().getMethod("setAlpnProtocols", byte[].class);
|
||||
// the concatenation of 8-bit, length prefixed protocol names, just one in our case...
|
||||
|
@ -78,16 +79,17 @@ public class SSLSockets {
|
|||
final byte[] protocolUTF8Bytes = protocol.getBytes(StandardCharsets.UTF_8);
|
||||
final byte[] lengthPrefixedProtocols = new byte[protocolUTF8Bytes.length + 1];
|
||||
lengthPrefixedProtocols[0] = (byte) protocol.length(); // cannot be over 255 anyhow
|
||||
System.arraycopy(protocolUTF8Bytes, 0, lengthPrefixedProtocols, 1, protocolUTF8Bytes.length);
|
||||
method.invoke(socket, new Object[]{lengthPrefixedProtocols});
|
||||
System.arraycopy(
|
||||
protocolUTF8Bytes, 0, lengthPrefixedProtocols, 1, protocolUTF8Bytes.length);
|
||||
method.invoke(socket, new Object[] {lengthPrefixedProtocols});
|
||||
} catch (Throwable e) {
|
||||
Log.e(Config.LOGTAG,"unable to set ALPN on socket",e);
|
||||
Log.e(Config.LOGTAG, "unable to set ALPN on socket", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setApplicationProtocol(final SSLSocket socket, final String protocol) {
|
||||
if (Conscrypt.isConscrypt(socket)) {
|
||||
Conscrypt.setApplicationProtocols(socket, new String[]{protocol});
|
||||
Conscrypt.setApplicationProtocols(socket, new String[] {protocol});
|
||||
} else {
|
||||
setApplicationProtocolReflection(socket, protocol);
|
||||
}
|
||||
|
@ -113,9 +115,12 @@ public class SSLSockets {
|
|||
}
|
||||
|
||||
public static Version version(final Socket socket) {
|
||||
if (socket instanceof SSLSocket) {
|
||||
final SSLSocket sslSocket = (SSLSocket) socket;
|
||||
return Version.of(sslSocket.getSession().getProtocol());
|
||||
if (socket instanceof SSLSocket sslSocket) {
|
||||
if (Conscrypt.isConscrypt(sslSocket)) {
|
||||
return Version.of(sslSocket.getSession().getProtocol());
|
||||
} else {
|
||||
return Version.TLS_UNSUPPORTED_VERSION;
|
||||
}
|
||||
} else {
|
||||
return Version.NONE;
|
||||
}
|
||||
|
@ -126,22 +131,17 @@ public class SSLSockets {
|
|||
TLS_1_1,
|
||||
TLS_1_2,
|
||||
TLS_1_3,
|
||||
UNKNOWN,
|
||||
TLS_UNSUPPORTED_VERSION,
|
||||
NONE;
|
||||
|
||||
private static Version of(final String protocol) {
|
||||
switch (Strings.nullToEmpty(protocol)) {
|
||||
case "TLSv1":
|
||||
return TLS_1_0;
|
||||
case "TLSv1.1":
|
||||
return TLS_1_1;
|
||||
case "TLSv1.2":
|
||||
return TLS_1_2;
|
||||
case "TLSv1.3":
|
||||
return TLS_1_3;
|
||||
default:
|
||||
return UNKNOWN;
|
||||
}
|
||||
return switch (Strings.nullToEmpty(protocol)) {
|
||||
case "TLSv1" -> TLS_1_0;
|
||||
case "TLSv1.1" -> TLS_1_1;
|
||||
case "TLSv1.2" -> TLS_1_2;
|
||||
case "TLSv1.3" -> TLS_1_3;
|
||||
default -> TLS_UNSUPPORTED_VERSION;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue