ssl_context.py 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. # Copyright 2014-2015 MongoDB, Inc.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you
  4. # may not use this file except in compliance with the License. You
  5. # may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  12. # implied. See the License for the specific language governing
  13. # permissions and limitations under the License.
  14. """A fake SSLContext implementation."""
  15. try:
  16. import ssl
  17. except ImportError:
  18. pass
  19. class SSLContext(object):
  20. """A fake SSLContext.
  21. This implements an API similar to ssl.SSLContext from python 3.2
  22. but does not implement methods or properties that would be
  23. incompatible with ssl.wrap_socket from python 2.6.
  24. You must pass protocol which must be one of the PROTOCOL_* constants
  25. defined in the ssl module. ssl.PROTOCOL_SSLv23 is recommended for maximum
  26. interoperability.
  27. """
  28. __slots__ = ('_cafile', '_certfile',
  29. '_keyfile', '_protocol', '_verify_mode')
  30. def __init__(self, protocol):
  31. self._cafile = None
  32. self._certfile = None
  33. self._keyfile = None
  34. self._protocol = protocol
  35. self._verify_mode = ssl.CERT_NONE
  36. @property
  37. def protocol(self):
  38. """The protocol version chosen when constructing the context.
  39. This attribute is read-only.
  40. """
  41. return self._protocol
  42. def __get_verify_mode(self):
  43. """Whether to try to verify other peers' certificates and how to
  44. behave if verification fails. This attribute must be one of
  45. ssl.CERT_NONE, ssl.CERT_OPTIONAL or ssl.CERT_REQUIRED.
  46. """
  47. return self._verify_mode
  48. def __set_verify_mode(self, value):
  49. """Setter for verify_mode."""
  50. self._verify_mode = value
  51. verify_mode = property(__get_verify_mode, __set_verify_mode)
  52. def load_cert_chain(self, certfile, keyfile=None):
  53. """Load a private key and the corresponding certificate. The certfile
  54. string must be the path to a single file in PEM format containing the
  55. certificate as well as any number of CA certificates needed to
  56. establish the certificate's authenticity. The keyfile string, if
  57. present, must point to a file containing the private key. Otherwise
  58. the private key will be taken from certfile as well.
  59. """
  60. self._certfile = certfile
  61. self._keyfile = keyfile
  62. def load_verify_locations(self, cafile=None, dummy=None):
  63. """Load a set of "certification authority"(CA) certificates used to
  64. validate other peers' certificates when `~verify_mode` is other than
  65. ssl.CERT_NONE.
  66. """
  67. self._cafile = cafile
  68. def wrap_socket(self, sock, server_side=False,
  69. do_handshake_on_connect=True,
  70. suppress_ragged_eofs=True, dummy=None):
  71. """Wrap an existing Python socket sock and return an ssl.SSLSocket
  72. object.
  73. """
  74. return ssl.wrap_socket(sock, keyfile=self._keyfile,
  75. certfile=self._certfile,
  76. server_side=server_side,
  77. cert_reqs=self._verify_mode,
  78. ssl_version=self._protocol,
  79. ca_certs=self._cafile,
  80. do_handshake_on_connect=do_handshake_on_connect,
  81. suppress_ragged_eofs=suppress_ragged_eofs)