1import OpenSSL 2import OpenSSL._util as pyOpenSSLutil 3 4from scrapy.utils.python import to_unicode 5 6 7# The OpenSSL symbol is present since 1.1.1 but it's not currently supported in any version of pyOpenSSL. 8# Using the binding directly, as this code does, requires cryptography 2.4. 9SSL_OP_NO_TLSv1_3 = getattr(pyOpenSSLutil.lib, 'SSL_OP_NO_TLSv1_3', 0) 10 11 12def ffi_buf_to_string(buf): 13 return to_unicode(pyOpenSSLutil.ffi.string(buf)) 14 15 16def x509name_to_string(x509name): 17 # from OpenSSL.crypto.X509Name.__repr__ 18 result_buffer = pyOpenSSLutil.ffi.new("char[]", 512) 19 pyOpenSSLutil.lib.X509_NAME_oneline(x509name._name, result_buffer, len(result_buffer)) 20 21 return ffi_buf_to_string(result_buffer) 22 23 24def get_temp_key_info(ssl_object): 25 if not hasattr(pyOpenSSLutil.lib, 'SSL_get_server_tmp_key'): # requires OpenSSL 1.0.2 26 return None 27 28 # adapted from OpenSSL apps/s_cb.c::ssl_print_tmp_key() 29 temp_key_p = pyOpenSSLutil.ffi.new("EVP_PKEY **") 30 if not pyOpenSSLutil.lib.SSL_get_server_tmp_key(ssl_object, temp_key_p): 31 return None 32 temp_key = temp_key_p[0] 33 if temp_key == pyOpenSSLutil.ffi.NULL: 34 return None 35 temp_key = pyOpenSSLutil.ffi.gc(temp_key, pyOpenSSLutil.lib.EVP_PKEY_free) 36 key_info = [] 37 key_type = pyOpenSSLutil.lib.EVP_PKEY_id(temp_key) 38 if key_type == pyOpenSSLutil.lib.EVP_PKEY_RSA: 39 key_info.append('RSA') 40 elif key_type == pyOpenSSLutil.lib.EVP_PKEY_DH: 41 key_info.append('DH') 42 elif key_type == pyOpenSSLutil.lib.EVP_PKEY_EC: 43 key_info.append('ECDH') 44 ec_key = pyOpenSSLutil.lib.EVP_PKEY_get1_EC_KEY(temp_key) 45 ec_key = pyOpenSSLutil.ffi.gc(ec_key, pyOpenSSLutil.lib.EC_KEY_free) 46 nid = pyOpenSSLutil.lib.EC_GROUP_get_curve_name(pyOpenSSLutil.lib.EC_KEY_get0_group(ec_key)) 47 cname = pyOpenSSLutil.lib.EC_curve_nid2nist(nid) 48 if cname == pyOpenSSLutil.ffi.NULL: 49 cname = pyOpenSSLutil.lib.OBJ_nid2sn(nid) 50 key_info.append(ffi_buf_to_string(cname)) 51 else: 52 key_info.append(ffi_buf_to_string(pyOpenSSLutil.lib.OBJ_nid2sn(key_type))) 53 key_info.append(f'{pyOpenSSLutil.lib.EVP_PKEY_bits(temp_key)} bits') 54 return ', '.join(key_info) 55 56 57def get_openssl_version(): 58 system_openssl = OpenSSL.SSL.SSLeay_version( 59 OpenSSL.SSL.SSLEAY_VERSION 60 ).decode('ascii', errors='replace') 61 return f'{OpenSSL.version.__version__} ({system_openssl})' 62