PageRenderTime 24ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/pypy/rlib/ropenssl.py

https://bitbucket.org/pypy/pypy/
Python | 293 lines | 249 code | 33 blank | 11 comment | 8 complexity | 6ed692ecfdb8a995a3859fa72b26aa2d MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from pypy.rpython.lltypesystem import rffi, lltype
  2. from pypy.rpython.tool import rffi_platform
  3. from pypy.translator.platform import platform
  4. from pypy.translator.tool.cbuild import ExternalCompilationInfo
  5. import sys
  6. if sys.platform == 'win32' and platform.name != 'mingw32':
  7. libraries = ['libeay32', 'ssleay32',
  8. 'user32', 'advapi32', 'gdi32', 'msvcrt', 'ws2_32']
  9. includes = [
  10. # ssl.h includes winsock.h, which will conflict with our own
  11. # need of winsock2. Remove this when separate compilation is
  12. # available...
  13. 'winsock2.h',
  14. # wincrypt.h defines X509_NAME, include it here
  15. # so that openssl/ssl.h can repair this nonsense.
  16. 'wincrypt.h']
  17. else:
  18. libraries = ['ssl', 'crypto']
  19. includes = []
  20. includes += [
  21. 'openssl/ssl.h',
  22. 'openssl/err.h',
  23. 'openssl/rand.h',
  24. 'openssl/evp.h',
  25. 'openssl/ossl_typ.h',
  26. 'openssl/x509v3.h']
  27. eci = ExternalCompilationInfo(
  28. libraries = libraries,
  29. includes = includes,
  30. export_symbols = [],
  31. post_include_bits = [
  32. # Unnamed structures are not supported by rffi_platform.
  33. # So we replace an attribute access with a macro call.
  34. '#define pypy_GENERAL_NAME_dirn(name) (name->d.dirn)',
  35. ],
  36. )
  37. eci = rffi_platform.configure_external_library(
  38. 'openssl', eci,
  39. [dict(prefix='openssl-',
  40. include_dir='inc32', library_dir='out32'),
  41. ])
  42. # WinSock does not use a bitmask in select, and uses
  43. # socket handles greater than FD_SETSIZE
  44. if sys.platform == 'win32':
  45. MAX_FD_SIZE = None
  46. else:
  47. from pypy.rlib._rsocket_rffi import FD_SETSIZE as MAX_FD_SIZE
  48. ASN1_STRING = lltype.Ptr(lltype.ForwardReference())
  49. ASN1_ITEM = rffi.COpaquePtr('ASN1_ITEM')
  50. X509_NAME = rffi.COpaquePtr('X509_NAME')
  51. class CConfig:
  52. _compilation_info_ = eci
  53. OPENSSL_VERSION_NUMBER = rffi_platform.ConstantInteger(
  54. "OPENSSL_VERSION_NUMBER")
  55. SSLEAY_VERSION = rffi_platform.DefinedConstantString(
  56. "SSLEAY_VERSION", "SSLeay_version(SSLEAY_VERSION)")
  57. OPENSSL_NO_SSL2 = rffi_platform.Defined("OPENSSL_NO_SSL2")
  58. SSL_FILETYPE_PEM = rffi_platform.ConstantInteger("SSL_FILETYPE_PEM")
  59. SSL_OP_ALL = rffi_platform.ConstantInteger("SSL_OP_ALL")
  60. SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS = rffi_platform.ConstantInteger(
  61. "SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS")
  62. SSL_VERIFY_NONE = rffi_platform.ConstantInteger("SSL_VERIFY_NONE")
  63. SSL_VERIFY_PEER = rffi_platform.ConstantInteger("SSL_VERIFY_PEER")
  64. SSL_VERIFY_FAIL_IF_NO_PEER_CERT = rffi_platform.ConstantInteger("SSL_VERIFY_FAIL_IF_NO_PEER_CERT")
  65. SSL_ERROR_WANT_READ = rffi_platform.ConstantInteger(
  66. "SSL_ERROR_WANT_READ")
  67. SSL_ERROR_WANT_WRITE = rffi_platform.ConstantInteger(
  68. "SSL_ERROR_WANT_WRITE")
  69. SSL_ERROR_ZERO_RETURN = rffi_platform.ConstantInteger(
  70. "SSL_ERROR_ZERO_RETURN")
  71. SSL_ERROR_WANT_X509_LOOKUP = rffi_platform.ConstantInteger(
  72. "SSL_ERROR_WANT_X509_LOOKUP")
  73. SSL_ERROR_WANT_CONNECT = rffi_platform.ConstantInteger(
  74. "SSL_ERROR_WANT_CONNECT")
  75. SSL_ERROR_SYSCALL = rffi_platform.ConstantInteger("SSL_ERROR_SYSCALL")
  76. SSL_ERROR_SSL = rffi_platform.ConstantInteger("SSL_ERROR_SSL")
  77. SSL_RECEIVED_SHUTDOWN = rffi_platform.ConstantInteger(
  78. "SSL_RECEIVED_SHUTDOWN")
  79. SSL_MODE_AUTO_RETRY = rffi_platform.ConstantInteger("SSL_MODE_AUTO_RETRY")
  80. NID_subject_alt_name = rffi_platform.ConstantInteger("NID_subject_alt_name")
  81. GEN_DIRNAME = rffi_platform.ConstantInteger("GEN_DIRNAME")
  82. CRYPTO_LOCK = rffi_platform.ConstantInteger("CRYPTO_LOCK")
  83. # Some structures, with only the fields used in the _ssl module
  84. X509_name_entry_st = rffi_platform.Struct('struct X509_name_entry_st',
  85. [('set', rffi.INT)])
  86. asn1_string_st = rffi_platform.Struct('struct asn1_string_st',
  87. [('length', rffi.INT),
  88. ('data', rffi.CCHARP)])
  89. X509_extension_st = rffi_platform.Struct(
  90. 'struct X509_extension_st',
  91. [('value', ASN1_STRING)])
  92. ASN1_ITEM_EXP = lltype.FuncType([], ASN1_ITEM)
  93. X509V3_EXT_D2I = lltype.FuncType([rffi.VOIDP, rffi.CCHARPP, rffi.LONG],
  94. rffi.VOIDP)
  95. v3_ext_method = rffi_platform.Struct(
  96. 'struct v3_ext_method',
  97. [('it', lltype.Ptr(ASN1_ITEM_EXP)),
  98. ('d2i', lltype.Ptr(X509V3_EXT_D2I))])
  99. GENERAL_NAME_st = rffi_platform.Struct(
  100. 'struct GENERAL_NAME_st',
  101. [('type', rffi.INT),
  102. ])
  103. EVP_MD_st = rffi_platform.Struct(
  104. 'EVP_MD',
  105. [('md_size', rffi.INT),
  106. ('block_size', rffi.INT)])
  107. EVP_MD_SIZE = rffi_platform.SizeOf('EVP_MD')
  108. EVP_MD_CTX_SIZE = rffi_platform.SizeOf('EVP_MD_CTX')
  109. for k, v in rffi_platform.configure(CConfig).items():
  110. globals()[k] = v
  111. # opaque structures
  112. SSL_METHOD = rffi.COpaquePtr('SSL_METHOD')
  113. SSL_CTX = rffi.COpaquePtr('SSL_CTX')
  114. SSL_CIPHER = rffi.COpaquePtr('SSL_CIPHER')
  115. SSL = rffi.COpaquePtr('SSL')
  116. BIO = rffi.COpaquePtr('BIO')
  117. X509 = rffi.COpaquePtr('X509')
  118. X509_NAME_ENTRY = rffi.CArrayPtr(X509_name_entry_st)
  119. X509_EXTENSION = rffi.CArrayPtr(X509_extension_st)
  120. X509V3_EXT_METHOD = rffi.CArrayPtr(v3_ext_method)
  121. ASN1_OBJECT = rffi.COpaquePtr('ASN1_OBJECT')
  122. ASN1_STRING.TO.become(asn1_string_st)
  123. ASN1_TIME = rffi.COpaquePtr('ASN1_TIME')
  124. ASN1_INTEGER = rffi.COpaquePtr('ASN1_INTEGER')
  125. GENERAL_NAMES = rffi.COpaquePtr('GENERAL_NAMES')
  126. GENERAL_NAME = rffi.CArrayPtr(GENERAL_NAME_st)
  127. HAVE_OPENSSL_RAND = OPENSSL_VERSION_NUMBER >= 0x0090500f
  128. def external(name, argtypes, restype, **kw):
  129. kw['compilation_info'] = eci
  130. if not kw.get('macro', False):
  131. eci.export_symbols += (name,)
  132. return rffi.llexternal(
  133. name, argtypes, restype, **kw)
  134. def ssl_external(name, argtypes, restype, **kw):
  135. globals()['libssl_' + name] = external(
  136. name, argtypes, restype, **kw)
  137. ssl_external('SSL_load_error_strings', [], lltype.Void)
  138. ssl_external('SSL_library_init', [], rffi.INT)
  139. ssl_external('CRYPTO_num_locks', [], rffi.INT)
  140. ssl_external('CRYPTO_set_locking_callback',
  141. [lltype.Ptr(lltype.FuncType(
  142. [rffi.INT, rffi.INT, rffi.CCHARP, rffi.INT], lltype.Void))],
  143. lltype.Void)
  144. ssl_external('CRYPTO_set_id_callback',
  145. [lltype.Ptr(lltype.FuncType([], rffi.LONG))],
  146. lltype.Void)
  147. if HAVE_OPENSSL_RAND:
  148. ssl_external('RAND_add', [rffi.CCHARP, rffi.INT, rffi.DOUBLE], lltype.Void)
  149. ssl_external('RAND_status', [], rffi.INT)
  150. ssl_external('RAND_egd', [rffi.CCHARP], rffi.INT)
  151. ssl_external('SSL_CTX_new', [SSL_METHOD], SSL_CTX)
  152. ssl_external('SSL_get_SSL_CTX', [SSL], SSL_CTX)
  153. ssl_external('TLSv1_method', [], SSL_METHOD)
  154. ssl_external('SSLv2_method', [], SSL_METHOD)
  155. ssl_external('SSLv3_method', [], SSL_METHOD)
  156. ssl_external('SSLv23_method', [], SSL_METHOD)
  157. ssl_external('SSL_CTX_use_PrivateKey_file', [SSL_CTX, rffi.CCHARP, rffi.INT], rffi.INT)
  158. ssl_external('SSL_CTX_use_certificate_chain_file', [SSL_CTX, rffi.CCHARP], rffi.INT)
  159. ssl_external('SSL_CTX_set_options', [SSL_CTX, rffi.INT], rffi.INT, macro=True)
  160. ssl_external('SSL_CTX_ctrl', [SSL_CTX, rffi.INT, rffi.INT, rffi.VOIDP], rffi.INT)
  161. ssl_external('SSL_CTX_set_verify', [SSL_CTX, rffi.INT, rffi.VOIDP], lltype.Void)
  162. ssl_external('SSL_CTX_get_verify_mode', [SSL_CTX], rffi.INT)
  163. ssl_external('SSL_CTX_set_cipher_list', [SSL_CTX, rffi.CCHARP], rffi.INT)
  164. ssl_external('SSL_CTX_load_verify_locations', [SSL_CTX, rffi.CCHARP, rffi.CCHARP], rffi.INT)
  165. ssl_external('SSL_new', [SSL_CTX], SSL)
  166. ssl_external('SSL_set_fd', [SSL, rffi.INT], rffi.INT)
  167. ssl_external('SSL_set_mode', [SSL, rffi.INT], rffi.INT, macro=True)
  168. ssl_external('SSL_ctrl', [SSL, rffi.INT, rffi.INT, rffi.VOIDP], rffi.INT)
  169. ssl_external('BIO_ctrl', [BIO, rffi.INT, rffi.INT, rffi.VOIDP], rffi.INT)
  170. ssl_external('SSL_get_rbio', [SSL], BIO)
  171. ssl_external('SSL_get_wbio', [SSL], BIO)
  172. ssl_external('SSL_set_connect_state', [SSL], lltype.Void)
  173. ssl_external('SSL_set_accept_state', [SSL], lltype.Void)
  174. ssl_external('SSL_connect', [SSL], rffi.INT)
  175. ssl_external('SSL_do_handshake', [SSL], rffi.INT)
  176. ssl_external('SSL_shutdown', [SSL], rffi.INT)
  177. ssl_external('SSL_get_error', [SSL, rffi.INT], rffi.INT)
  178. ssl_external('SSL_get_shutdown', [SSL], rffi.INT)
  179. ssl_external('SSL_set_read_ahead', [SSL, rffi.INT], lltype.Void)
  180. ssl_external('SSL_get_peer_certificate', [SSL], X509)
  181. ssl_external('X509_get_subject_name', [X509], X509_NAME)
  182. ssl_external('X509_get_issuer_name', [X509], X509_NAME)
  183. ssl_external('X509_NAME_oneline', [X509_NAME, rffi.CCHARP, rffi.INT], rffi.CCHARP)
  184. ssl_external('X509_NAME_entry_count', [X509_NAME], rffi.INT)
  185. ssl_external('X509_NAME_get_entry', [X509_NAME, rffi.INT], X509_NAME_ENTRY)
  186. ssl_external('X509_NAME_ENTRY_get_object', [X509_NAME_ENTRY], ASN1_OBJECT)
  187. ssl_external('X509_NAME_ENTRY_get_data', [X509_NAME_ENTRY], ASN1_STRING)
  188. ssl_external('i2d_X509', [X509, rffi.CCHARPP], rffi.INT)
  189. ssl_external('X509_free', [X509], lltype.Void)
  190. ssl_external('X509_get_notBefore', [X509], ASN1_TIME, macro=True)
  191. ssl_external('X509_get_notAfter', [X509], ASN1_TIME, macro=True)
  192. ssl_external('X509_get_serialNumber', [X509], ASN1_INTEGER)
  193. ssl_external('X509_get_version', [X509], rffi.INT, macro=True)
  194. ssl_external('X509_get_ext_by_NID', [X509, rffi.INT, rffi.INT], rffi.INT)
  195. ssl_external('X509_get_ext', [X509, rffi.INT], X509_EXTENSION)
  196. ssl_external('X509V3_EXT_get', [X509_EXTENSION], X509V3_EXT_METHOD)
  197. ssl_external('OBJ_obj2txt',
  198. [rffi.CCHARP, rffi.INT, ASN1_OBJECT, rffi.INT], rffi.INT)
  199. ssl_external('ASN1_STRING_to_UTF8', [rffi.CCHARPP, ASN1_STRING], rffi.INT)
  200. ssl_external('ASN1_TIME_print', [BIO, ASN1_TIME], rffi.INT)
  201. ssl_external('i2a_ASN1_INTEGER', [BIO, ASN1_INTEGER], rffi.INT)
  202. ssl_external('ASN1_item_d2i',
  203. [rffi.VOIDP, rffi.CCHARPP, rffi.LONG, ASN1_ITEM], rffi.VOIDP)
  204. ssl_external('ASN1_ITEM_ptr', [rffi.VOIDP], ASN1_ITEM, macro=True)
  205. ssl_external('sk_GENERAL_NAME_num', [GENERAL_NAMES], rffi.INT,
  206. macro=True)
  207. ssl_external('sk_GENERAL_NAME_value', [GENERAL_NAMES, rffi.INT], GENERAL_NAME,
  208. macro=True)
  209. ssl_external('GENERAL_NAME_print', [BIO, GENERAL_NAME], rffi.INT)
  210. ssl_external('pypy_GENERAL_NAME_dirn', [GENERAL_NAME], X509_NAME,
  211. macro=True)
  212. ssl_external('SSL_get_current_cipher', [SSL], SSL_CIPHER)
  213. ssl_external('SSL_CIPHER_get_name', [SSL_CIPHER], rffi.CCHARP)
  214. ssl_external('SSL_CIPHER_get_version', [SSL_CIPHER], rffi.CCHARP)
  215. ssl_external('SSL_CIPHER_get_bits', [SSL_CIPHER, rffi.INTP], rffi.INT)
  216. ssl_external('ERR_get_error', [], rffi.INT)
  217. ssl_external('ERR_error_string', [rffi.ULONG, rffi.CCHARP], rffi.CCHARP)
  218. ssl_external('SSL_free', [SSL], lltype.Void)
  219. ssl_external('SSL_CTX_free', [SSL_CTX], lltype.Void)
  220. ssl_external('CRYPTO_free', [rffi.VOIDP], lltype.Void)
  221. libssl_OPENSSL_free = libssl_CRYPTO_free
  222. ssl_external('SSL_write', [SSL, rffi.CCHARP, rffi.INT], rffi.INT)
  223. ssl_external('SSL_pending', [SSL], rffi.INT)
  224. ssl_external('SSL_read', [SSL, rffi.CCHARP, rffi.INT], rffi.INT)
  225. BIO_METHOD = rffi.COpaquePtr('BIO_METHOD')
  226. ssl_external('BIO_s_mem', [], BIO_METHOD)
  227. ssl_external('BIO_s_file', [], BIO_METHOD)
  228. ssl_external('BIO_new', [BIO_METHOD], BIO)
  229. ssl_external('BIO_set_nbio', [BIO, rffi.INT], rffi.INT, macro=True)
  230. ssl_external('BIO_free', [BIO], rffi.INT)
  231. ssl_external('BIO_reset', [BIO], rffi.INT, macro=True)
  232. ssl_external('BIO_read_filename', [BIO, rffi.CCHARP], rffi.INT, macro=True)
  233. ssl_external('BIO_gets', [BIO, rffi.CCHARP, rffi.INT], rffi.INT)
  234. ssl_external('PEM_read_bio_X509_AUX',
  235. [BIO, rffi.VOIDP, rffi.VOIDP, rffi.VOIDP], X509)
  236. EVP_MD_CTX = rffi.COpaquePtr('EVP_MD_CTX', compilation_info=eci)
  237. EVP_MD = lltype.Ptr(EVP_MD_st)
  238. OpenSSL_add_all_digests = external(
  239. 'OpenSSL_add_all_digests', [], lltype.Void)
  240. EVP_get_digestbyname = external(
  241. 'EVP_get_digestbyname',
  242. [rffi.CCHARP], EVP_MD)
  243. EVP_DigestInit = external(
  244. 'EVP_DigestInit',
  245. [EVP_MD_CTX, EVP_MD], rffi.INT)
  246. EVP_DigestUpdate = external(
  247. 'EVP_DigestUpdate',
  248. [EVP_MD_CTX, rffi.CCHARP, rffi.SIZE_T], rffi.INT)
  249. EVP_DigestFinal = external(
  250. 'EVP_DigestFinal',
  251. [EVP_MD_CTX, rffi.CCHARP, rffi.VOIDP], rffi.INT)
  252. EVP_MD_CTX_copy = external(
  253. 'EVP_MD_CTX_copy', [EVP_MD_CTX, EVP_MD_CTX], rffi.INT)
  254. EVP_MD_CTX_cleanup = external(
  255. 'EVP_MD_CTX_cleanup', [EVP_MD_CTX], rffi.INT, threadsafe=False)
  256. def init_ssl():
  257. libssl_SSL_load_error_strings()
  258. libssl_SSL_library_init()
  259. def init_digests():
  260. OpenSSL_add_all_digests()