Author: Stefano Rivera <stef...@rivera.za.net> Branch: openssl-1.1 Changeset: r87955:7270dc830901 Date: 2016-10-27 00:31 -0700 http://bitbucket.org/pypy/pypy/changeset/7270dc830901/
Log: First pass at OpenSSL 1.1 support diff --git a/pypy/module/_hashlib/interp_hashlib.py b/pypy/module/_hashlib/interp_hashlib.py --- a/pypy/module/_hashlib/interp_hashlib.py +++ b/pypy/module/_hashlib/interp_hashlib.py @@ -58,14 +58,14 @@ def __init__(self, space, name, copy_from=NULL_CTX): self.name = name digest_type = self.digest_type_by_name(space) - self.digest_size = rffi.getintfield(digest_type, 'c_md_size') + self.digest_size = ropenssl.EVP_MD_size(digest_type) # Allocate a lock for each HASH object. # An optimization would be to not release the GIL on small requests, # and use a custom lock only when needed. self.lock = Lock(space) - ctx = lltype.malloc(ropenssl.EVP_MD_CTX.TO, flavor='raw') + ctx = ropenssl.EVP_MD_CTX_new() rgc.add_memory_pressure(ropenssl.HASH_MALLOC_SIZE + self.digest_size) try: if copy_from: @@ -74,7 +74,7 @@ ropenssl.EVP_DigestInit(ctx, digest_type) self.ctx = ctx except: - lltype.free(ctx, flavor='raw') + ropenssl.EVP_MD_CTX_free(ctx) raise self.register_finalizer(space) @@ -82,8 +82,7 @@ ctx = self.ctx if ctx: self.ctx = lltype.nullptr(ropenssl.EVP_MD_CTX.TO) - ropenssl.EVP_MD_CTX_cleanup(ctx) - lltype.free(ctx, flavor='raw') + ropenssl.EVP_MD_CTX_free(ctx) def digest_type_by_name(self, space): digest_type = ropenssl.EVP_get_digestbyname(self.name) @@ -128,21 +127,23 @@ def get_block_size(self, space): digest_type = self.digest_type_by_name(space) - block_size = rffi.getintfield(digest_type, 'c_block_size') + block_size = ropenssl.EVP_MD_block_size(digest_type) return space.wrap(block_size) def get_name(self, space): return space.wrap(self.name) def _digest(self, space): - with lltype.scoped_alloc(ropenssl.EVP_MD_CTX.TO) as ctx: + ctx = ropenssl.EVP_MD_CTX_new() + try: with self.lock: ropenssl.EVP_MD_CTX_copy(ctx, self.ctx) digest_size = self.digest_size with rffi.scoped_alloc_buffer(digest_size) as buf: ropenssl.EVP_DigestFinal(ctx, buf.raw, None) - ropenssl.EVP_MD_CTX_cleanup(ctx) return buf.str(digest_size) + finally: + ropenssl.EVP_MD_CTX_free(ctx) W_Hash.typedef = TypeDef( diff --git a/pypy/module/_hashlib/test/test_hashlib.py b/pypy/module/_hashlib/test/test_hashlib.py --- a/pypy/module/_hashlib/test/test_hashlib.py +++ b/pypy/module/_hashlib/test/test_hashlib.py @@ -15,17 +15,19 @@ def test_attributes(self): import hashlib - for name, expected_size in {'md5': 16, - 'sha1': 20, - 'sha224': 28, - 'sha256': 32, - 'sha384': 48, - 'sha512': 64, - }.items(): + for name, (expected_size, expected_block_size) in { + 'md5': (16, 64), + 'sha1': (20, 64), + 'sha224': (28, 64), + 'sha256': (32, 64), + 'sha384': (48, 128), + 'sha512': (64, 128), + }.items(): h = hashlib.new(name) assert h.name == name assert h.digest_size == expected_size assert h.digestsize == expected_size + assert h.block_size == expected_block_size # h.update('abc') h2 = h.copy() @@ -46,6 +48,7 @@ h = py_new(name)('') assert h.digest_size == expected_size assert h.digestsize == expected_size + assert h.block_size == expected_block_size # h.update('abc') h2 = h.copy() diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py --- a/pypy/module/_ssl/interp_ssl.py +++ b/pypy/module/_ssl/interp_ssl.py @@ -33,9 +33,10 @@ PY_SSL_CLIENT, PY_SSL_SERVER = 0, 1 (PY_SSL_VERSION_SSL2, PY_SSL_VERSION_SSL3, - PY_SSL_VERSION_SSL23, PY_SSL_VERSION_TLS1, PY_SSL_VERSION_TLS1_1, + PY_SSL_VERSION_TLS, PY_SSL_VERSION_TLS1, PY_SSL_VERSION_TLS1_1, PY_SSL_VERSION_TLS1_2) = range(6) + SOCKET_IS_NONBLOCKING, SOCKET_IS_BLOCKING = 0, 1 SOCKET_HAS_TIMED_OUT, SOCKET_HAS_BEEN_CLOSED = 2, 3 SOCKET_TOO_LARGE_FOR_SELECT, SOCKET_OPERATION_OK = 4, 5 @@ -68,11 +69,12 @@ constants["HAS_NPN"] = HAS_NPN constants["HAS_ALPN"] = HAS_ALPN +constants["PROTOCOL_TLS"] = PY_SSL_VERSION_TLS +constants["PROTOCOL_SSLv23"] = PY_SSL_VERSION_TLS # Legacy name if not OPENSSL_NO_SSL2: constants["PROTOCOL_SSLv2"] = PY_SSL_VERSION_SSL2 if not OPENSSL_NO_SSL3: constants["PROTOCOL_SSLv3"] = PY_SSL_VERSION_SSL3 -constants["PROTOCOL_SSLv23"] = PY_SSL_VERSION_SSL23 constants["PROTOCOL_TLSv1"] = PY_SSL_VERSION_TLS1 if HAVE_TLSv1_2: constants["PROTOCOL_TLSv1_1"] = PY_SSL_VERSION_TLS1_1 @@ -637,9 +639,12 @@ if not self.ssl: return space.w_None comp_method = libssl_SSL_get_current_compression(self.ssl) - if not comp_method or intmask(comp_method[0].c_type) == NID_undef: + if not comp_method: return space.w_None - short_name = libssl_OBJ_nid2sn(comp_method[0].c_type) + method_type = intmask(libssl_COMP_get_type(comp_method)) + if method_type == NID_undef: + return space.w_None + short_name = libssl_OBJ_nid2sn(method_type) if not short_name: return space.w_None return space.wrap(rffi.charp2str(short_name)) @@ -795,7 +800,7 @@ for index in range(entry_count): entry = libssl_X509_NAME_get_entry(xname, index) # check to see if we've gotten to a new RDN - entry_level = intmask(entry[0].c_set) + entry_level = intmask(libssl_X509_NAME_ENTRY_set(entry)) if rdn_level >= 0: if rdn_level != entry_level: # yes, new RDN @@ -846,8 +851,9 @@ "No method for internalizing subjectAltName!'") with lltype.scoped_alloc(rffi.CCHARPP.TO, 1) as p_ptr: - p_ptr[0] = ext[0].c_value.c_data - length = intmask(ext[0].c_value.c_length) + ext_value = libssl_X509_EXTENSION_get_data(ext) + p_ptr[0] = ext_value.c_data + length = intmask(ext_value.c_length) null = lltype.nullptr(rffi.VOIDP.TO) if method[0].c_it: names = rffi.cast(GENERAL_NAMES, libssl_ASN1_item_d2i( @@ -967,10 +973,8 @@ if OPENSSL_VERSION_NUMBER >= 0x10001000: # Calls x509v3_cache_extensions and sets up crldp libssl_X509_check_ca(certificate) - dps = certificate[0].c_crldp - else: - dps = rffi.cast(stack_st_DIST_POINT, libssl_X509_get_ext_d2i( - certificate, NID_crl_distribution_points, None, None)) + dps = rffi.cast(stack_st_DIST_POINT, libssl_X509_get_ext_d2i( + certificate, NID_crl_distribution_points, None, None)) if not dps: return None @@ -1268,14 +1272,14 @@ @staticmethod @unwrap_spec(protocol=int) def descr_new(space, w_subtype, protocol): - if protocol == PY_SSL_VERSION_TLS1: + if protocol == PY_SSL_VERSION_TLS: + method = libssl_TLS_method() + elif protocol == PY_SSL_VERSION_TLS1: method = libssl_TLSv1_method() elif protocol == PY_SSL_VERSION_SSL3 and not OPENSSL_NO_SSL3: method = libssl_SSLv3_method() elif protocol == PY_SSL_VERSION_SSL2 and not OPENSSL_NO_SSL2: method = libssl_SSLv2_method() - elif protocol == PY_SSL_VERSION_SSL23: - method = libssl_SSLv23_method() elif protocol == PY_SSL_VERSION_TLS1_1 and HAVE_TLSv1_2: method = libssl_TLSv1_1_method() elif protocol == PY_SSL_VERSION_TLS1_2 and HAVE_TLSv1_2: @@ -1390,20 +1394,22 @@ def descr_get_verify_flags(self, space): store = libssl_SSL_CTX_get_cert_store(self.ctx) - flags = libssl_X509_VERIFY_PARAM_get_flags(store[0].c_param) + param = libssl_X509_STORE_get0_param(store) + flags = libssl_X509_VERIFY_PARAM_get_flags(param) return space.wrap(flags) def descr_set_verify_flags(self, space, w_obj): new_flags = space.int_w(w_obj) store = libssl_SSL_CTX_get_cert_store(self.ctx) - flags = libssl_X509_VERIFY_PARAM_get_flags(store[0].c_param) + param = libssl_X509_STORE_get0_param(store) + flags = libssl_X509_VERIFY_PARAM_get_flags(param) flags_clear = flags & ~new_flags flags_set = ~flags & new_flags if flags_clear and not libssl_X509_VERIFY_PARAM_clear_flags( - store[0].c_param, flags_clear): + param, flags_clear): raise _ssl_seterror(space, None, 0) if flags_set and not libssl_X509_VERIFY_PARAM_set_flags( - store[0].c_param, flags_set): + param, flags_set): raise _ssl_seterror(space, None, 0) def descr_get_check_hostname(self, space): @@ -1614,14 +1620,16 @@ x509 = 0 x509_ca = 0 crl = 0 - for i in range(libssl_sk_X509_OBJECT_num(store[0].c_objs)): - obj = libssl_sk_X509_OBJECT_value(store[0].c_objs, i) - if intmask(obj.c_type) == X509_LU_X509: + objs = libssl_X509_STORE_get0_objects(store) + for i in range(libssl_sk_X509_OBJECT_num(objs)): + obj = libssl_sk_X509_OBJECT_value(objs, i) + obj_type = intmask(libssl_X509_OBJECT_get_type(obj)) + if obj_type == X509_LU_X509: x509 += 1 if libssl_X509_check_ca( - libssl_pypy_X509_OBJECT_data_x509(obj)): + libssl_X509_OBJECT_get0_X509(obj)): x509_ca += 1 - elif intmask(obj.c_type) == X509_LU_CRL: + elif obj_type == X509_LU_CRL: crl += 1 else: # Ignore X509_LU_FAIL, X509_LU_RETRY, X509_LU_PKEY. @@ -1660,13 +1668,14 @@ binary_mode = False rlist = [] store = libssl_SSL_CTX_get_cert_store(self.ctx) - for i in range(libssl_sk_X509_OBJECT_num(store[0].c_objs)): - obj = libssl_sk_X509_OBJECT_value(store[0].c_objs, i) - if intmask(obj.c_type) != X509_LU_X509: + objs = libssl_X509_STORE_get0_objects(store) + for i in range(libssl_sk_X509_OBJECT_num(objs)): + obj = libssl_sk_X509_OBJECT_value(objs, i) + if intmask(libssl_X509_OBJECT_get_type(obj)) != X509_LU_X509: # not a x509 cert continue # CA for any purpose - cert = libssl_pypy_X509_OBJECT_data_x509(obj) + cert = libssl_X509_OBJECT_get0_X509(obj) if not libssl_X509_check_ca(cert): continue if binary_mode: diff --git a/pypy/module/_ssl/test/test_ssl.py b/pypy/module/_ssl/test/test_ssl.py --- a/pypy/module/_ssl/test/test_ssl.py +++ b/pypy/module/_ssl/test/test_ssl.py @@ -77,7 +77,7 @@ if sys.version_info < (2, 7, 9): ss = _ssl.sslwrap(s, 0) else: - ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLSv1) + ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLS) ss = ctx._wrap_socket(s, 0) assert ss.context is ctx exc = raises(_socket.error, ss.do_handshake) @@ -95,7 +95,7 @@ if sys.version_info < (2, 7, 9): ss = _ssl.sslwrap(s, 0) else: - ss = _ssl._SSLContext(_ssl.PROTOCOL_TLSv1)._wrap_socket(s, 0) + ss = _ssl._SSLContext(_ssl.PROTOCOL_TLS)._wrap_socket(s, 0) s.close() exc = raises(_ssl.SSLError, ss.write, "data") assert exc.value.message == 'Underlying socket has been closed.' @@ -123,13 +123,13 @@ def test_context(self): import _ssl - s = _ssl._SSLContext(_ssl.PROTOCOL_TLSv1) + s = _ssl._SSLContext(_ssl.PROTOCOL_TLS) raises(ValueError, _ssl._SSLContext, -1) assert type(s.options) is long - assert s.options & _ssl.OP_NO_SSLv2 - s.options &= ~_ssl.OP_NO_SSLv2 - assert not s.options & _ssl.OP_NO_SSLv2 + assert s.options & _ssl.OP_NO_SSLv3 + s.options &= ~_ssl.OP_NO_SSLv3 + assert not s.options & _ssl.OP_NO_SSLv3 raises(TypeError, "s.options = 2.5") assert not s.check_hostname @@ -159,7 +159,7 @@ def test_set_default_verify_paths(self): import _ssl - s = _ssl._SSLContext(_ssl.PROTOCOL_TLSv1) + s = _ssl._SSLContext(_ssl.PROTOCOL_TLS) s.set_default_verify_paths() @@ -253,13 +253,42 @@ if not _ssl.HAS_NPN: skip("NPN requires OpenSSL 1.0.1 or greater") - ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLSv1) + ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLS) ctx._set_npn_protocols(b'\x08http/1.1\x06spdy/2') ss = ctx._wrap_socket(self.s._sock, True, server_hostname="svn.python.org") self.s.close() del ss; gc.collect() + def test_peer_certificate(self): + import _ssl, gc + ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLS) + ss = ctx._wrap_socket(self.s._sock, False) + ss.do_handshake() + assert isinstance(ss.peer_certificate(der=True), bytes) + assert isinstance(ss.peer_certificate(), dict) + self.s.close() + del ss; gc.collect() + + def test_peer_certificate_verify(self): + import _ssl, ssl, gc + paths = ssl.get_default_verify_paths() + + ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLS) + ctx.verify_mode = _ssl.CERT_REQUIRED + ctx.load_verify_locations(capath=paths.capath, cafile=paths.cafile) + + ss = ctx._wrap_socket(self.s._sock, False) + try: + ss.do_handshake() + except _ssl.SSLError as e: + if e.reason == 'CERTIFICATE_VERIFY_FAILED': + skip("Certificate verification failed. " + "Most likely we just don't have any CA certificates.") + assert ss.peer_certificate() + self.s.close() + del ss; gc.collect() + def test_tls_unique_cb(self): import ssl, sys, gc ss = ssl.wrap_socket(self.s) @@ -325,7 +354,7 @@ def test_load_cert_chain(self): import _ssl, errno - ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLSv1) + ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLS) ctx.load_cert_chain(self.keycert) ctx.load_cert_chain(self.cert, self.key) exc = raises(IOError, ctx.load_cert_chain, "inexistent.pem") @@ -344,11 +373,11 @@ def test_load_verify_locations(self): import _ssl - ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLSv1) + ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLS) ctx.load_verify_locations(self.keycert) ctx.load_verify_locations(cafile=self.keycert, capath=None) - ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLSv1) + ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLS) with open(self.keycert) as f: cacert_pem = f.read().decode('ascii') ctx.load_verify_locations(cadata=cacert_pem) @@ -356,7 +385,7 @@ def test_get_ca_certs(self): import _ssl - ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLSv1) + ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLS) ctx.load_verify_locations(self.keycert) assert ctx.get_ca_certs() == [] ctx.load_verify_locations(self.python_org_cert) @@ -370,7 +399,7 @@ def test_cert_store_stats(self): import _ssl - ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLSv1) + ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLS) assert ctx.cert_store_stats() == {'x509_ca': 0, 'crl': 0, 'x509': 0} ctx.load_cert_chain(self.keycert) assert ctx.cert_store_stats() == {'x509_ca': 0, 'crl': 0, 'x509': 0} @@ -379,7 +408,7 @@ def test_load_dh_params(self): import _ssl, errno - ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLSv1) + ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLS) ctx.load_dh_params(self.dh512) raises(TypeError, ctx.load_dh_params) raises(TypeError, ctx.load_dh_params, None) @@ -389,7 +418,7 @@ def test_set_ecdh_curve(self): import _ssl - ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLSv1) + ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLS) ctx.set_ecdh_curve("prime256v1") raises(ValueError, ctx.set_ecdh_curve, "foo") @@ -434,7 +463,7 @@ def test_lib_reason(self): # Test the library and reason attributes import _ssl - ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLSv1) + ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLS) exc = raises(_ssl.SSLError, ctx.load_dh_params, self.keycert) assert exc.value.library == 'PEM' assert exc.value.reason == 'NO_START_LINE' @@ -445,7 +474,7 @@ # Check that the appropriate SSLError subclass is raised # (this only tests one of them) import _ssl, _socket - ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLSv1) + ctx = _ssl._SSLContext(_ssl.PROTOCOL_TLS) s = _socket.socket() try: s.bind(("127.0.0.1", 0)) diff --git a/rpython/rlib/ropenssl.py b/rpython/rlib/ropenssl.py --- a/rpython/rlib/ropenssl.py +++ b/rpython/rlib/ropenssl.py @@ -57,8 +57,21 @@ '#define pypy_GENERAL_NAME_dirn(name) (name->d.dirn)', '#define pypy_GENERAL_NAME_uri(name) (name->d.uniformResourceIdentifier)', '#define pypy_GENERAL_NAME_pop_free(names) (sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free))', - '#define pypy_X509_OBJECT_data_x509(obj) (obj->data.x509)', '#define pypy_DIST_POINT_fullname(obj) (obj->distpoint->name.fullname)', + # Backwards compatibility for functions introduced in 1.1 + '#if (OPENSSL_VERSION_NUMBER < 0x10100000)', + '# define X509_OBJECT_get0_X509(obj) (obj->data.x509)', + '# define X509_OBJECT_get_type(obj) (obj->type)', + '# define COMP_get_type(meth) (meth->type)', + '# define X509_NAME_ENTRY_set(ne) (ne->set)', + '# define X509_STORE_get0_objects(store) (store->objs)', + '# define X509_STORE_get0_param(store) (store->param)', + '# define TLS_method SSLv23_method', + '# define EVP_MD_CTX_new EVP_MD_CTX_create', + '# define EVP_MD_CTX_free EVP_MD_CTX_destroy', + '#else /* (OPENSSL_VERSION_NUMBER < 0x10100000) */', + '# define OPENSSL_NO_SSL2', + '#endif /* (OPENSSL_VERSION_NUMBER < 0x10100000) */', ], ) @@ -88,6 +101,7 @@ "OPENSSL_EXPORT_VAR_AS_FUNCTION") OPENSSL_VERSION_NUMBER = rffi_platform.ConstantInteger( "OPENSSL_VERSION_NUMBER") + LIBRESSL = rffi_platform.Defined("LIBRESSL_VERSION_NUMBER") cconfig = rffi_platform.configure(CConfigBootstrap) if cconfig["OPENSSL_EXPORT_VAR_AS_FUNCTION"]: @@ -95,23 +109,9 @@ else: ASN1_ITEM_EXP = ASN1_ITEM OPENSSL_VERSION_NUMBER = cconfig["OPENSSL_VERSION_NUMBER"] +LIBRESSL = cconfig["LIBRESSL"] HAVE_TLSv1_2 = OPENSSL_VERSION_NUMBER >= 0x10001000 -if (OPENSSL_VERSION_NUMBER >= 0x10100000 and - OPENSSL_VERSION_NUMBER < 0x20000000): # <= libressl :-( - eci.pre_include_bits = () - eci.post_include_bits = () - raise Exception("""OpenSSL version >= 1.1 not supported yet. - - This program requires OpenSSL version 1.0.x, and may also - work with LibreSSL or OpenSSL 0.9.x. OpenSSL 1.1 is quite - some work to update to; contributions are welcome. Sorry, - you need to install an older version of OpenSSL for now. - Make sure this older version is the one picked up by this - program when it runs the compiler. - - This is the configuration used: %r""" % (eci,)) - class CConfig: _compilation_info_ = eci @@ -139,7 +139,7 @@ SSL_OP_SINGLE_ECDH_USE = rffi_platform.ConstantInteger( "SSL_OP_SINGLE_ECDH_USE") SSL_OP_NO_COMPRESSION = rffi_platform.DefinedConstantInteger( - "SSL_OP_NO_COMPRESSION") + "SSL_OP_NO_COMPRESSION") SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS = rffi_platform.ConstantInteger( "SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS") SSL_OP_CIPHER_SERVER_PREFERENCE = rffi_platform.ConstantInteger( @@ -210,28 +210,10 @@ OBJ_NAME_TYPE_MD_METH = rffi_platform.ConstantInteger( "OBJ_NAME_TYPE_MD_METH") - if OPENSSL_VERSION_NUMBER >= 0x10001000: - X509_st = rffi_platform.Struct( - 'struct x509_st', - [('crldp', stack_st_DIST_POINT)]) - # Some structures, with only the fields used in the _ssl module - X509_name_entry_st = rffi_platform.Struct('struct X509_name_entry_st', - [('set', rffi.INT)]) asn1_string_st = rffi_platform.Struct('struct asn1_string_st', [('length', rffi.INT), ('data', rffi.CCHARP)]) - X509_extension_st = rffi_platform.Struct( - 'struct X509_extension_st', - [('value', ASN1_STRING)]) - x509_store_st = rffi_platform.Struct( - 'struct x509_store_st', - [('objs', stack_st_X509_OBJECT), - ('param', X509_VERIFY_PARAM)]) - x509_object_st = rffi_platform.Struct( - 'struct x509_object_st', - [('type', rffi.INT)]) - X509_LU_X509 = rffi_platform.ConstantInteger("X509_LU_X509") X509_LU_CRL = rffi_platform.ConstantInteger("X509_LU_CRL") @@ -244,12 +226,6 @@ GENERAL_NAME_st = rffi_platform.Struct( 'struct GENERAL_NAME_st', [('type', rffi.INT)]) - EVP_MD_st = rffi_platform.Struct( - 'EVP_MD', - [('md_size', rffi.INT), - ('block_size', rffi.INT)]) - EVP_MD_SIZE = rffi_platform.SizeOf('EVP_MD') - EVP_MD_CTX_SIZE = rffi_platform.SizeOf('EVP_MD_CTX') OBJ_NAME_st = rffi_platform.Struct( 'OBJ_NAME', @@ -257,10 +233,6 @@ ('name', rffi.CCHARP), ]) - COMP_METHOD_st = rffi_platform.Struct( - 'struct comp_method_st', - [('type', rffi.INT),]) - ACCESS_DESCRIPTION_st = rffi_platform.Struct( 'struct ACCESS_DESCRIPTION_st', [('method', ASN1_OBJECT), @@ -275,14 +247,12 @@ SSL_CIPHER = rffi.COpaquePtr('SSL_CIPHER') SSL = rffi.COpaquePtr('SSL') BIO = rffi.COpaquePtr('BIO') -if OPENSSL_VERSION_NUMBER >= 0x10001000: - X509 = rffi.CArrayPtr(X509_st) -else: - X509 = rffi.COpaquePtr('X509') -X509_NAME_ENTRY = rffi.CArrayPtr(X509_name_entry_st) -X509_EXTENSION = rffi.CArrayPtr(X509_extension_st) -X509_STORE = rffi.CArrayPtr(x509_store_st) -X509_OBJECT = lltype.Ptr(x509_object_st) +X509 = rffi.COpaquePtr('X509') +X509_OBJECT = rffi.COpaquePtr('X509_OBJECT') +COMP_METHOD = rffi.COpaquePtr('COMP_METHOD') +X509_NAME_ENTRY = rffi.COpaquePtr('X509_NAME_ENTRY') +X509_EXTENSION = rffi.COpaquePtr('X509_EXTENSION') +X509_STORE = rffi.COpaquePtr('X509_STORE') X509V3_EXT_METHOD = rffi.CArrayPtr(v3_ext_method) ASN1_STRING.TO.become(asn1_string_st) ASN1_TIME = rffi.COpaquePtr('ASN1_TIME') @@ -290,9 +260,9 @@ GENERAL_NAMES = rffi.COpaquePtr('GENERAL_NAMES') GENERAL_NAME.TO.become(GENERAL_NAME_st) OBJ_NAME = rffi.CArrayPtr(OBJ_NAME_st) -COMP_METHOD = rffi.CArrayPtr(COMP_METHOD_st) ACCESS_DESCRIPTION = rffi.CArrayPtr(ACCESS_DESCRIPTION_st) + HAVE_OPENSSL_RAND = OPENSSL_VERSION_NUMBER >= 0x0090500f HAVE_OPENSSL_FINISHED = OPENSSL_VERSION_NUMBER >= 0x0090500f HAVE_SSL_CTX_CLEAR_OPTIONS = OPENSSL_VERSION_NUMBER >= 0x009080df and \ @@ -314,8 +284,10 @@ globals()['libssl_' + name] = external( name, argtypes, restype, **kw) -ssl_external('SSL_load_error_strings', [], lltype.Void) -ssl_external('SSL_library_init', [], rffi.INT) +ssl_external('SSL_load_error_strings', [], lltype.Void, + macro=bool(OPENSSL_VERSION_NUMBER >= 0x10100000 and not LIBRESSL) or None) +ssl_external('SSL_library_init', [], rffi.INT, + macro=bool(OPENSSL_VERSION_NUMBER >= 0x10100000 and not LIBRESSL) or None) ssl_external('CRYPTO_num_locks', [], rffi.INT) ssl_external('CRYPTO_set_locking_callback', [lltype.Ptr(lltype.FuncType( @@ -341,7 +313,8 @@ ssl_external('TLSv1_2_method', [], SSL_METHOD) ssl_external('SSLv2_method', [], SSL_METHOD) ssl_external('SSLv3_method', [], SSL_METHOD) -ssl_external('SSLv23_method', [], SSL_METHOD) +ssl_external('TLS_method', [], SSL_METHOD, + macro=bool(OPENSSL_VERSION_NUMBER < 0x10100000) or None) ssl_external('SSL_CTX_use_PrivateKey_file', [SSL_CTX, rffi.CCHARP, rffi.INT], rffi.INT, save_err=rffi.RFFI_FULL_ERRNO_ZERO) ssl_external('SSL_CTX_use_certificate_chain_file', [SSL_CTX, rffi.CCHARP], rffi.INT, @@ -416,6 +389,8 @@ ssl_external('X509_NAME_get_entry', [X509_NAME, rffi.INT], X509_NAME_ENTRY) ssl_external('X509_NAME_ENTRY_get_object', [X509_NAME_ENTRY], ASN1_OBJECT) ssl_external('X509_NAME_ENTRY_get_data', [X509_NAME_ENTRY], ASN1_STRING) +ssl_external('X509_NAME_ENTRY_set', [X509_NAME_ENTRY], rffi.INT, + macro=bool(OPENSSL_VERSION_NUMBER < 0x10100000) or None) ssl_external('i2d_X509', [X509, rffi.CCHARPP], rffi.INT, save_err=SAVE_ERR) ssl_external('X509_free', [X509], lltype.Void, releasegil=False) ssl_external('X509_check_ca', [X509], rffi.INT) @@ -427,11 +402,16 @@ ssl_external('X509_get_ext', [X509, rffi.INT], X509_EXTENSION) ssl_external('X509_get_ext_d2i', [X509, rffi.INT, rffi.VOIDP, rffi.VOIDP], rffi.VOIDP) ssl_external('X509V3_EXT_get', [X509_EXTENSION], X509V3_EXT_METHOD) +ssl_external('X509_EXTENSION_get_data', [X509_EXTENSION], ASN1_STRING) ssl_external('X509_VERIFY_PARAM_get_flags', [X509_VERIFY_PARAM], rffi.ULONG) ssl_external('X509_VERIFY_PARAM_set_flags', [X509_VERIFY_PARAM, rffi.ULONG], rffi.INT) ssl_external('X509_VERIFY_PARAM_clear_flags', [X509_VERIFY_PARAM, rffi.ULONG], rffi.INT) ssl_external('X509_STORE_add_cert', [X509_STORE, X509], rffi.INT) +ssl_external('X509_STORE_get0_objects', [X509_STORE], stack_st_X509_OBJECT, + macro=bool(OPENSSL_VERSION_NUMBER < 0x10100000) or None) +ssl_external('X509_STORE_get0_param', [X509_STORE], X509_VERIFY_PARAM, + macro=bool(OPENSSL_VERSION_NUMBER < 0x10100000) or None) ssl_external('X509_get_default_cert_file_env', [], rffi.CCHARP) ssl_external('X509_get_default_cert_file', [], rffi.CCHARP) @@ -468,8 +448,12 @@ macro=True) ssl_external('sk_X509_OBJECT_value', [stack_st_X509_OBJECT, rffi.INT], X509_OBJECT, macro=True) -ssl_external('pypy_X509_OBJECT_data_x509', [X509_OBJECT], X509, - macro=True) +ssl_external('X509_OBJECT_get0_X509', [X509_OBJECT], X509, + macro=bool(OPENSSL_VERSION_NUMBER < 0x10100000) or None) +ssl_external('X509_OBJECT_get_type', [X509_OBJECT], rffi.INT, + macro=bool(OPENSSL_VERSION_NUMBER < 0x10100000) or None) +ssl_external('COMP_get_type', [COMP_METHOD], rffi.INT, + macro=bool(OPENSSL_VERSION_NUMBER < 0x10100000) or None) ssl_external('sk_DIST_POINT_num', [stack_st_DIST_POINT], rffi.INT, macro=True) ssl_external('sk_DIST_POINT_value', [stack_st_DIST_POINT, rffi.INT], DIST_POINT, @@ -511,8 +495,7 @@ # with the GIL held, and so is allowed to run in a RPython __del__ method. ssl_external('SSL_free', [SSL], lltype.Void, releasegil=False) ssl_external('SSL_CTX_free', [SSL_CTX], lltype.Void, releasegil=False) -ssl_external('CRYPTO_free', [rffi.VOIDP], lltype.Void) -libssl_OPENSSL_free = libssl_CRYPTO_free +ssl_external('OPENSSL_free', [rffi.VOIDP], lltype.Void, macro=True) ssl_external('SSL_write', [SSL, rffi.CCHARP, rffi.INT], rffi.INT, save_err=SAVE_ERR) @@ -576,10 +559,11 @@ SSL, rffi.CCHARPP, rffi.UINTP], lltype.Void) EVP_MD_CTX = rffi.COpaquePtr('EVP_MD_CTX', compilation_info=eci) -EVP_MD = lltype.Ptr(EVP_MD_st) +EVP_MD = rffi.COpaquePtr('EVP_MD') OpenSSL_add_all_digests = external( - 'OpenSSL_add_all_digests', [], lltype.Void) + 'OpenSSL_add_all_digests', [], lltype.Void, + macro=bool(OPENSSL_VERSION_NUMBER >= 0x10100000 and not LIBRESSL) or None) EVP_get_digestbyname = external( 'EVP_get_digestbyname', [rffi.CCHARP], EVP_MD) @@ -592,10 +576,18 @@ EVP_DigestFinal = external( 'EVP_DigestFinal', [EVP_MD_CTX, rffi.CCHARP, rffi.VOIDP], rffi.INT) +EVP_MD_size = external( + 'EVP_MD_size', [EVP_MD], rffi.INT) +EVP_MD_block_size = external( + 'EVP_MD_block_size', [EVP_MD], rffi.INT) EVP_MD_CTX_copy = external( 'EVP_MD_CTX_copy', [EVP_MD_CTX, EVP_MD_CTX], rffi.INT) -EVP_MD_CTX_cleanup = external( - 'EVP_MD_CTX_cleanup', [EVP_MD_CTX], rffi.INT, releasegil=False) +EVP_MD_CTX_new = external( + 'EVP_MD_CTX_new', [], EVP_MD_CTX, + macro=bool(OPENSSL_VERSION_NUMBER < 0x10100000) or None) +EVP_MD_CTX_free = external( + 'EVP_MD_CTX_free', [EVP_MD_CTX], lltype.Void, releasegil=False, + macro=bool(OPENSSL_VERSION_NUMBER < 0x10100000) or None) OBJ_NAME_CALLBACK = lltype.Ptr(lltype.FuncType( [OBJ_NAME, rffi.VOIDP], lltype.Void)) @@ -606,7 +598,7 @@ # Used for adding memory pressure. Last number is an (under?)estimate of # EVP_PKEY_CTX's size. # XXX: Make a better estimate here -HASH_MALLOC_SIZE = EVP_MD_SIZE + EVP_MD_CTX_SIZE \ +HASH_MALLOC_SIZE = 120 + 48 \ + rffi.sizeof(EVP_MD) * 2 + 208 def init_ssl(): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit