[pypy-commit] pypy openssl-1.1: First pass at OpenSSL 1.1 support
stefanor
pypy.commits at gmail.com
Thu Oct 27 03:36:58 EDT 2016
Author: Stefano Rivera <stefano at 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():
More information about the pypy-commit
mailing list