Issue #12551: Provide a get_channel_binding() method on SSL sockets so as
to get channel binding data for the current SSL session (only the
"tls-unique" channel binding is implemented).  This allows the
implementation of certain authentication mechanisms such as SCRAM-SHA-1-PLUS.

Patch by Jacek Konieczny.
diff --git a/Lib/ssl.py b/Lib/ssl.py
index cde99fc..914e749 100644
--- a/Lib/ssl.py
+++ b/Lib/ssl.py
@@ -99,6 +99,10 @@
 import traceback
 import errno
 
+if _ssl.HAS_TLS_UNIQUE:
+    CHANNEL_BINDING_TYPES = ['tls-unique']
+else:
+    CHANNEL_BINDING_TYPES = []
 
 class CertificateError(ValueError):
     pass
@@ -495,6 +499,21 @@
                               self.do_handshake_on_connect),
                 addr)
 
+    def get_channel_binding(self, cb_type="tls-unique"):
+        """Get channel binding data for current connection.  Raise ValueError
+        if the requested `cb_type` is not supported.  Return bytes of the data
+        or None if the data is not available (e.g. before the handshake).
+        """
+        if cb_type not in CHANNEL_BINDING_TYPES:
+            raise ValueError("Unsupported channel binding type")
+        if cb_type != "tls-unique":
+            raise NotImplementedError(
+                            "{0} channel binding type not implemented"
+                            .format(cb_type))
+        if self._sslobj is None:
+            return None
+        return self._sslobj.tls_unique_cb()
+
     def __del__(self):
         # sys.stderr.write("__del__ on %s\n" % repr(self))
         self._real_close()