Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/iNPUTmice/Conversations.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Gultsch <daniel@gultsch.de>2022-09-07 12:08:54 +0300
committerDaniel Gultsch <daniel@gultsch.de>2022-09-07 12:08:54 +0300
commit018e0d9edfd212c866063e04297a59b500b2c393 (patch)
treecfaf820dec084f0cb94f61265a96d22b3643d1b4
parentd4ec1eaf3878dc1f43f1bf81124731de64537bfd (diff)
add (inactive) channel binding end-point code
-rw-r--r--src/main/java/eu/siacs/conversations/crypto/sasl/ScramPlusMechanism.java63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/main/java/eu/siacs/conversations/crypto/sasl/ScramPlusMechanism.java b/src/main/java/eu/siacs/conversations/crypto/sasl/ScramPlusMechanism.java
index 8f6dec20e..8de4524f2 100644
--- a/src/main/java/eu/siacs/conversations/crypto/sasl/ScramPlusMechanism.java
+++ b/src/main/java/eu/siacs/conversations/crypto/sasl/ScramPlusMechanism.java
@@ -1,11 +1,24 @@
package eu.siacs.conversations.crypto.sasl;
+import android.util.Log;
+
+import org.bouncycastle.jcajce.provider.digest.SHA256;
import org.conscrypt.Conscrypt;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
+import eu.siacs.conversations.Config;
import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.utils.CryptoHelper;
abstract class ScramPlusMechanism extends ScramMechanism {
@@ -41,9 +54,59 @@ abstract class ScramPlusMechanism extends ScramMechanism {
"Could not retrieve tls unique. Socket not ready");
}
return unique;
+ } else if (this.channelBinding == ChannelBinding.TLS_SERVER_END_POINT) {
+ final byte[] endPoint = getServerEndPointChannelBinding(sslSocket.getSession());
+ Log.d(Config.LOGTAG, "retrieved endpoint " + CryptoHelper.bytesToHex(endPoint));
+ return endPoint;
} else {
throw new AuthenticationException(
String.format("%s is not a valid channel binding", ChannelBinding.NONE));
}
}
+
+ private byte[] getServerEndPointChannelBinding(final SSLSession session)
+ throws AuthenticationException {
+ final Certificate[] certificates;
+ try {
+ certificates = session.getPeerCertificates();
+ } catch (final SSLPeerUnverifiedException e) {
+ throw new AuthenticationException("Could not verify peer certificates");
+ }
+ if (certificates == null || certificates.length == 0) {
+ throw new AuthenticationException("Could not retrieve peer certificate");
+ }
+ final X509Certificate certificate;
+ if (certificates[0] instanceof X509Certificate) {
+ certificate = (X509Certificate) certificates[0];
+ } else {
+ throw new AuthenticationException("Certificate was not X509");
+ }
+ final String algorithm = certificate.getSigAlgName();
+ final int withIndex = algorithm.indexOf("with");
+ if (withIndex <= 0) {
+ throw new AuthenticationException("Unable to parse SigAlgName");
+ }
+ final String hashAlgorithm = algorithm.substring(0, withIndex);
+ final MessageDigest messageDigest;
+ // https://www.rfc-editor.org/rfc/rfc5929#section-4.1
+ if ("MD5".equalsIgnoreCase(hashAlgorithm) || "SHA1".equalsIgnoreCase(hashAlgorithm)) {
+ messageDigest = new SHA256.Digest();
+ } else {
+ try {
+ messageDigest = MessageDigest.getInstance(hashAlgorithm);
+ } catch (final NoSuchAlgorithmException e) {
+ throw new AuthenticationException(
+ "Could not instantiate message digest for " + hashAlgorithm);
+ }
+ }
+ Log.d(Config.LOGTAG, "hashing certificate with " + messageDigest.getAlgorithm());
+ final byte[] encodedCertificate;
+ try {
+ encodedCertificate = certificate.getEncoded();
+ } catch (final CertificateEncodingException e) {
+ throw new AuthenticationException("Could not encode certificate");
+ }
+ messageDigest.update(encodedCertificate);
+ return messageDigest.digest();
+ }
}