support channel binding with tls-exporter

This commit is contained in:
Daniel Gultsch 2022-09-06 16:43:51 +02:00
parent 5da9f5b3a3
commit 6d3d9dfe26
4 changed files with 32 additions and 15 deletions

View file

@ -18,6 +18,14 @@ public abstract class SaslMechanism {
this.account = account; this.account = account;
} }
public static String namespace(final Version version) {
if (version == Version.SASL) {
return Namespace.SASL;
} else {
return Namespace.SASL_2;
}
}
/** /**
* The priority is used to pin the authentication mechanism. If authentication fails, it MAY be * The priority is used to pin the authentication mechanism. If authentication fails, it MAY be
* retried with another mechanism of the same priority, but MUST NOT be tried with a mechanism * retried with another mechanism of the same priority, but MUST NOT be tried with a mechanism
@ -97,6 +105,9 @@ public abstract class SaslMechanism {
final Collection<String> mechanisms, final Collection<ChannelBinding> bindings) { final Collection<String> mechanisms, final Collection<ChannelBinding> bindings) {
if (mechanisms.contains(External.MECHANISM) && account.getPrivateKeyAlias() != null) { if (mechanisms.contains(External.MECHANISM) && account.getPrivateKeyAlias() != null) {
return new External(account); return new External(account);
} else if (mechanisms.contains(ScramSha1Plus.MECHANISM)
&& bindings.contains(ChannelBinding.TLS_EXPORTER)) {
return new ScramSha1Plus(account, ChannelBinding.TLS_EXPORTER);
} else if (mechanisms.contains(ScramSha512.MECHANISM)) { } else if (mechanisms.contains(ScramSha512.MECHANISM)) {
return new ScramSha512(account); return new ScramSha512(account);
} else if (mechanisms.contains(ScramSha256.MECHANISM)) { } else if (mechanisms.contains(ScramSha256.MECHANISM)) {
@ -115,12 +126,4 @@ public abstract class SaslMechanism {
} }
} }
} }
public static String namespace(final Version version) {
if (version == Version.SASL) {
return Namespace.SASL;
} else {
return Namespace.SASL_2;
}
}
} }

View file

@ -258,7 +258,8 @@ abstract class ScramMechanism extends SaslMechanism {
} }
} }
protected byte[] getChannelBindingData(final SSLSocket sslSocket) throws AuthenticationException { protected byte[] getChannelBindingData(final SSLSocket sslSocket)
throws AuthenticationException {
if (this.channelBinding == ChannelBinding.NONE) { if (this.channelBinding == ChannelBinding.NONE) {
return new byte[0]; return new byte[0];
} }

View file

@ -1,22 +1,35 @@
package eu.siacs.conversations.crypto.sasl; package eu.siacs.conversations.crypto.sasl;
import org.conscrypt.Conscrypt;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocket;
import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Account;
abstract class ScramPlusMechanism extends ScramMechanism { abstract class ScramPlusMechanism extends ScramMechanism {
private static final String EXPORTER_LABEL = "EXPORTER-Channel-Binding";
ScramPlusMechanism(Account account, ChannelBinding channelBinding) { ScramPlusMechanism(Account account, ChannelBinding channelBinding) {
super(account, channelBinding); super(account, channelBinding);
} }
@Override @Override
protected byte[] getChannelBindingData(final SSLSocket sslSocket) throws AuthenticationException { protected byte[] getChannelBindingData(final SSLSocket sslSocket)
if (this.channelBinding == ChannelBinding.NONE) { throws AuthenticationException {
throw new AuthenticationException(String.format("%s is not a valid channel binding", ChannelBinding.NONE));
}
if (sslSocket == null) { if (sslSocket == null) {
throw new AuthenticationException("Channel binding attempt on non secure socket"); throw new AuthenticationException("Channel binding attempt on non secure socket");
} }
throw new AssertionError("not yet implemented"); if (this.channelBinding == ChannelBinding.TLS_EXPORTER) {
try {
return Conscrypt.exportKeyingMaterial(sslSocket, EXPORTER_LABEL, new byte[0], 32);
} catch (final SSLException e) {
throw new AuthenticationException("Could not export keying material");
}
} else {
throw new AuthenticationException(
String.format("%s is not a valid channel binding", ChannelBinding.NONE));
}
} }
} }