[pypy-commit] pypy default: handle OpenSSL v1.1, in _ssl, add post_handshake_auth for TLSv1_3
mattip
pypy.commits at gmail.com
Sat Dec 14 16:46:08 EST 2019
Author: Matti Picus <matti.picus at gmail.com>
Branch:
Changeset: r98287:826708d0c629
Date: 2019-12-14 23:33 +0200
http://bitbucket.org/pypy/pypy/changeset/826708d0c629/
Log: handle OpenSSL v1.1, in _ssl, add post_handshake_auth for TLSv1_3
(grafted from a56889d5df88dc57c7385151b1f54f644c34c2da)
diff --git a/lib_pypy/_cffi_ssl/_cffi_src/openssl/ssl.py b/lib_pypy/_cffi_ssl/_cffi_src/openssl/ssl.py
--- a/lib_pypy/_cffi_ssl/_cffi_src/openssl/ssl.py
+++ b/lib_pypy/_cffi_ssl/_cffi_src/openssl/ssl.py
@@ -76,6 +76,7 @@
static const long SSL_OP_SINGLE_DH_USE;
static const long SSL_OP_EPHEMERAL_RSA;
static const long SSL_OP_MICROSOFT_SESS_ID_BUG;
+static const long SSL_OP_ENABLE_MIDDLEBOX_COMPAT;
static const long SSL_OP_NETSCAPE_CHALLENGE_BUG;
static const long SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG;
static const long SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG;
diff --git a/lib_pypy/_cffi_ssl/_stdssl/__init__.py b/lib_pypy/_cffi_ssl/_stdssl/__init__.py
--- a/lib_pypy/_cffi_ssl/_stdssl/__init__.py
+++ b/lib_pypy/_cffi_ssl/_stdssl/__init__.py
@@ -83,6 +83,9 @@
OP_NO_SSLv2 = lib.SSL_OP_NO_SSLv2
OP_NO_SSLv3 = lib.SSL_OP_NO_SSLv3
OP_NO_TLSv1_3 = lib.SSL_OP_NO_TLSv1_3
+if OPENSSL_VERSION_INFO > (1, 1, 0, 0, 0):
+ OP_ENABLE_MIDDLEBOX_COMPAT = lib.SSL_OP_ENABLE_MIDDLEBOX_COMPAT
+
SSL_CLIENT = 0
@@ -265,6 +268,20 @@
mode |= lib.SSL_MODE_AUTO_RETRY
lib.SSL_set_mode(ssl, mode)
+ if HAS_TLSv1_3:
+ if sslctx._post_handshake_auth:
+ if socket_type == SSL_SERVER:
+ # bpo-37428: OpenSSL does not ignore SSL_VERIFY_POST_HANDSHAKE.
+ # Set SSL_VERIFY_POST_HANDSHAKE flag only for server sockets and
+ # only in combination with SSL_VERIFY_PEER flag.
+ mode = lib.SSL_CTX_get_verify_mode(lib.SSL_get_SSL_CTX(self.ssl))
+ if (mode & lib.SSL_VERIFY_PEER):
+ verify_cb = lib.SSL_get_verify_callback(self.ssl)
+ mode |= lib.SSL_VERIFY_POST_HANDSHAKE
+ lib.SSL_set_verify(ssl, mode, verify_cb)
+ else:
+ lib.SSL_set_post_handshake_auth(ssl, 1)
+
if HAS_SNI and self.server_hostname:
name = _str_to_ffi_buffer(self.server_hostname)
lib.SSL_set_tlsext_host_name(ssl, name)
@@ -652,6 +669,15 @@
else:
return None
+ def verify_client_post_handshake(self):
+
+ if not HAS_TLSv1_3:
+ raise NotImplementedError("Post-handshake auth is not supported by "
+ "your OpenSSL version.")
+ err = lib.SSL_verify_client_post_handshake(self.ssl);
+ if err == 0:
+ raise pyssl_error(self, err)
+
def pending(self):
count = lib.SSL_pending(self.ssl)
if count < 0:
@@ -708,6 +734,7 @@
return bool(lib.SSL_session_reused(self.ssl))
+
def _fs_decode(name):
return name.decode(sys.getfilesystemencoding())
def _fs_converter(name):
@@ -763,13 +790,13 @@
if OPENSSL_VERSION_INFO > (1, 1, 0, 0, 0):
aead = lib.SSL_CIPHER_is_aead(cipher)
nid = lib.SSL_CIPHER_get_cipher_nid(cipher)
- skcipher = OBJ_nid2ln(nid) if nid != NID_undef else None
+ skcipher = lib.OBJ_nid2ln(nid) if nid != lib.NID_undef else None
nid = lib.SSL_CIPHER_get_digest_nid(cipher);
- digest = OBJ_nid2ln(nid) if nid != NID_undef else None
+ digest = lib.OBJ_nid2ln(nid) if nid != lib.NID_undef else None
nid = lib.SSL_CIPHER_get_kx_nid(cipher);
- kx = OBJ_nid2ln(nid) if nid != NID_undef else None
- nid = SSL_CIPHER_get_auth_nid(cipher);
- auth = OBJ_nid2ln(nid) if nid != NID_undef else None
+ kx = lib.OBJ_nid2ln(nid) if nid != lib.NID_undef else None
+ nid = lib.SSL_CIPHER_get_auth_nid(cipher);
+ auth = lib.OBJ_nid2ln(nid) if nid != lib.NID_undef else None
ret.update({'aead' : bool(aead),
'symmmetric' : skcipher,
'digest' : digest,
@@ -829,9 +856,8 @@
class _SSLContext(object):
__slots__ = ('ctx', '_check_hostname', 'servername_callback',
'alpn_protocols', '_alpn_protocols_handle',
- 'npn_protocols', 'set_hostname',
+ 'npn_protocols', 'set_hostname', '_post_handshake_auth',
'_set_hostname_handle', '_npn_protocols_handle')
-
def __new__(cls, protocol):
self = object.__new__(cls)
self.ctx = ffi.NULL
@@ -908,6 +934,9 @@
if lib.Cryptography_HAS_X509_V_FLAG_TRUSTED_FIRST:
store = lib.SSL_CTX_get_cert_store(self.ctx)
lib.X509_STORE_set_flags(store, lib.X509_V_FLAG_TRUSTED_FIRST)
+ if HAS_TLSv1_3:
+ self.post_handshake_auth = 0;
+ lib.SSL_CTX_set_post_handshake_auth(self.ctx, self.post_handshake_auth)
return self
@property
@@ -993,6 +1022,7 @@
"CERT_OPTIONAL or CERT_REQUIRED")
self._check_hostname = check_hostname
+
def set_ciphers(self, cipherlist):
cipherlistbuf = _str_to_ffi_buffer(cipherlist)
ret = lib.SSL_CTX_set_cipher_list(self.ctx, cipherlistbuf)
@@ -1329,6 +1359,25 @@
sock = _SSLSocket._new__ssl_socket(self, None, server_side, hostname, incoming, outgoing)
return sock
+ @property
+ def post_handshake_auth(self):
+ if HAS_TLSv1_3:
+ return bool(self._post_handshake_auth)
+ return None
+
+ @post_handshake_auth.setter
+ def post_handshake_auth(self, arg):
+ if arg is None:
+ raise AttributeError("cannot delete attribute")
+
+ pha = bool(arg)
+ self._post_handshake_auth = pha;
+
+ # bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for
+ # server sockets and SSL_set_post_handshake_auth() for client
+
+ return 0;
+
# cryptography constraint: OPENSSL_NO_TLSEXT will never be set!
More information about the pypy-commit
mailing list