PageRenderTime 60ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/Lib/test/test_ssl.py

https://bitbucket.org/matthewlmcclure/cpython
Python | 2379 lines | 2244 code | 76 blank | 59 comment | 145 complexity | 80bca57da597d77065d2ee5db7dd9462 MD5 | raw file
Possible License(s): 0BSD

Large files files are truncated, but you can click here to view the full file

  1. # Test the support for SSL and sockets
  2. import sys
  3. import unittest
  4. from test import support
  5. import socket
  6. import select
  7. import time
  8. import datetime
  9. import gc
  10. import os
  11. import errno
  12. import pprint
  13. import tempfile
  14. import urllib.request
  15. import traceback
  16. import asyncore
  17. import weakref
  18. import platform
  19. import functools
  20. from unittest import mock
  21. ssl = support.import_module("ssl")
  22. PROTOCOLS = sorted(ssl._PROTOCOL_NAMES)
  23. HOST = support.HOST
  24. data_file = lambda name: os.path.join(os.path.dirname(__file__), name)
  25. # The custom key and certificate files used in test_ssl are generated
  26. # using Lib/test/make_ssl_certs.py.
  27. # Other certificates are simply fetched from the Internet servers they
  28. # are meant to authenticate.
  29. CERTFILE = data_file("keycert.pem")
  30. BYTES_CERTFILE = os.fsencode(CERTFILE)
  31. ONLYCERT = data_file("ssl_cert.pem")
  32. ONLYKEY = data_file("ssl_key.pem")
  33. BYTES_ONLYCERT = os.fsencode(ONLYCERT)
  34. BYTES_ONLYKEY = os.fsencode(ONLYKEY)
  35. CERTFILE_PROTECTED = data_file("keycert.passwd.pem")
  36. ONLYKEY_PROTECTED = data_file("ssl_key.passwd.pem")
  37. KEY_PASSWORD = "somepass"
  38. CAPATH = data_file("capath")
  39. BYTES_CAPATH = os.fsencode(CAPATH)
  40. # Two keys and certs signed by the same CA (for SNI tests)
  41. SIGNED_CERTFILE = data_file("keycert3.pem")
  42. SIGNED_CERTFILE2 = data_file("keycert4.pem")
  43. SIGNING_CA = data_file("pycacert.pem")
  44. SVN_PYTHON_ORG_ROOT_CERT = data_file("https_svn_python_org_root.pem")
  45. EMPTYCERT = data_file("nullcert.pem")
  46. BADCERT = data_file("badcert.pem")
  47. WRONGCERT = data_file("XXXnonexisting.pem")
  48. BADKEY = data_file("badkey.pem")
  49. NOKIACERT = data_file("nokia.pem")
  50. DHFILE = data_file("dh512.pem")
  51. BYTES_DHFILE = os.fsencode(DHFILE)
  52. def handle_error(prefix):
  53. exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
  54. if support.verbose:
  55. sys.stdout.write(prefix + exc_format)
  56. def can_clear_options():
  57. # 0.9.8m or higher
  58. return ssl._OPENSSL_API_VERSION >= (0, 9, 8, 13, 15)
  59. def no_sslv2_implies_sslv3_hello():
  60. # 0.9.7h or higher
  61. return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15)
  62. def asn1time(cert_time):
  63. # Some versions of OpenSSL ignore seconds, see #18207
  64. # 0.9.8.i
  65. if ssl._OPENSSL_API_VERSION == (0, 9, 8, 9, 15):
  66. fmt = "%b %d %H:%M:%S %Y GMT"
  67. dt = datetime.datetime.strptime(cert_time, fmt)
  68. dt = dt.replace(second=0)
  69. cert_time = dt.strftime(fmt)
  70. # %d adds leading zero but ASN1_TIME_print() uses leading space
  71. if cert_time[4] == "0":
  72. cert_time = cert_time[:4] + " " + cert_time[5:]
  73. return cert_time
  74. # Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
  75. def skip_if_broken_ubuntu_ssl(func):
  76. if hasattr(ssl, 'PROTOCOL_SSLv2'):
  77. @functools.wraps(func)
  78. def f(*args, **kwargs):
  79. try:
  80. ssl.SSLContext(ssl.PROTOCOL_SSLv2)
  81. except ssl.SSLError:
  82. if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
  83. platform.linux_distribution() == ('debian', 'squeeze/sid', '')):
  84. raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
  85. return func(*args, **kwargs)
  86. return f
  87. else:
  88. return func
  89. needs_sni = unittest.skipUnless(ssl.HAS_SNI, "SNI support needed for this test")
  90. class BasicSocketTests(unittest.TestCase):
  91. def test_constants(self):
  92. ssl.CERT_NONE
  93. ssl.CERT_OPTIONAL
  94. ssl.CERT_REQUIRED
  95. ssl.OP_CIPHER_SERVER_PREFERENCE
  96. ssl.OP_SINGLE_DH_USE
  97. if ssl.HAS_ECDH:
  98. ssl.OP_SINGLE_ECDH_USE
  99. if ssl.OPENSSL_VERSION_INFO >= (1, 0):
  100. ssl.OP_NO_COMPRESSION
  101. self.assertIn(ssl.HAS_SNI, {True, False})
  102. self.assertIn(ssl.HAS_ECDH, {True, False})
  103. def test_random(self):
  104. v = ssl.RAND_status()
  105. if support.verbose:
  106. sys.stdout.write("\n RAND_status is %d (%s)\n"
  107. % (v, (v and "sufficient randomness") or
  108. "insufficient randomness"))
  109. data, is_cryptographic = ssl.RAND_pseudo_bytes(16)
  110. self.assertEqual(len(data), 16)
  111. self.assertEqual(is_cryptographic, v == 1)
  112. if v:
  113. data = ssl.RAND_bytes(16)
  114. self.assertEqual(len(data), 16)
  115. else:
  116. self.assertRaises(ssl.SSLError, ssl.RAND_bytes, 16)
  117. self.assertRaises(TypeError, ssl.RAND_egd, 1)
  118. self.assertRaises(TypeError, ssl.RAND_egd, 'foo', 1)
  119. ssl.RAND_add("this is a random string", 75.0)
  120. def test_parse_cert(self):
  121. # note that this uses an 'unofficial' function in _ssl.c,
  122. # provided solely for this test, to exercise the certificate
  123. # parsing code
  124. p = ssl._ssl._test_decode_cert(CERTFILE)
  125. if support.verbose:
  126. sys.stdout.write("\n" + pprint.pformat(p) + "\n")
  127. self.assertEqual(p['issuer'],
  128. ((('countryName', 'XY'),),
  129. (('localityName', 'Castle Anthrax'),),
  130. (('organizationName', 'Python Software Foundation'),),
  131. (('commonName', 'localhost'),))
  132. )
  133. # Note the next three asserts will fail if the keys are regenerated
  134. self.assertEqual(p['notAfter'], asn1time('Oct 5 23:01:56 2020 GMT'))
  135. self.assertEqual(p['notBefore'], asn1time('Oct 8 23:01:56 2010 GMT'))
  136. self.assertEqual(p['serialNumber'], 'D7C7381919AFC24E')
  137. self.assertEqual(p['subject'],
  138. ((('countryName', 'XY'),),
  139. (('localityName', 'Castle Anthrax'),),
  140. (('organizationName', 'Python Software Foundation'),),
  141. (('commonName', 'localhost'),))
  142. )
  143. self.assertEqual(p['subjectAltName'], (('DNS', 'localhost'),))
  144. # Issue #13034: the subjectAltName in some certificates
  145. # (notably projects.developer.nokia.com:443) wasn't parsed
  146. p = ssl._ssl._test_decode_cert(NOKIACERT)
  147. if support.verbose:
  148. sys.stdout.write("\n" + pprint.pformat(p) + "\n")
  149. self.assertEqual(p['subjectAltName'],
  150. (('DNS', 'projects.developer.nokia.com'),
  151. ('DNS', 'projects.forum.nokia.com'))
  152. )
  153. def test_DER_to_PEM(self):
  154. with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
  155. pem = f.read()
  156. d1 = ssl.PEM_cert_to_DER_cert(pem)
  157. p2 = ssl.DER_cert_to_PEM_cert(d1)
  158. d2 = ssl.PEM_cert_to_DER_cert(p2)
  159. self.assertEqual(d1, d2)
  160. if not p2.startswith(ssl.PEM_HEADER + '\n'):
  161. self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
  162. if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
  163. self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
  164. def test_openssl_version(self):
  165. n = ssl.OPENSSL_VERSION_NUMBER
  166. t = ssl.OPENSSL_VERSION_INFO
  167. s = ssl.OPENSSL_VERSION
  168. self.assertIsInstance(n, int)
  169. self.assertIsInstance(t, tuple)
  170. self.assertIsInstance(s, str)
  171. # Some sanity checks follow
  172. # >= 0.9
  173. self.assertGreaterEqual(n, 0x900000)
  174. # < 2.0
  175. self.assertLess(n, 0x20000000)
  176. major, minor, fix, patch, status = t
  177. self.assertGreaterEqual(major, 0)
  178. self.assertLess(major, 2)
  179. self.assertGreaterEqual(minor, 0)
  180. self.assertLess(minor, 256)
  181. self.assertGreaterEqual(fix, 0)
  182. self.assertLess(fix, 256)
  183. self.assertGreaterEqual(patch, 0)
  184. self.assertLessEqual(patch, 26)
  185. self.assertGreaterEqual(status, 0)
  186. self.assertLessEqual(status, 15)
  187. # Version string as returned by OpenSSL, the format might change
  188. self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
  189. (s, t))
  190. @support.cpython_only
  191. def test_refcycle(self):
  192. # Issue #7943: an SSL object doesn't create reference cycles with
  193. # itself.
  194. s = socket.socket(socket.AF_INET)
  195. ss = ssl.wrap_socket(s)
  196. wr = weakref.ref(ss)
  197. with support.check_warnings(("", ResourceWarning)):
  198. del ss
  199. self.assertEqual(wr(), None)
  200. def test_wrapped_unconnected(self):
  201. # Methods on an unconnected SSLSocket propagate the original
  202. # OSError raise by the underlying socket object.
  203. s = socket.socket(socket.AF_INET)
  204. with ssl.wrap_socket(s) as ss:
  205. self.assertRaises(OSError, ss.recv, 1)
  206. self.assertRaises(OSError, ss.recv_into, bytearray(b'x'))
  207. self.assertRaises(OSError, ss.recvfrom, 1)
  208. self.assertRaises(OSError, ss.recvfrom_into, bytearray(b'x'), 1)
  209. self.assertRaises(OSError, ss.send, b'x')
  210. self.assertRaises(OSError, ss.sendto, b'x', ('0.0.0.0', 0))
  211. def test_timeout(self):
  212. # Issue #8524: when creating an SSL socket, the timeout of the
  213. # original socket should be retained.
  214. for timeout in (None, 0.0, 5.0):
  215. s = socket.socket(socket.AF_INET)
  216. s.settimeout(timeout)
  217. with ssl.wrap_socket(s) as ss:
  218. self.assertEqual(timeout, ss.gettimeout())
  219. def test_errors(self):
  220. sock = socket.socket()
  221. self.assertRaisesRegex(ValueError,
  222. "certfile must be specified",
  223. ssl.wrap_socket, sock, keyfile=CERTFILE)
  224. self.assertRaisesRegex(ValueError,
  225. "certfile must be specified for server-side operations",
  226. ssl.wrap_socket, sock, server_side=True)
  227. self.assertRaisesRegex(ValueError,
  228. "certfile must be specified for server-side operations",
  229. ssl.wrap_socket, sock, server_side=True, certfile="")
  230. with ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE) as s:
  231. self.assertRaisesRegex(ValueError, "can't connect in server-side mode",
  232. s.connect, (HOST, 8080))
  233. with self.assertRaises(OSError) as cm:
  234. with socket.socket() as sock:
  235. ssl.wrap_socket(sock, certfile=WRONGCERT)
  236. self.assertEqual(cm.exception.errno, errno.ENOENT)
  237. with self.assertRaises(OSError) as cm:
  238. with socket.socket() as sock:
  239. ssl.wrap_socket(sock, certfile=CERTFILE, keyfile=WRONGCERT)
  240. self.assertEqual(cm.exception.errno, errno.ENOENT)
  241. with self.assertRaises(OSError) as cm:
  242. with socket.socket() as sock:
  243. ssl.wrap_socket(sock, certfile=WRONGCERT, keyfile=WRONGCERT)
  244. self.assertEqual(cm.exception.errno, errno.ENOENT)
  245. def test_match_hostname(self):
  246. def ok(cert, hostname):
  247. ssl.match_hostname(cert, hostname)
  248. def fail(cert, hostname):
  249. self.assertRaises(ssl.CertificateError,
  250. ssl.match_hostname, cert, hostname)
  251. cert = {'subject': ((('commonName', 'example.com'),),)}
  252. ok(cert, 'example.com')
  253. ok(cert, 'ExAmple.cOm')
  254. fail(cert, 'www.example.com')
  255. fail(cert, '.example.com')
  256. fail(cert, 'example.org')
  257. fail(cert, 'exampleXcom')
  258. cert = {'subject': ((('commonName', '*.a.com'),),)}
  259. ok(cert, 'foo.a.com')
  260. fail(cert, 'bar.foo.a.com')
  261. fail(cert, 'a.com')
  262. fail(cert, 'Xa.com')
  263. fail(cert, '.a.com')
  264. cert = {'subject': ((('commonName', 'a.*.com'),),)}
  265. ok(cert, 'a.foo.com')
  266. fail(cert, 'a..com')
  267. fail(cert, 'a.com')
  268. cert = {'subject': ((('commonName', 'f*.com'),),)}
  269. ok(cert, 'foo.com')
  270. ok(cert, 'f.com')
  271. fail(cert, 'bar.com')
  272. fail(cert, 'foo.a.com')
  273. fail(cert, 'bar.foo.com')
  274. # Slightly fake real-world example
  275. cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT',
  276. 'subject': ((('commonName', 'linuxfrz.org'),),),
  277. 'subjectAltName': (('DNS', 'linuxfr.org'),
  278. ('DNS', 'linuxfr.com'),
  279. ('othername', '<unsupported>'))}
  280. ok(cert, 'linuxfr.org')
  281. ok(cert, 'linuxfr.com')
  282. # Not a "DNS" entry
  283. fail(cert, '<unsupported>')
  284. # When there is a subjectAltName, commonName isn't used
  285. fail(cert, 'linuxfrz.org')
  286. # A pristine real-world example
  287. cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
  288. 'subject': ((('countryName', 'US'),),
  289. (('stateOrProvinceName', 'California'),),
  290. (('localityName', 'Mountain View'),),
  291. (('organizationName', 'Google Inc'),),
  292. (('commonName', 'mail.google.com'),))}
  293. ok(cert, 'mail.google.com')
  294. fail(cert, 'gmail.com')
  295. # Only commonName is considered
  296. fail(cert, 'California')
  297. # Neither commonName nor subjectAltName
  298. cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
  299. 'subject': ((('countryName', 'US'),),
  300. (('stateOrProvinceName', 'California'),),
  301. (('localityName', 'Mountain View'),),
  302. (('organizationName', 'Google Inc'),))}
  303. fail(cert, 'mail.google.com')
  304. # No DNS entry in subjectAltName but a commonName
  305. cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
  306. 'subject': ((('countryName', 'US'),),
  307. (('stateOrProvinceName', 'California'),),
  308. (('localityName', 'Mountain View'),),
  309. (('commonName', 'mail.google.com'),)),
  310. 'subjectAltName': (('othername', 'blabla'), )}
  311. ok(cert, 'mail.google.com')
  312. # No DNS entry subjectAltName and no commonName
  313. cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
  314. 'subject': ((('countryName', 'US'),),
  315. (('stateOrProvinceName', 'California'),),
  316. (('localityName', 'Mountain View'),),
  317. (('organizationName', 'Google Inc'),)),
  318. 'subjectAltName': (('othername', 'blabla'),)}
  319. fail(cert, 'google.com')
  320. # Empty cert / no cert
  321. self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com')
  322. self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com')
  323. # Issue #17980: avoid denials of service by refusing more than one
  324. # wildcard per fragment.
  325. cert = {'subject': ((('commonName', 'a*b.com'),),)}
  326. ok(cert, 'axxb.com')
  327. cert = {'subject': ((('commonName', 'a*b.co*'),),)}
  328. ok(cert, 'axxb.com')
  329. cert = {'subject': ((('commonName', 'a*b*.com'),),)}
  330. with self.assertRaises(ssl.CertificateError) as cm:
  331. ssl.match_hostname(cert, 'axxbxxc.com')
  332. self.assertIn("too many wildcards", str(cm.exception))
  333. def test_server_side(self):
  334. # server_hostname doesn't work for server sockets
  335. ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
  336. with socket.socket() as sock:
  337. self.assertRaises(ValueError, ctx.wrap_socket, sock, True,
  338. server_hostname="some.hostname")
  339. def test_unknown_channel_binding(self):
  340. # should raise ValueError for unknown type
  341. s = socket.socket(socket.AF_INET)
  342. with ssl.wrap_socket(s) as ss:
  343. with self.assertRaises(ValueError):
  344. ss.get_channel_binding("unknown-type")
  345. @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
  346. "'tls-unique' channel binding not available")
  347. def test_tls_unique_channel_binding(self):
  348. # unconnected should return None for known type
  349. s = socket.socket(socket.AF_INET)
  350. with ssl.wrap_socket(s) as ss:
  351. self.assertIsNone(ss.get_channel_binding("tls-unique"))
  352. # the same for server-side
  353. s = socket.socket(socket.AF_INET)
  354. with ssl.wrap_socket(s, server_side=True, certfile=CERTFILE) as ss:
  355. self.assertIsNone(ss.get_channel_binding("tls-unique"))
  356. def test_dealloc_warn(self):
  357. ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
  358. r = repr(ss)
  359. with self.assertWarns(ResourceWarning) as cm:
  360. ss = None
  361. support.gc_collect()
  362. self.assertIn(r, str(cm.warning.args[0]))
  363. def test_get_default_verify_paths(self):
  364. paths = ssl.get_default_verify_paths()
  365. self.assertEqual(len(paths), 6)
  366. self.assertIsInstance(paths, ssl.DefaultVerifyPaths)
  367. with support.EnvironmentVarGuard() as env:
  368. env["SSL_CERT_DIR"] = CAPATH
  369. env["SSL_CERT_FILE"] = CERTFILE
  370. paths = ssl.get_default_verify_paths()
  371. self.assertEqual(paths.cafile, CERTFILE)
  372. self.assertEqual(paths.capath, CAPATH)
  373. @unittest.skipUnless(sys.platform == "win32", "Windows specific")
  374. def test_enum_cert_store(self):
  375. self.assertEqual(ssl.X509_ASN_ENCODING, 1)
  376. self.assertEqual(ssl.PKCS_7_ASN_ENCODING, 0x00010000)
  377. self.assertEqual(ssl.enum_cert_store("CA"),
  378. ssl.enum_cert_store("CA", "certificate"))
  379. ssl.enum_cert_store("CA", "crl")
  380. self.assertEqual(ssl.enum_cert_store("ROOT"),
  381. ssl.enum_cert_store("ROOT", "certificate"))
  382. ssl.enum_cert_store("ROOT", "crl")
  383. self.assertRaises(TypeError, ssl.enum_cert_store)
  384. self.assertRaises(WindowsError, ssl.enum_cert_store, "")
  385. self.assertRaises(ValueError, ssl.enum_cert_store, "CA", "wrong")
  386. ca = ssl.enum_cert_store("CA")
  387. self.assertIsInstance(ca, list)
  388. self.assertIsInstance(ca[0], tuple)
  389. self.assertEqual(len(ca[0]), 2)
  390. self.assertIsInstance(ca[0][0], bytes)
  391. self.assertIsInstance(ca[0][1], int)
  392. class ContextTests(unittest.TestCase):
  393. @skip_if_broken_ubuntu_ssl
  394. def test_constructor(self):
  395. for protocol in PROTOCOLS:
  396. ssl.SSLContext(protocol)
  397. self.assertRaises(TypeError, ssl.SSLContext)
  398. self.assertRaises(ValueError, ssl.SSLContext, -1)
  399. self.assertRaises(ValueError, ssl.SSLContext, 42)
  400. @skip_if_broken_ubuntu_ssl
  401. def test_protocol(self):
  402. for proto in PROTOCOLS:
  403. ctx = ssl.SSLContext(proto)
  404. self.assertEqual(ctx.protocol, proto)
  405. def test_ciphers(self):
  406. ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
  407. ctx.set_ciphers("ALL")
  408. ctx.set_ciphers("DEFAULT")
  409. with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
  410. ctx.set_ciphers("^$:,;?*'dorothyx")
  411. @skip_if_broken_ubuntu_ssl
  412. def test_options(self):
  413. ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
  414. # OP_ALL is the default value
  415. self.assertEqual(ssl.OP_ALL, ctx.options)
  416. ctx.options |= ssl.OP_NO_SSLv2
  417. self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2,
  418. ctx.options)
  419. ctx.options |= ssl.OP_NO_SSLv3
  420. self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3,
  421. ctx.options)
  422. if can_clear_options():
  423. ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1
  424. self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3,
  425. ctx.options)
  426. ctx.options = 0
  427. self.assertEqual(0, ctx.options)
  428. else:
  429. with self.assertRaises(ValueError):
  430. ctx.options = 0
  431. def test_verify(self):
  432. ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
  433. # Default value
  434. self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
  435. ctx.verify_mode = ssl.CERT_OPTIONAL
  436. self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL)
  437. ctx.verify_mode = ssl.CERT_REQUIRED
  438. self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
  439. ctx.verify_mode = ssl.CERT_NONE
  440. self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
  441. with self.assertRaises(TypeError):
  442. ctx.verify_mode = None
  443. with self.assertRaises(ValueError):
  444. ctx.verify_mode = 42
  445. def test_load_cert_chain(self):
  446. ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
  447. # Combined key and cert in a single file
  448. ctx.load_cert_chain(CERTFILE)
  449. ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE)
  450. self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE)
  451. with self.assertRaises(OSError) as cm:
  452. ctx.load_cert_chain(WRONGCERT)
  453. self.assertEqual(cm.exception.errno, errno.ENOENT)
  454. with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
  455. ctx.load_cert_chain(BADCERT)
  456. with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
  457. ctx.load_cert_chain(EMPTYCERT)
  458. # Separate key and cert
  459. ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
  460. ctx.load_cert_chain(ONLYCERT, ONLYKEY)
  461. ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY)
  462. ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY)
  463. with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
  464. ctx.load_cert_chain(ONLYCERT)
  465. with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
  466. ctx.load_cert_chain(ONLYKEY)
  467. with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
  468. ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT)
  469. # Mismatching key and cert
  470. ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
  471. with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"):
  472. ctx.load_cert_chain(SVN_PYTHON_ORG_ROOT_CERT, ONLYKEY)
  473. # Password protected key and cert
  474. ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD)
  475. ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD.encode())
  476. ctx.load_cert_chain(CERTFILE_PROTECTED,
  477. password=bytearray(KEY_PASSWORD.encode()))
  478. ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD)
  479. ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD.encode())
  480. ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED,
  481. bytearray(KEY_PASSWORD.encode()))
  482. with self.assertRaisesRegex(TypeError, "should be a string"):
  483. ctx.load_cert_chain(CERTFILE_PROTECTED, password=True)
  484. with self.assertRaises(ssl.SSLError):
  485. ctx.load_cert_chain(CERTFILE_PROTECTED, password="badpass")
  486. with self.assertRaisesRegex(ValueError, "cannot be longer"):
  487. # openssl has a fixed limit on the password buffer.
  488. # PEM_BUFSIZE is generally set to 1kb.
  489. # Return a string larger than this.
  490. ctx.load_cert_chain(CERTFILE_PROTECTED, password=b'a' * 102400)
  491. # Password callback
  492. def getpass_unicode():
  493. return KEY_PASSWORD
  494. def getpass_bytes():
  495. return KEY_PASSWORD.encode()
  496. def getpass_bytearray():
  497. return bytearray(KEY_PASSWORD.encode())
  498. def getpass_badpass():
  499. return "badpass"
  500. def getpass_huge():
  501. return b'a' * (1024 * 1024)
  502. def getpass_bad_type():
  503. return 9
  504. def getpass_exception():
  505. raise Exception('getpass error')
  506. class GetPassCallable:
  507. def __call__(self):
  508. return KEY_PASSWORD
  509. def getpass(self):
  510. return KEY_PASSWORD
  511. ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_unicode)
  512. ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytes)
  513. ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytearray)
  514. ctx.load_cert_chain(CERTFILE_PROTECTED, password=GetPassCallable())
  515. ctx.load_cert_chain(CERTFILE_PROTECTED,
  516. password=GetPassCallable().getpass)
  517. with self.assertRaises(ssl.SSLError):
  518. ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_badpass)
  519. with self.assertRaisesRegex(ValueError, "cannot be longer"):
  520. ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_huge)
  521. with self.assertRaisesRegex(TypeError, "must return a string"):
  522. ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bad_type)
  523. with self.assertRaisesRegex(Exception, "getpass error"):
  524. ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_exception)
  525. # Make sure the password function isn't called if it isn't needed
  526. ctx.load_cert_chain(CERTFILE, password=getpass_exception)
  527. def test_load_verify_locations(self):
  528. ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
  529. ctx.load_verify_locations(CERTFILE)
  530. ctx.load_verify_locations(cafile=CERTFILE, capath=None)
  531. ctx.load_verify_locations(BYTES_CERTFILE)
  532. ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None)
  533. self.assertRaises(TypeError, ctx.load_verify_locations)
  534. self.assertRaises(TypeError, ctx.load_verify_locations, None, None)
  535. with self.assertRaises(OSError) as cm:
  536. ctx.load_verify_locations(WRONGCERT)
  537. self.assertEqual(cm.exception.errno, errno.ENOENT)
  538. with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
  539. ctx.load_verify_locations(BADCERT)
  540. ctx.load_verify_locations(CERTFILE, CAPATH)
  541. ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH)
  542. # Issue #10989: crash if the second argument type is invalid
  543. self.assertRaises(TypeError, ctx.load_verify_locations, None, True)
  544. def test_load_dh_params(self):
  545. ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
  546. ctx.load_dh_params(DHFILE)
  547. if os.name != 'nt':
  548. ctx.load_dh_params(BYTES_DHFILE)
  549. self.assertRaises(TypeError, ctx.load_dh_params)
  550. self.assertRaises(TypeError, ctx.load_dh_params, None)
  551. with self.assertRaises(FileNotFoundError) as cm:
  552. ctx.load_dh_params(WRONGCERT)
  553. self.assertEqual(cm.exception.errno, errno.ENOENT)
  554. with self.assertRaises(ssl.SSLError) as cm:
  555. ctx.load_dh_params(CERTFILE)
  556. @skip_if_broken_ubuntu_ssl
  557. def test_session_stats(self):
  558. for proto in PROTOCOLS:
  559. ctx = ssl.SSLContext(proto)
  560. self.assertEqual(ctx.session_stats(), {
  561. 'number': 0,
  562. 'connect': 0,
  563. 'connect_good': 0,
  564. 'connect_renegotiate': 0,
  565. 'accept': 0,
  566. 'accept_good': 0,
  567. 'accept_renegotiate': 0,
  568. 'hits': 0,
  569. 'misses': 0,
  570. 'timeouts': 0,
  571. 'cache_full': 0,
  572. })
  573. def test_set_default_verify_paths(self):
  574. # There's not much we can do to test that it acts as expected,
  575. # so just check it doesn't crash or raise an exception.
  576. ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
  577. ctx.set_default_verify_paths()
  578. @unittest.skipUnless(ssl.HAS_ECDH, "ECDH disabled on this OpenSSL build")
  579. def test_set_ecdh_curve(self):
  580. ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
  581. ctx.set_ecdh_curve("prime256v1")
  582. ctx.set_ecdh_curve(b"prime256v1")
  583. self.assertRaises(TypeError, ctx.set_ecdh_curve)
  584. self.assertRaises(TypeError, ctx.set_ecdh_curve, None)
  585. self.assertRaises(ValueError, ctx.set_ecdh_curve, "foo")
  586. self.assertRaises(ValueError, ctx.set_ecdh_curve, b"foo")
  587. @needs_sni
  588. def test_sni_callback(self):
  589. ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
  590. # set_servername_callback expects a callable, or None
  591. self.assertRaises(TypeError, ctx.set_servername_callback)
  592. self.assertRaises(TypeError, ctx.set_servername_callback, 4)
  593. self.assertRaises(TypeError, ctx.set_servername_callback, "")
  594. self.assertRaises(TypeError, ctx.set_servername_callback, ctx)
  595. def dummycallback(sock, servername, ctx):
  596. pass
  597. ctx.set_servername_callback(None)
  598. ctx.set_servername_callback(dummycallback)
  599. @needs_sni
  600. def test_sni_callback_refcycle(self):
  601. # Reference cycles through the servername callback are detected
  602. # and cleared.
  603. ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
  604. def dummycallback(sock, servername, ctx, cycle=ctx):
  605. pass
  606. ctx.set_servername_callback(dummycallback)
  607. wr = weakref.ref(ctx)
  608. del ctx, dummycallback
  609. gc.collect()
  610. self.assertIs(wr(), None)
  611. def test_cert_store_stats(self):
  612. ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
  613. self.assertEqual(ctx.cert_store_stats(),
  614. {'x509_ca': 0, 'crl': 0, 'x509': 0})
  615. ctx.load_cert_chain(CERTFILE)
  616. self.assertEqual(ctx.cert_store_stats(),
  617. {'x509_ca': 0, 'crl': 0, 'x509': 0})
  618. ctx.load_verify_locations(CERTFILE)
  619. self.assertEqual(ctx.cert_store_stats(),
  620. {'x509_ca': 0, 'crl': 0, 'x509': 1})
  621. ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
  622. self.assertEqual(ctx.cert_store_stats(),
  623. {'x509_ca': 1, 'crl': 0, 'x509': 2})
  624. def test_get_ca_certs(self):
  625. ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
  626. self.assertEqual(ctx.get_ca_certs(), [])
  627. # CERTFILE is not flagged as X509v3 Basic Constraints: CA:TRUE
  628. ctx.load_verify_locations(CERTFILE)
  629. self.assertEqual(ctx.get_ca_certs(), [])
  630. # but SVN_PYTHON_ORG_ROOT_CERT is a CA cert
  631. ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
  632. self.assertEqual(ctx.get_ca_certs(),
  633. [{'issuer': ((('organizationName', 'Root CA'),),
  634. (('organizationalUnitName', 'http://www.cacert.org'),),
  635. (('commonName', 'CA Cert Signing Authority'),),
  636. (('emailAddress', 'support@cacert.org'),)),
  637. 'notAfter': asn1time('Mar 29 12:29:49 2033 GMT'),
  638. 'notBefore': asn1time('Mar 30 12:29:49 2003 GMT'),
  639. 'serialNumber': '00',
  640. 'subject': ((('organizationName', 'Root CA'),),
  641. (('organizationalUnitName', 'http://www.cacert.org'),),
  642. (('commonName', 'CA Cert Signing Authority'),),
  643. (('emailAddress', 'support@cacert.org'),)),
  644. 'version': 3}])
  645. with open(SVN_PYTHON_ORG_ROOT_CERT) as f:
  646. pem = f.read()
  647. der = ssl.PEM_cert_to_DER_cert(pem)
  648. self.assertEqual(ctx.get_ca_certs(True), [der])
  649. class SSLErrorTests(unittest.TestCase):
  650. def test_str(self):
  651. # The str() of a SSLError doesn't include the errno
  652. e = ssl.SSLError(1, "foo")
  653. self.assertEqual(str(e), "foo")
  654. self.assertEqual(e.errno, 1)
  655. # Same for a subclass
  656. e = ssl.SSLZeroReturnError(1, "foo")
  657. self.assertEqual(str(e), "foo")
  658. self.assertEqual(e.errno, 1)
  659. def test_lib_reason(self):
  660. # Test the library and reason attributes
  661. ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
  662. with self.assertRaises(ssl.SSLError) as cm:
  663. ctx.load_dh_params(CERTFILE)
  664. self.assertEqual(cm.exception.library, 'PEM')
  665. self.assertEqual(cm.exception.reason, 'NO_START_LINE')
  666. s = str(cm.exception)
  667. self.assertTrue(s.startswith("[PEM: NO_START_LINE] no start line"), s)
  668. def test_subclass(self):
  669. # Check that the appropriate SSLError subclass is raised
  670. # (this only tests one of them)
  671. ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
  672. with socket.socket() as s:
  673. s.bind(("127.0.0.1", 0))
  674. s.listen(5)
  675. c = socket.socket()
  676. c.connect(s.getsockname())
  677. c.setblocking(False)
  678. with ctx.wrap_socket(c, False, do_handshake_on_connect=False) as c:
  679. with self.assertRaises(ssl.SSLWantReadError) as cm:
  680. c.do_handshake()
  681. s = str(cm.exception)
  682. self.assertTrue(s.startswith("The operation did not complete (read)"), s)
  683. # For compatibility
  684. self.assertEqual(cm.exception.errno, ssl.SSL_ERROR_WANT_READ)
  685. class NetworkedTests(unittest.TestCase):
  686. def test_connect(self):
  687. with support.transient_internet("svn.python.org"):
  688. s = ssl.wrap_socket(socket.socket(socket.AF_INET),
  689. cert_reqs=ssl.CERT_NONE)
  690. try:
  691. s.connect(("svn.python.org", 443))
  692. self.assertEqual({}, s.getpeercert())
  693. finally:
  694. s.close()
  695. # this should fail because we have no verification certs
  696. s = ssl.wrap_socket(socket.socket(socket.AF_INET),
  697. cert_reqs=ssl.CERT_REQUIRED)
  698. self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
  699. s.connect, ("svn.python.org", 443))
  700. s.close()
  701. # this should succeed because we specify the root cert
  702. s = ssl.wrap_socket(socket.socket(socket.AF_INET),
  703. cert_reqs=ssl.CERT_REQUIRED,
  704. ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
  705. try:
  706. s.connect(("svn.python.org", 443))
  707. self.assertTrue(s.getpeercert())
  708. finally:
  709. s.close()
  710. def test_connect_ex(self):
  711. # Issue #11326: check connect_ex() implementation
  712. with support.transient_internet("svn.python.org"):
  713. s = ssl.wrap_socket(socket.socket(socket.AF_INET),
  714. cert_reqs=ssl.CERT_REQUIRED,
  715. ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
  716. try:
  717. self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
  718. self.assertTrue(s.getpeercert())
  719. finally:
  720. s.close()
  721. def test_non_blocking_connect_ex(self):
  722. # Issue #11326: non-blocking connect_ex() should allow handshake
  723. # to proceed after the socket gets ready.
  724. with support.transient_internet("svn.python.org"):
  725. s = ssl.wrap_socket(socket.socket(socket.AF_INET),
  726. cert_reqs=ssl.CERT_REQUIRED,
  727. ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
  728. do_handshake_on_connect=False)
  729. try:
  730. s.setblocking(False)
  731. rc = s.connect_ex(('svn.python.org', 443))
  732. # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
  733. self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
  734. # Wait for connect to finish
  735. select.select([], [s], [], 5.0)
  736. # Non-blocking handshake
  737. while True:
  738. try:
  739. s.do_handshake()
  740. break
  741. except ssl.SSLWantReadError:
  742. select.select([s], [], [], 5.0)
  743. except ssl.SSLWantWriteError:
  744. select.select([], [s], [], 5.0)
  745. # SSL established
  746. self.assertTrue(s.getpeercert())
  747. finally:
  748. s.close()
  749. def test_timeout_connect_ex(self):
  750. # Issue #12065: on a timeout, connect_ex() should return the original
  751. # errno (mimicking the behaviour of non-SSL sockets).
  752. with support.transient_internet("svn.python.org"):
  753. s = ssl.wrap_socket(socket.socket(socket.AF_INET),
  754. cert_reqs=ssl.CERT_REQUIRED,
  755. ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
  756. do_handshake_on_connect=False)
  757. try:
  758. s.settimeout(0.0000001)
  759. rc = s.connect_ex(('svn.python.org', 443))
  760. if rc == 0:
  761. self.skipTest("svn.python.org responded too quickly")
  762. self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
  763. finally:
  764. s.close()
  765. def test_connect_ex_error(self):
  766. with support.transient_internet("svn.python.org"):
  767. s = ssl.wrap_socket(socket.socket(socket.AF_INET),
  768. cert_reqs=ssl.CERT_REQUIRED,
  769. ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
  770. try:
  771. self.assertEqual(errno.ECONNREFUSED,
  772. s.connect_ex(("svn.python.org", 444)))
  773. finally:
  774. s.close()
  775. def test_connect_with_context(self):
  776. with support.transient_internet("svn.python.org"):
  777. # Same as test_connect, but with a separately created context
  778. ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
  779. s = ctx.wrap_socket(socket.socket(socket.AF_INET))
  780. s.connect(("svn.python.org", 443))
  781. try:
  782. self.assertEqual({}, s.getpeercert())
  783. finally:
  784. s.close()
  785. # Same with a server hostname
  786. s = ctx.wrap_socket(socket.socket(socket.AF_INET),
  787. server_hostname="svn.python.org")
  788. if ssl.HAS_SNI:
  789. s.connect(("svn.python.org", 443))
  790. s.close()
  791. else:
  792. self.assertRaises(ValueError, s.connect, ("svn.python.org", 443))
  793. # This should fail because we have no verification certs
  794. ctx.verify_mode = ssl.CERT_REQUIRED
  795. s = ctx.wrap_socket(socket.socket(socket.AF_INET))
  796. self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
  797. s.connect, ("svn.python.org", 443))
  798. s.close()
  799. # This should succeed because we specify the root cert
  800. ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
  801. s = ctx.wrap_socket(socket.socket(socket.AF_INET))
  802. s.connect(("svn.python.org", 443))
  803. try:
  804. cert = s.getpeercert()
  805. self.assertTrue(cert)
  806. finally:
  807. s.close()
  808. def test_connect_capath(self):
  809. # Verify server certificates using the `capath` argument
  810. # NOTE: the subject hashing algorithm has been changed between
  811. # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
  812. # contain both versions of each certificate (same content, different
  813. # filename) for this test to be portable across OpenSSL releases.
  814. with support.transient_internet("svn.python.org"):
  815. ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
  816. ctx.verify_mode = ssl.CERT_REQUIRED
  817. ctx.load_verify_locations(capath=CAPATH)
  818. s = ctx.wrap_socket(socket.socket(socket.AF_INET))
  819. s.connect(("svn.python.org", 443))
  820. try:
  821. cert = s.getpeercert()
  822. self.assertTrue(cert)
  823. finally:
  824. s.close()
  825. # Same with a bytes `capath` argument
  826. ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
  827. ctx.verify_mode = ssl.CERT_REQUIRED
  828. ctx.load_verify_locations(capath=BYTES_CAPATH)
  829. s = ctx.wrap_socket(socket.socket(socket.AF_INET))
  830. s.connect(("svn.python.org", 443))
  831. try:
  832. cert = s.getpeercert()
  833. self.assertTrue(cert)
  834. finally:
  835. s.close()
  836. @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
  837. def test_makefile_close(self):
  838. # Issue #5238: creating a file-like object with makefile() shouldn't
  839. # delay closing the underlying "real socket" (here tested with its
  840. # file descriptor, hence skipping the test under Windows).
  841. with support.transient_internet("svn.python.org"):
  842. ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
  843. ss.connect(("svn.python.org", 443))
  844. fd = ss.fileno()
  845. f = ss.makefile()
  846. f.close()
  847. # The fd is still open
  848. os.read(fd, 0)
  849. # Closing the SSL socket should close the fd too
  850. ss.close()
  851. gc.collect()
  852. with self.assertRaises(OSError) as e:
  853. os.read(fd, 0)
  854. self.assertEqual(e.exception.errno, errno.EBADF)
  855. def test_non_blocking_handshake(self):
  856. with support.transient_internet("svn.python.org"):
  857. s = socket.socket(socket.AF_INET)
  858. s.connect(("svn.python.org", 443))
  859. s.setblocking(False)
  860. s = ssl.wrap_socket(s,
  861. cert_reqs=ssl.CERT_NONE,
  862. do_handshake_on_connect=False)
  863. count = 0
  864. while True:
  865. try:
  866. count += 1
  867. s.do_handshake()
  868. break
  869. except ssl.SSLWantReadError:
  870. select.select([s], [], [])
  871. except ssl.SSLWantWriteError:
  872. select.select([], [s], [])
  873. s.close()
  874. if support.verbose:
  875. sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
  876. def test_get_server_certificate(self):
  877. def _test_get_server_certificate(host, port, cert=None):
  878. with support.transient_internet(host):
  879. pem = ssl.get_server_certificate((host, port))
  880. if not pem:
  881. self.fail("No server certificate on %s:%s!" % (host, port))
  882. try:
  883. pem = ssl.get_server_certificate((host, port), ca_certs=CERTFILE)
  884. except ssl.SSLError as x:
  885. #should fail
  886. if support.verbose:
  887. sys.stdout.write("%s\n" % x)
  888. else:
  889. self.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
  890. pem = ssl.get_server_certificate((host, port), ca_certs=cert)
  891. if not pem:
  892. self.fail("No server certificate on %s:%s!" % (host, port))
  893. if support.verbose:
  894. sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem))
  895. _test_get_server_certificate('svn.python.org', 443, SVN_PYTHON_ORG_ROOT_CERT)
  896. if support.IPV6_ENABLED:
  897. _test_get_server_certificate('ipv6.google.com', 443)
  898. def test_ciphers(self):
  899. remote = ("svn.python.org", 443)
  900. with support.transient_internet(remote[0]):
  901. with ssl.wrap_socket(socket.socket(socket.AF_INET),
  902. cert_reqs=ssl.CERT_NONE, ciphers="ALL") as s:
  903. s.connect(remote)
  904. with ssl.wrap_socket(socket.socket(socket.AF_INET),
  905. cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT") as s:
  906. s.connect(remote)
  907. # Error checking can happen at instantiation or when connecting
  908. with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
  909. with socket.socket(socket.AF_INET) as sock:
  910. s = ssl.wrap_socket(sock,
  911. cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
  912. s.connect(remote)
  913. def test_algorithms(self):
  914. # Issue #8484: all algorithms should be available when verifying a
  915. # certificate.
  916. # SHA256 was added in OpenSSL 0.9.8
  917. if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
  918. self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
  919. # sha256.tbs-internet.com needs SNI to use the correct certificate
  920. if not ssl.HAS_SNI:
  921. self.skipTest("SNI needed for this test")
  922. # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
  923. remote = ("sha256.tbs-internet.com", 443)
  924. sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
  925. with support.transient_internet("sha256.tbs-internet.com"):
  926. ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
  927. ctx.verify_mode = ssl.CERT_REQUIRED
  928. ctx.load_verify_locations(sha256_cert)
  929. s = ctx.wrap_socket(socket.socket(socket.AF_INET),
  930. server_hostname="sha256.tbs-internet.com")
  931. try:
  932. s.connect(remote)
  933. if support.verbose:
  934. sys.stdout.write("\nCipher with %r is %r\n" %
  935. (remote, s.cipher()))
  936. sys.stdout.write("Certificate is:\n%s\n" %
  937. pprint.pformat(s.getpeercert()))
  938. finally:
  939. s.close()
  940. def test_get_ca_certs_capath(self):
  941. # capath certs are loaded on request
  942. with support.transient_internet("svn.python.org"):
  943. ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
  944. ctx.verify_mode = ssl.CERT_REQUIRED
  945. ctx.load_verify_locations(capath=CAPATH)
  946. self.assertEqual(ctx.get_ca_certs(), [])
  947. s = ctx.wrap_socket(socket.socket(socket.AF_INET))
  948. s.connect(("svn.python.org", 443))
  949. try:
  950. cert = s.getpeercert()
  951. self.assertTrue(cert)
  952. finally:
  953. s.close()
  954. self.assertEqual(len(ctx.get_ca_certs()), 1)
  955. try:
  956. import threading
  957. except ImportError:
  958. _have_threads = False
  959. else:
  960. _have_threads = True
  961. from test.ssl_servers import make_https_server
  962. class ThreadedEchoServer(threading.Thread):
  963. class ConnectionHandler(threading.Thread):
  964. """A mildly complicated class, because we want it to work both
  965. with and without the SSL wrapper around the socket connection, so
  966. that we can test the STARTTLS functionality."""
  967. def __init__(self, server, connsock, addr):
  968. self.server = server
  969. self.running = False
  970. self.sock = connsock
  971. self.addr = addr
  972. self.sock.setblocking(1)
  973. self.sslconn = None
  974. threading.Thread.__init__(self)
  975. self.daemon = True
  976. def wrap_conn(self):
  977. try:
  978. self.sslconn = self.server.context.wrap_socket(
  979. self.sock, server_side=True)
  980. self.server.selected_protocols.append(self.sslconn.selected_npn_protocol())
  981. except (ssl.SSLError, ConnectionResetError) as e:
  982. # We treat ConnectionResetError as though it were an
  983. # SSLError - OpenSSL on Ubuntu abruptly closes the
  984. # connection when asked to use an unsupported protocol.
  985. #
  986. # XXX Various errors can have happened here, for example
  987. # a mismatching protocol version, an invalid certificate,
  988. # or a low-level bug. This should be made more discriminating.
  989. self.server.conn_errors.append(e)
  990. if self.server.chatty:
  991. handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
  992. self.running = False
  993. self.server.stop()
  994. self.close()
  995. return False
  996. else:
  997. if self.server.context.verify_mode == ssl.CERT_REQUIRED:
  998. cert = self.sslconn.getpeercert()
  999. if support.verbose and self.server.chatty:
  1000. sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
  1001. cert_binary = self.sslconn.getpeercert(True)
  1002. if support.verbose and self.server.chatty:
  1003. sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
  1004. cipher = self.sslconn.cipher()
  1005. if support.verbose and self.server.chatty:
  1006. sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
  1007. sys.stdout.write(" server: selected protocol is now "
  1008. + str(self.sslconn.selected_npn_protocol()) + "\n")
  1009. return True
  1010. def read(self):
  1011. if self.sslconn:
  1012. return self.sslconn.read()
  1013. else:
  1014. return self.sock.recv(1024)
  1015. def write(self, bytes):
  1016. if self.sslconn:
  1017. return self.sslconn.write(bytes)
  1018. else:
  1019. return self.sock.send(bytes)
  1020. def close(self):
  1021. if self.sslconn:
  1022. self.sslconn.close()
  1023. else:
  1024. self.sock.close()
  1025. def run(self):
  1026. self.running = True
  1027. if not self.server.starttls_server:
  1028. if not self.wrap_conn():
  1029. return
  1030. while self.running:
  1031. try:
  1032. msg = self.read()
  1033. stripped = msg.strip()
  1034. if not stripped:
  1035. # eof, so quit this handler
  1036. self.running = False
  1037. self.close()
  1038. elif stripped == b'over':
  1039. if support.verbose and self.server.connectionchatty:
  1040. sys.stdout.write(" server: client closed connection\n")
  1041. self.close()
  1042. return
  1043. elif (self.server.starttls_server and
  1044. stripped == b'STARTTLS'):

Large files files are truncated, but you can click here to view the full file