1package eu.siacs.conversations.crypto.sasl;
2
3import org.conscrypt.Conscrypt;
4
5import javax.net.ssl.SSLException;
6import javax.net.ssl.SSLSocket;
7
8import eu.siacs.conversations.entities.Account;
9
10abstract class ScramPlusMechanism extends ScramMechanism {
11
12 private static final String EXPORTER_LABEL = "EXPORTER-Channel-Binding";
13
14 ScramPlusMechanism(Account account, ChannelBinding channelBinding) {
15 super(account, channelBinding);
16 }
17
18 @Override
19 protected byte[] getChannelBindingData(final SSLSocket sslSocket)
20 throws AuthenticationException {
21 if (sslSocket == null) {
22 throw new AuthenticationException("Channel binding attempt on non secure socket");
23 }
24 if (this.channelBinding == ChannelBinding.TLS_EXPORTER) {
25 final byte[] keyingMaterial;
26 try {
27 keyingMaterial =
28 Conscrypt.exportKeyingMaterial(sslSocket, EXPORTER_LABEL, new byte[0], 32);
29 } catch (final SSLException e) {
30 throw new AuthenticationException("Could not export keying material");
31 }
32 if (keyingMaterial == null) {
33 throw new AuthenticationException(
34 "Could not export keying material. Socket not ready");
35 }
36 return keyingMaterial;
37 } else if (this.channelBinding == ChannelBinding.TLS_UNIQUE) {
38 final byte[] unique = Conscrypt.getTlsUnique(sslSocket);
39 if (unique == null) {
40 throw new AuthenticationException(
41 "Could not retrieve tls unique. Socket not ready");
42 }
43 return unique;
44 } else {
45 throw new AuthenticationException(
46 String.format("%s is not a valid channel binding", ChannelBinding.NONE));
47 }
48 }
49}