ssl.py 2.4 KB

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