Issue #26470: Port ssl and hashlib module to OpenSSL 1.1.0.
This commit is contained in:
parent
b3b7a5a16b
commit
598894ff48
|
@ -178,7 +178,7 @@ instead.
|
||||||
use. Typically, the server chooses a particular protocol version, and the
|
use. Typically, the server chooses a particular protocol version, and the
|
||||||
client must adapt to the server's choice. Most of the versions are not
|
client must adapt to the server's choice. Most of the versions are not
|
||||||
interoperable with the other versions. If not specified, the default is
|
interoperable with the other versions. If not specified, the default is
|
||||||
:data:`PROTOCOL_SSLv23`; it provides the most compatibility with other
|
:data:`PROTOCOL_TLS`; it provides the most compatibility with other
|
||||||
versions.
|
versions.
|
||||||
|
|
||||||
Here's a table showing which versions in a client (down the side) can connect
|
Here's a table showing which versions in a client (down the side) can connect
|
||||||
|
@ -187,11 +187,11 @@ instead.
|
||||||
.. table::
|
.. table::
|
||||||
|
|
||||||
======================== ========= ========= ========== ========= =========== ===========
|
======================== ========= ========= ========== ========= =========== ===========
|
||||||
*client* / **server** **SSLv2** **SSLv3** **SSLv23** **TLSv1** **TLSv1.1** **TLSv1.2**
|
*client* / **server** **SSLv2** **SSLv3** **TLS** **TLSv1** **TLSv1.1** **TLSv1.2**
|
||||||
------------------------ --------- --------- ---------- --------- ----------- -----------
|
------------------------ --------- --------- ---------- --------- ----------- -----------
|
||||||
*SSLv2* yes no yes no no no
|
*SSLv2* yes no yes no no no
|
||||||
*SSLv3* no yes yes no no no
|
*SSLv3* no yes yes no no no
|
||||||
*SSLv23* no yes yes yes yes yes
|
*TLS* (*SSLv23*) no yes yes yes yes yes
|
||||||
*TLSv1* no no yes yes no no
|
*TLSv1* no no yes yes no no
|
||||||
*TLSv1.1* no no yes no yes no
|
*TLSv1.1* no no yes no yes no
|
||||||
*TLSv1.2* no no yes no no yes
|
*TLSv1.2* no no yes no no yes
|
||||||
|
@ -244,7 +244,7 @@ purposes.
|
||||||
:const:`None`, this function can choose to trust the system's default
|
:const:`None`, this function can choose to trust the system's default
|
||||||
CA certificates instead.
|
CA certificates instead.
|
||||||
|
|
||||||
The settings are: :data:`PROTOCOL_SSLv23`, :data:`OP_NO_SSLv2`, and
|
The settings are: :data:`PROTOCOL_TLS`, :data:`OP_NO_SSLv2`, and
|
||||||
:data:`OP_NO_SSLv3` with high encryption cipher suites without RC4 and
|
:data:`OP_NO_SSLv3` with high encryption cipher suites without RC4 and
|
||||||
without unauthenticated cipher suites. Passing :data:`~Purpose.SERVER_AUTH`
|
without unauthenticated cipher suites. Passing :data:`~Purpose.SERVER_AUTH`
|
||||||
as *purpose* sets :data:`~SSLContext.verify_mode` to :data:`CERT_REQUIRED`
|
as *purpose* sets :data:`~SSLContext.verify_mode` to :data:`CERT_REQUIRED`
|
||||||
|
@ -316,6 +316,11 @@ Random generation
|
||||||
|
|
||||||
.. versionadded:: 3.3
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
.. deprecated:: 3.5.3
|
||||||
|
|
||||||
|
OpenSSL has deprecated :func:`ssl.RAND_pseudo_bytes`, use
|
||||||
|
:func:`ssl.RAND_bytes` instead.
|
||||||
|
|
||||||
.. function:: RAND_status()
|
.. function:: RAND_status()
|
||||||
|
|
||||||
Return ``True`` if the SSL pseudo-random number generator has been seeded
|
Return ``True`` if the SSL pseudo-random number generator has been seeded
|
||||||
|
@ -334,7 +339,7 @@ Random generation
|
||||||
See http://egd.sourceforge.net/ or http://prngd.sourceforge.net/ for sources
|
See http://egd.sourceforge.net/ or http://prngd.sourceforge.net/ for sources
|
||||||
of entropy-gathering daemons.
|
of entropy-gathering daemons.
|
||||||
|
|
||||||
Availability: not available with LibreSSL.
|
Availability: not available with LibreSSL and OpenSSL > 1.1.0
|
||||||
|
|
||||||
.. function:: RAND_add(bytes, entropy)
|
.. function:: RAND_add(bytes, entropy)
|
||||||
|
|
||||||
|
@ -409,7 +414,7 @@ Certificate handling
|
||||||
previously. Return an integer (no fractions of a second in the
|
previously. Return an integer (no fractions of a second in the
|
||||||
input format)
|
input format)
|
||||||
|
|
||||||
.. function:: get_server_certificate(addr, ssl_version=PROTOCOL_SSLv23, ca_certs=None)
|
.. function:: get_server_certificate(addr, ssl_version=PROTOCOL_TLS, ca_certs=None)
|
||||||
|
|
||||||
Given the address ``addr`` of an SSL-protected server, as a (*hostname*,
|
Given the address ``addr`` of an SSL-protected server, as a (*hostname*,
|
||||||
*port-number*) pair, fetches the server's certificate, and returns it as a
|
*port-number*) pair, fetches the server's certificate, and returns it as a
|
||||||
|
@ -425,7 +430,7 @@ Certificate handling
|
||||||
|
|
||||||
.. versionchanged:: 3.5
|
.. versionchanged:: 3.5
|
||||||
The default *ssl_version* is changed from :data:`PROTOCOL_SSLv3` to
|
The default *ssl_version* is changed from :data:`PROTOCOL_SSLv3` to
|
||||||
:data:`PROTOCOL_SSLv23` for maximum compatibility with modern servers.
|
:data:`PROTOCOL_TLS` for maximum compatibility with modern servers.
|
||||||
|
|
||||||
.. function:: DER_cert_to_PEM_cert(DER_cert_bytes)
|
.. function:: DER_cert_to_PEM_cert(DER_cert_bytes)
|
||||||
|
|
||||||
|
@ -451,6 +456,9 @@ Certificate handling
|
||||||
* :attr:`openssl_capath_env` - OpenSSL's environment key that points to a capath,
|
* :attr:`openssl_capath_env` - OpenSSL's environment key that points to a capath,
|
||||||
* :attr:`openssl_capath` - hard coded path to a capath directory
|
* :attr:`openssl_capath` - hard coded path to a capath directory
|
||||||
|
|
||||||
|
Availability: LibreSSL ignores the environment vars
|
||||||
|
:attr:`openssl_cafile_env` and :attr:`openssl_capath_env`
|
||||||
|
|
||||||
.. versionadded:: 3.4
|
.. versionadded:: 3.4
|
||||||
|
|
||||||
.. function:: enum_certificates(store_name)
|
.. function:: enum_certificates(store_name)
|
||||||
|
@ -568,11 +576,21 @@ Constants
|
||||||
|
|
||||||
.. versionadded:: 3.4.4
|
.. versionadded:: 3.4.4
|
||||||
|
|
||||||
.. data:: PROTOCOL_SSLv23
|
.. data:: PROTOCOL_TLS
|
||||||
|
|
||||||
Selects the highest protocol version that both the client and server support.
|
Selects the highest protocol version that both the client and server support.
|
||||||
Despite the name, this option can select "TLS" protocols as well as "SSL".
|
Despite the name, this option can select "TLS" protocols as well as "SSL".
|
||||||
|
|
||||||
|
.. versionadded:: 3.5.3
|
||||||
|
|
||||||
|
.. data:: PROTOCOL_SSLv23
|
||||||
|
|
||||||
|
Alias for data:`PROTOCOL_TLS`.
|
||||||
|
|
||||||
|
.. deprecated:: 3.5.3
|
||||||
|
|
||||||
|
Use data:`PROTOCOL_TLS` instead.
|
||||||
|
|
||||||
.. data:: PROTOCOL_SSLv2
|
.. data:: PROTOCOL_SSLv2
|
||||||
|
|
||||||
Selects SSL version 2 as the channel encryption protocol.
|
Selects SSL version 2 as the channel encryption protocol.
|
||||||
|
@ -584,6 +602,10 @@ Constants
|
||||||
|
|
||||||
SSL version 2 is insecure. Its use is highly discouraged.
|
SSL version 2 is insecure. Its use is highly discouraged.
|
||||||
|
|
||||||
|
.. deprecated:: 3.5.3
|
||||||
|
|
||||||
|
OpenSSL has removed support for SSLv2.
|
||||||
|
|
||||||
.. data:: PROTOCOL_SSLv3
|
.. data:: PROTOCOL_SSLv3
|
||||||
|
|
||||||
Selects SSL version 3 as the channel encryption protocol.
|
Selects SSL version 3 as the channel encryption protocol.
|
||||||
|
@ -595,10 +617,20 @@ Constants
|
||||||
|
|
||||||
SSL version 3 is insecure. Its use is highly discouraged.
|
SSL version 3 is insecure. Its use is highly discouraged.
|
||||||
|
|
||||||
|
.. deprecated:: 3.5.3
|
||||||
|
|
||||||
|
OpenSSL has deprecated all version specific protocols. Use the default
|
||||||
|
protocol data:`PROTOCOL_TLS` with flags like data:`OP_NO_SSLv3` instead.
|
||||||
|
|
||||||
.. data:: PROTOCOL_TLSv1
|
.. data:: PROTOCOL_TLSv1
|
||||||
|
|
||||||
Selects TLS version 1.0 as the channel encryption protocol.
|
Selects TLS version 1.0 as the channel encryption protocol.
|
||||||
|
|
||||||
|
.. deprecated:: 3.5.3
|
||||||
|
|
||||||
|
OpenSSL has deprecated all version specific protocols. Use the default
|
||||||
|
protocol data:`PROTOCOL_TLS` with flags like data:`OP_NO_SSLv3` instead.
|
||||||
|
|
||||||
.. data:: PROTOCOL_TLSv1_1
|
.. data:: PROTOCOL_TLSv1_1
|
||||||
|
|
||||||
Selects TLS version 1.1 as the channel encryption protocol.
|
Selects TLS version 1.1 as the channel encryption protocol.
|
||||||
|
@ -606,6 +638,11 @@ Constants
|
||||||
|
|
||||||
.. versionadded:: 3.4
|
.. versionadded:: 3.4
|
||||||
|
|
||||||
|
.. deprecated:: 3.5.3
|
||||||
|
|
||||||
|
OpenSSL has deprecated all version specific protocols. Use the default
|
||||||
|
protocol data:`PROTOCOL_TLS` with flags like data:`OP_NO_SSLv3` instead.
|
||||||
|
|
||||||
.. data:: PROTOCOL_TLSv1_2
|
.. data:: PROTOCOL_TLSv1_2
|
||||||
|
|
||||||
Selects TLS version 1.2 as the channel encryption protocol. This is the
|
Selects TLS version 1.2 as the channel encryption protocol. This is the
|
||||||
|
@ -614,6 +651,11 @@ Constants
|
||||||
|
|
||||||
.. versionadded:: 3.4
|
.. versionadded:: 3.4
|
||||||
|
|
||||||
|
.. deprecated:: 3.5.3
|
||||||
|
|
||||||
|
OpenSSL has deprecated all version specific protocols. Use the default
|
||||||
|
protocol data:`PROTOCOL_TLS` with flags like data:`OP_NO_SSLv3` instead.
|
||||||
|
|
||||||
.. data:: OP_ALL
|
.. data:: OP_ALL
|
||||||
|
|
||||||
Enables workarounds for various bugs present in other SSL implementations.
|
Enables workarounds for various bugs present in other SSL implementations.
|
||||||
|
@ -625,23 +667,32 @@ Constants
|
||||||
.. data:: OP_NO_SSLv2
|
.. data:: OP_NO_SSLv2
|
||||||
|
|
||||||
Prevents an SSLv2 connection. This option is only applicable in
|
Prevents an SSLv2 connection. This option is only applicable in
|
||||||
conjunction with :const:`PROTOCOL_SSLv23`. It prevents the peers from
|
conjunction with :const:`PROTOCOL_TLS`. It prevents the peers from
|
||||||
choosing SSLv2 as the protocol version.
|
choosing SSLv2 as the protocol version.
|
||||||
|
|
||||||
.. versionadded:: 3.2
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
.. deprecated:: 3.5.3
|
||||||
|
|
||||||
|
SSLv2 is deprecated
|
||||||
|
|
||||||
|
|
||||||
.. data:: OP_NO_SSLv3
|
.. data:: OP_NO_SSLv3
|
||||||
|
|
||||||
Prevents an SSLv3 connection. This option is only applicable in
|
Prevents an SSLv3 connection. This option is only applicable in
|
||||||
conjunction with :const:`PROTOCOL_SSLv23`. It prevents the peers from
|
conjunction with :const:`PROTOCOL_TLS`. It prevents the peers from
|
||||||
choosing SSLv3 as the protocol version.
|
choosing SSLv3 as the protocol version.
|
||||||
|
|
||||||
.. versionadded:: 3.2
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
.. deprecated:: 3.5.3
|
||||||
|
|
||||||
|
SSLv3 is deprecated
|
||||||
|
|
||||||
.. data:: OP_NO_TLSv1
|
.. data:: OP_NO_TLSv1
|
||||||
|
|
||||||
Prevents a TLSv1 connection. This option is only applicable in
|
Prevents a TLSv1 connection. This option is only applicable in
|
||||||
conjunction with :const:`PROTOCOL_SSLv23`. It prevents the peers from
|
conjunction with :const:`PROTOCOL_TLS`. It prevents the peers from
|
||||||
choosing TLSv1 as the protocol version.
|
choosing TLSv1 as the protocol version.
|
||||||
|
|
||||||
.. versionadded:: 3.2
|
.. versionadded:: 3.2
|
||||||
|
@ -649,7 +700,7 @@ Constants
|
||||||
.. data:: OP_NO_TLSv1_1
|
.. data:: OP_NO_TLSv1_1
|
||||||
|
|
||||||
Prevents a TLSv1.1 connection. This option is only applicable in conjunction
|
Prevents a TLSv1.1 connection. This option is only applicable in conjunction
|
||||||
with :const:`PROTOCOL_SSLv23`. It prevents the peers from choosing TLSv1.1 as
|
with :const:`PROTOCOL_TLS`. It prevents the peers from choosing TLSv1.1 as
|
||||||
the protocol version. Available only with openssl version 1.0.1+.
|
the protocol version. Available only with openssl version 1.0.1+.
|
||||||
|
|
||||||
.. versionadded:: 3.4
|
.. versionadded:: 3.4
|
||||||
|
@ -657,7 +708,7 @@ Constants
|
||||||
.. data:: OP_NO_TLSv1_2
|
.. data:: OP_NO_TLSv1_2
|
||||||
|
|
||||||
Prevents a TLSv1.2 connection. This option is only applicable in conjunction
|
Prevents a TLSv1.2 connection. This option is only applicable in conjunction
|
||||||
with :const:`PROTOCOL_SSLv23`. It prevents the peers from choosing TLSv1.2 as
|
with :const:`PROTOCOL_TLS`. It prevents the peers from choosing TLSv1.2 as
|
||||||
the protocol version. Available only with openssl version 1.0.1+.
|
the protocol version. Available only with openssl version 1.0.1+.
|
||||||
|
|
||||||
.. versionadded:: 3.4
|
.. versionadded:: 3.4
|
||||||
|
@ -1081,17 +1132,21 @@ such as SSL configuration options, certificate(s) and private key(s).
|
||||||
It also manages a cache of SSL sessions for server-side sockets, in order
|
It also manages a cache of SSL sessions for server-side sockets, in order
|
||||||
to speed up repeated connections from the same clients.
|
to speed up repeated connections from the same clients.
|
||||||
|
|
||||||
.. class:: SSLContext(protocol)
|
.. class:: SSLContext(protocol=PROTOCOL_TLS)
|
||||||
|
|
||||||
Create a new SSL context. You must pass *protocol* which must be one
|
Create a new SSL context. You may pass *protocol* which must be one
|
||||||
of the ``PROTOCOL_*`` constants defined in this module.
|
of the ``PROTOCOL_*`` constants defined in this module.
|
||||||
:data:`PROTOCOL_SSLv23` is currently recommended for maximum
|
:data:`PROTOCOL_TLS` is currently recommended for maximum
|
||||||
interoperability.
|
interoperability and default value.
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
:func:`create_default_context` lets the :mod:`ssl` module choose
|
:func:`create_default_context` lets the :mod:`ssl` module choose
|
||||||
security settings for a given purpose.
|
security settings for a given purpose.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.5.3
|
||||||
|
|
||||||
|
:data:`PROTOCOL_TLS` is the default value.
|
||||||
|
|
||||||
|
|
||||||
:class:`SSLContext` objects have the following methods and attributes:
|
:class:`SSLContext` objects have the following methods and attributes:
|
||||||
|
|
||||||
|
@ -1232,6 +1287,9 @@ to speed up repeated connections from the same clients.
|
||||||
This method will raise :exc:`NotImplementedError` if :data:`HAS_ALPN` is
|
This method will raise :exc:`NotImplementedError` if :data:`HAS_ALPN` is
|
||||||
False.
|
False.
|
||||||
|
|
||||||
|
OpenSSL 1.1.0+ will abort the handshake and raise :exc:`SSLError` when
|
||||||
|
both sides support ALPN but cannot agree on a protocol.
|
||||||
|
|
||||||
.. versionadded:: 3.5
|
.. versionadded:: 3.5
|
||||||
|
|
||||||
.. method:: SSLContext.set_npn_protocols(protocols)
|
.. method:: SSLContext.set_npn_protocols(protocols)
|
||||||
|
@ -1598,7 +1656,7 @@ If you prefer to tune security settings yourself, you might create
|
||||||
a context from scratch (but beware that you might not get the settings
|
a context from scratch (but beware that you might not get the settings
|
||||||
right)::
|
right)::
|
||||||
|
|
||||||
>>> context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
>>> context = ssl.SSLContext(ssl.PROTOCOL_TLS)
|
||||||
>>> context.verify_mode = ssl.CERT_REQUIRED
|
>>> context.verify_mode = ssl.CERT_REQUIRED
|
||||||
>>> context.check_hostname = True
|
>>> context.check_hostname = True
|
||||||
>>> context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")
|
>>> context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")
|
||||||
|
@ -1999,15 +2057,17 @@ Protocol versions
|
||||||
|
|
||||||
SSL versions 2 and 3 are considered insecure and are therefore dangerous to
|
SSL versions 2 and 3 are considered insecure and are therefore dangerous to
|
||||||
use. If you want maximum compatibility between clients and servers, it is
|
use. If you want maximum compatibility between clients and servers, it is
|
||||||
recommended to use :const:`PROTOCOL_SSLv23` as the protocol version and then
|
recommended to use :const:`PROTOCOL_TLS` as the protocol version and then
|
||||||
disable SSLv2 and SSLv3 explicitly using the :data:`SSLContext.options`
|
disable SSLv2 and SSLv3 explicitly using the :data:`SSLContext.options`
|
||||||
attribute::
|
attribute::
|
||||||
|
|
||||||
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
|
||||||
context.options |= ssl.OP_NO_SSLv2
|
context.options |= ssl.OP_NO_SSLv2
|
||||||
context.options |= ssl.OP_NO_SSLv3
|
context.options |= ssl.OP_NO_SSLv3
|
||||||
|
context.options |= ssl.OP_NO_TLSv1
|
||||||
|
context.options |= ssl.OP_NO_TLSv1_1
|
||||||
|
|
||||||
The SSL context created above will only allow TLSv1 and later (if
|
The SSL context created above will only allow TLSv1.2 and later (if
|
||||||
supported by your system) connections.
|
supported by your system) connections.
|
||||||
|
|
||||||
Cipher selection
|
Cipher selection
|
||||||
|
|
18
Lib/ssl.py
18
Lib/ssl.py
|
@ -51,6 +51,7 @@ The following constants identify various SSL protocol variants:
|
||||||
PROTOCOL_SSLv2
|
PROTOCOL_SSLv2
|
||||||
PROTOCOL_SSLv3
|
PROTOCOL_SSLv3
|
||||||
PROTOCOL_SSLv23
|
PROTOCOL_SSLv23
|
||||||
|
PROTOCOL_TLS
|
||||||
PROTOCOL_TLSv1
|
PROTOCOL_TLSv1
|
||||||
PROTOCOL_TLSv1_1
|
PROTOCOL_TLSv1_1
|
||||||
PROTOCOL_TLSv1_2
|
PROTOCOL_TLSv1_2
|
||||||
|
@ -128,9 +129,10 @@ from _ssl import _OPENSSL_API_VERSION
|
||||||
|
|
||||||
_IntEnum._convert(
|
_IntEnum._convert(
|
||||||
'_SSLMethod', __name__,
|
'_SSLMethod', __name__,
|
||||||
lambda name: name.startswith('PROTOCOL_'),
|
lambda name: name.startswith('PROTOCOL_') and name != 'PROTOCOL_SSLv23',
|
||||||
source=_ssl)
|
source=_ssl)
|
||||||
|
|
||||||
|
PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_TLS
|
||||||
_PROTOCOL_NAMES = {value: name for name, value in _SSLMethod.__members__.items()}
|
_PROTOCOL_NAMES = {value: name for name, value in _SSLMethod.__members__.items()}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -357,13 +359,13 @@ class SSLContext(_SSLContext):
|
||||||
__slots__ = ('protocol', '__weakref__')
|
__slots__ = ('protocol', '__weakref__')
|
||||||
_windows_cert_stores = ("CA", "ROOT")
|
_windows_cert_stores = ("CA", "ROOT")
|
||||||
|
|
||||||
def __new__(cls, protocol, *args, **kwargs):
|
def __new__(cls, protocol=PROTOCOL_TLS, *args, **kwargs):
|
||||||
self = _SSLContext.__new__(cls, protocol)
|
self = _SSLContext.__new__(cls, protocol)
|
||||||
if protocol != _SSLv2_IF_EXISTS:
|
if protocol != _SSLv2_IF_EXISTS:
|
||||||
self.set_ciphers(_DEFAULT_CIPHERS)
|
self.set_ciphers(_DEFAULT_CIPHERS)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __init__(self, protocol):
|
def __init__(self, protocol=PROTOCOL_TLS):
|
||||||
self.protocol = protocol
|
self.protocol = protocol
|
||||||
|
|
||||||
def wrap_socket(self, sock, server_side=False,
|
def wrap_socket(self, sock, server_side=False,
|
||||||
|
@ -438,7 +440,7 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None,
|
||||||
if not isinstance(purpose, _ASN1Object):
|
if not isinstance(purpose, _ASN1Object):
|
||||||
raise TypeError(purpose)
|
raise TypeError(purpose)
|
||||||
|
|
||||||
context = SSLContext(PROTOCOL_SSLv23)
|
context = SSLContext(PROTOCOL_TLS)
|
||||||
|
|
||||||
# SSLv2 considered harmful.
|
# SSLv2 considered harmful.
|
||||||
context.options |= OP_NO_SSLv2
|
context.options |= OP_NO_SSLv2
|
||||||
|
@ -475,7 +477,7 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None,
|
||||||
context.load_default_certs(purpose)
|
context.load_default_certs(purpose)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def _create_unverified_context(protocol=PROTOCOL_SSLv23, *, cert_reqs=None,
|
def _create_unverified_context(protocol=PROTOCOL_TLS, *, cert_reqs=None,
|
||||||
check_hostname=False, purpose=Purpose.SERVER_AUTH,
|
check_hostname=False, purpose=Purpose.SERVER_AUTH,
|
||||||
certfile=None, keyfile=None,
|
certfile=None, keyfile=None,
|
||||||
cafile=None, capath=None, cadata=None):
|
cafile=None, capath=None, cadata=None):
|
||||||
|
@ -666,7 +668,7 @@ class SSLSocket(socket):
|
||||||
|
|
||||||
def __init__(self, sock=None, keyfile=None, certfile=None,
|
def __init__(self, sock=None, keyfile=None, certfile=None,
|
||||||
server_side=False, cert_reqs=CERT_NONE,
|
server_side=False, cert_reqs=CERT_NONE,
|
||||||
ssl_version=PROTOCOL_SSLv23, ca_certs=None,
|
ssl_version=PROTOCOL_TLS, ca_certs=None,
|
||||||
do_handshake_on_connect=True,
|
do_handshake_on_connect=True,
|
||||||
family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None,
|
family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None,
|
||||||
suppress_ragged_eofs=True, npn_protocols=None, ciphers=None,
|
suppress_ragged_eofs=True, npn_protocols=None, ciphers=None,
|
||||||
|
@ -1056,7 +1058,7 @@ class SSLSocket(socket):
|
||||||
|
|
||||||
def wrap_socket(sock, keyfile=None, certfile=None,
|
def wrap_socket(sock, keyfile=None, certfile=None,
|
||||||
server_side=False, cert_reqs=CERT_NONE,
|
server_side=False, cert_reqs=CERT_NONE,
|
||||||
ssl_version=PROTOCOL_SSLv23, ca_certs=None,
|
ssl_version=PROTOCOL_TLS, ca_certs=None,
|
||||||
do_handshake_on_connect=True,
|
do_handshake_on_connect=True,
|
||||||
suppress_ragged_eofs=True,
|
suppress_ragged_eofs=True,
|
||||||
ciphers=None):
|
ciphers=None):
|
||||||
|
@ -1125,7 +1127,7 @@ def PEM_cert_to_DER_cert(pem_cert_string):
|
||||||
d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)]
|
d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)]
|
||||||
return base64.decodebytes(d.encode('ASCII', 'strict'))
|
return base64.decodebytes(d.encode('ASCII', 'strict'))
|
||||||
|
|
||||||
def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv23, ca_certs=None):
|
def get_server_certificate(addr, ssl_version=PROTOCOL_TLS, ca_certs=None):
|
||||||
"""Retrieve the certificate from the server at the specified address,
|
"""Retrieve the certificate from the server at the specified address,
|
||||||
and return it as a PEM-encoded string.
|
and return it as a PEM-encoded string.
|
||||||
If 'ca_certs' is specified, validate the server cert against it.
|
If 'ca_certs' is specified, validate the server cert against it.
|
||||||
|
|
|
@ -23,6 +23,9 @@ ssl = support.import_module("ssl")
|
||||||
|
|
||||||
PROTOCOLS = sorted(ssl._PROTOCOL_NAMES)
|
PROTOCOLS = sorted(ssl._PROTOCOL_NAMES)
|
||||||
HOST = support.HOST
|
HOST = support.HOST
|
||||||
|
IS_LIBRESSL = ssl.OPENSSL_VERSION.startswith('LibreSSL')
|
||||||
|
IS_OPENSSL_1_1 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0)
|
||||||
|
|
||||||
|
|
||||||
def data_file(*name):
|
def data_file(*name):
|
||||||
return os.path.join(os.path.dirname(__file__), *name)
|
return os.path.join(os.path.dirname(__file__), *name)
|
||||||
|
@ -143,8 +146,8 @@ class BasicSocketTests(unittest.TestCase):
|
||||||
def test_str_for_enums(self):
|
def test_str_for_enums(self):
|
||||||
# Make sure that the PROTOCOL_* constants have enum-like string
|
# Make sure that the PROTOCOL_* constants have enum-like string
|
||||||
# reprs.
|
# reprs.
|
||||||
proto = ssl.PROTOCOL_SSLv23
|
proto = ssl.PROTOCOL_TLS
|
||||||
self.assertEqual(str(proto), '_SSLMethod.PROTOCOL_SSLv23')
|
self.assertEqual(str(proto), '_SSLMethod.PROTOCOL_TLS')
|
||||||
ctx = ssl.SSLContext(proto)
|
ctx = ssl.SSLContext(proto)
|
||||||
self.assertIs(ctx.protocol, proto)
|
self.assertIs(ctx.protocol, proto)
|
||||||
|
|
||||||
|
@ -312,8 +315,8 @@ class BasicSocketTests(unittest.TestCase):
|
||||||
self.assertGreaterEqual(status, 0)
|
self.assertGreaterEqual(status, 0)
|
||||||
self.assertLessEqual(status, 15)
|
self.assertLessEqual(status, 15)
|
||||||
# Version string as returned by {Open,Libre}SSL, the format might change
|
# Version string as returned by {Open,Libre}SSL, the format might change
|
||||||
if "LibreSSL" in s:
|
if IS_LIBRESSL:
|
||||||
self.assertTrue(s.startswith("LibreSSL {:d}.{:d}".format(major, minor)),
|
self.assertTrue(s.startswith("LibreSSL {:d}".format(major)),
|
||||||
(s, t, hex(n)))
|
(s, t, hex(n)))
|
||||||
else:
|
else:
|
||||||
self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
|
self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
|
||||||
|
@ -790,7 +793,8 @@ class ContextTests(unittest.TestCase):
|
||||||
def test_constructor(self):
|
def test_constructor(self):
|
||||||
for protocol in PROTOCOLS:
|
for protocol in PROTOCOLS:
|
||||||
ssl.SSLContext(protocol)
|
ssl.SSLContext(protocol)
|
||||||
self.assertRaises(TypeError, ssl.SSLContext)
|
ctx = ssl.SSLContext()
|
||||||
|
self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLS)
|
||||||
self.assertRaises(ValueError, ssl.SSLContext, -1)
|
self.assertRaises(ValueError, ssl.SSLContext, -1)
|
||||||
self.assertRaises(ValueError, ssl.SSLContext, 42)
|
self.assertRaises(ValueError, ssl.SSLContext, 42)
|
||||||
|
|
||||||
|
@ -811,15 +815,15 @@ class ContextTests(unittest.TestCase):
|
||||||
def test_options(self):
|
def test_options(self):
|
||||||
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
||||||
# OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value
|
# OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value
|
||||||
self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3,
|
default = (ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
|
||||||
ctx.options)
|
if not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0):
|
||||||
|
default |= ssl.OP_NO_COMPRESSION
|
||||||
|
self.assertEqual(default, ctx.options)
|
||||||
ctx.options |= ssl.OP_NO_TLSv1
|
ctx.options |= ssl.OP_NO_TLSv1
|
||||||
self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1,
|
self.assertEqual(default | ssl.OP_NO_TLSv1, ctx.options)
|
||||||
ctx.options)
|
|
||||||
if can_clear_options():
|
if can_clear_options():
|
||||||
ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1
|
ctx.options = (ctx.options & ~ssl.OP_NO_TLSv1)
|
||||||
self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3,
|
self.assertEqual(default, ctx.options)
|
||||||
ctx.options)
|
|
||||||
ctx.options = 0
|
ctx.options = 0
|
||||||
# Ubuntu has OP_NO_SSLv3 forced on by default
|
# Ubuntu has OP_NO_SSLv3 forced on by default
|
||||||
self.assertEqual(0, ctx.options & ~ssl.OP_NO_SSLv3)
|
self.assertEqual(0, ctx.options & ~ssl.OP_NO_SSLv3)
|
||||||
|
@ -1155,6 +1159,7 @@ class ContextTests(unittest.TestCase):
|
||||||
self.assertRaises(TypeError, ctx.load_default_certs, 'SERVER_AUTH')
|
self.assertRaises(TypeError, ctx.load_default_certs, 'SERVER_AUTH')
|
||||||
|
|
||||||
@unittest.skipIf(sys.platform == "win32", "not-Windows specific")
|
@unittest.skipIf(sys.platform == "win32", "not-Windows specific")
|
||||||
|
@unittest.skipIf(IS_LIBRESSL, "LibreSSL doesn't support env vars")
|
||||||
def test_load_default_certs_env(self):
|
def test_load_default_certs_env(self):
|
||||||
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
||||||
with support.EnvironmentVarGuard() as env:
|
with support.EnvironmentVarGuard() as env:
|
||||||
|
@ -1750,13 +1755,13 @@ class NetworkedBIOTests(unittest.TestCase):
|
||||||
sslobj = ctx.wrap_bio(incoming, outgoing, False, REMOTE_HOST)
|
sslobj = ctx.wrap_bio(incoming, outgoing, False, REMOTE_HOST)
|
||||||
self.assertIs(sslobj._sslobj.owner, sslobj)
|
self.assertIs(sslobj._sslobj.owner, sslobj)
|
||||||
self.assertIsNone(sslobj.cipher())
|
self.assertIsNone(sslobj.cipher())
|
||||||
self.assertIsNone(sslobj.shared_ciphers())
|
self.assertIsNotNone(sslobj.shared_ciphers())
|
||||||
self.assertRaises(ValueError, sslobj.getpeercert)
|
self.assertRaises(ValueError, sslobj.getpeercert)
|
||||||
if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES:
|
if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES:
|
||||||
self.assertIsNone(sslobj.get_channel_binding('tls-unique'))
|
self.assertIsNone(sslobj.get_channel_binding('tls-unique'))
|
||||||
self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake)
|
self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake)
|
||||||
self.assertTrue(sslobj.cipher())
|
self.assertTrue(sslobj.cipher())
|
||||||
self.assertIsNone(sslobj.shared_ciphers())
|
self.assertIsNotNone(sslobj.shared_ciphers())
|
||||||
self.assertTrue(sslobj.getpeercert())
|
self.assertTrue(sslobj.getpeercert())
|
||||||
if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES:
|
if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES:
|
||||||
self.assertTrue(sslobj.get_channel_binding('tls-unique'))
|
self.assertTrue(sslobj.get_channel_binding('tls-unique'))
|
||||||
|
@ -2993,7 +2998,7 @@ else:
|
||||||
with context.wrap_socket(socket.socket()) as s:
|
with context.wrap_socket(socket.socket()) as s:
|
||||||
self.assertIs(s.version(), None)
|
self.assertIs(s.version(), None)
|
||||||
s.connect((HOST, server.port))
|
s.connect((HOST, server.port))
|
||||||
self.assertEqual(s.version(), "TLSv1")
|
self.assertEqual(s.version(), 'TLSv1')
|
||||||
self.assertIs(s.version(), None)
|
self.assertIs(s.version(), None)
|
||||||
|
|
||||||
@unittest.skipUnless(ssl.HAS_ECDH, "test requires ECDH-enabled OpenSSL")
|
@unittest.skipUnless(ssl.HAS_ECDH, "test requires ECDH-enabled OpenSSL")
|
||||||
|
@ -3135,24 +3140,36 @@ else:
|
||||||
(['http/3.0', 'http/4.0'], None)
|
(['http/3.0', 'http/4.0'], None)
|
||||||
]
|
]
|
||||||
for client_protocols, expected in protocol_tests:
|
for client_protocols, expected in protocol_tests:
|
||||||
server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
|
||||||
server_context.load_cert_chain(CERTFILE)
|
server_context.load_cert_chain(CERTFILE)
|
||||||
server_context.set_alpn_protocols(server_protocols)
|
server_context.set_alpn_protocols(server_protocols)
|
||||||
client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
|
||||||
client_context.load_cert_chain(CERTFILE)
|
client_context.load_cert_chain(CERTFILE)
|
||||||
client_context.set_alpn_protocols(client_protocols)
|
client_context.set_alpn_protocols(client_protocols)
|
||||||
stats = server_params_test(client_context, server_context,
|
|
||||||
chatty=True, connectionchatty=True)
|
|
||||||
|
|
||||||
msg = "failed trying %s (s) and %s (c).\n" \
|
try:
|
||||||
"was expecting %s, but got %%s from the %%s" \
|
stats = server_params_test(client_context,
|
||||||
% (str(server_protocols), str(client_protocols),
|
server_context,
|
||||||
str(expected))
|
chatty=True,
|
||||||
client_result = stats['client_alpn_protocol']
|
connectionchatty=True)
|
||||||
self.assertEqual(client_result, expected, msg % (client_result, "client"))
|
except ssl.SSLError as e:
|
||||||
server_result = stats['server_alpn_protocols'][-1] \
|
stats = e
|
||||||
if len(stats['server_alpn_protocols']) else 'nothing'
|
|
||||||
self.assertEqual(server_result, expected, msg % (server_result, "server"))
|
if expected is None and IS_OPENSSL_1_1:
|
||||||
|
# OpenSSL 1.1.0 raises handshake error
|
||||||
|
self.assertIsInstance(stats, ssl.SSLError)
|
||||||
|
else:
|
||||||
|
msg = "failed trying %s (s) and %s (c).\n" \
|
||||||
|
"was expecting %s, but got %%s from the %%s" \
|
||||||
|
% (str(server_protocols), str(client_protocols),
|
||||||
|
str(expected))
|
||||||
|
client_result = stats['client_alpn_protocol']
|
||||||
|
self.assertEqual(client_result, expected,
|
||||||
|
msg % (client_result, "client"))
|
||||||
|
server_result = stats['server_alpn_protocols'][-1] \
|
||||||
|
if len(stats['server_alpn_protocols']) else 'nothing'
|
||||||
|
self.assertEqual(server_result, expected,
|
||||||
|
msg % (server_result, "server"))
|
||||||
|
|
||||||
def test_selected_npn_protocol(self):
|
def test_selected_npn_protocol(self):
|
||||||
# selected_npn_protocol() is None unless NPN is used
|
# selected_npn_protocol() is None unless NPN is used
|
||||||
|
@ -3300,13 +3317,23 @@ else:
|
||||||
client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
||||||
client_context.verify_mode = ssl.CERT_REQUIRED
|
client_context.verify_mode = ssl.CERT_REQUIRED
|
||||||
client_context.load_verify_locations(SIGNING_CA)
|
client_context.load_verify_locations(SIGNING_CA)
|
||||||
client_context.set_ciphers("RC4")
|
if ssl.OPENSSL_VERSION_INFO >= (1, 0, 2):
|
||||||
server_context.set_ciphers("AES:RC4")
|
client_context.set_ciphers("AES128:AES256")
|
||||||
|
server_context.set_ciphers("AES256")
|
||||||
|
alg1 = "AES256"
|
||||||
|
alg2 = "AES-256"
|
||||||
|
else:
|
||||||
|
client_context.set_ciphers("AES:3DES")
|
||||||
|
server_context.set_ciphers("3DES")
|
||||||
|
alg1 = "3DES"
|
||||||
|
alg2 = "DES-CBC3"
|
||||||
|
|
||||||
stats = server_params_test(client_context, server_context)
|
stats = server_params_test(client_context, server_context)
|
||||||
ciphers = stats['server_shared_ciphers'][0]
|
ciphers = stats['server_shared_ciphers'][0]
|
||||||
self.assertGreater(len(ciphers), 0)
|
self.assertGreater(len(ciphers), 0)
|
||||||
for name, tls_version, bits in ciphers:
|
for name, tls_version, bits in ciphers:
|
||||||
self.assertIn("RC4", name.split("-"))
|
if not alg1 in name.split("-") and alg2 not in name:
|
||||||
|
self.fail(name)
|
||||||
|
|
||||||
def test_read_write_after_close_raises_valuerror(self):
|
def test_read_write_after_close_raises_valuerror(self):
|
||||||
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
||||||
|
|
|
@ -60,6 +60,8 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #26470: Port ssl and hashlib module to OpenSSL 1.1.0.
|
||||||
|
|
||||||
- Issue #12885: Fix error when distutils encounters symlink.
|
- Issue #12885: Fix error when distutils encounters symlink.
|
||||||
|
|
||||||
- Issue #27881: Fixed possible bugs when setting sqlite3.Connection.isolation_level.
|
- Issue #27881: Fixed possible bugs when setting sqlite3.Connection.isolation_level.
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
|
|
||||||
/* EVP is the preferred interface to hashing in OpenSSL */
|
/* EVP is the preferred interface to hashing in OpenSSL */
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/hmac.h>
|
|
||||||
/* We use the object interface to discover what hashes OpenSSL supports. */
|
/* We use the object interface to discover what hashes OpenSSL supports. */
|
||||||
#include <openssl/objects.h>
|
#include <openssl/objects.h>
|
||||||
#include "openssl/err.h"
|
#include "openssl/err.h"
|
||||||
|
@ -32,11 +31,22 @@
|
||||||
#define HASH_OBJ_CONSTRUCTOR 0
|
#define HASH_OBJ_CONSTRUCTOR 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
|
||||||
|
/* OpenSSL < 1.1.0 */
|
||||||
|
#define EVP_MD_CTX_new EVP_MD_CTX_create
|
||||||
|
#define EVP_MD_CTX_free EVP_MD_CTX_destroy
|
||||||
|
#define HAS_FAST_PKCS5_PBKDF2_HMAC 0
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
#else
|
||||||
|
/* OpenSSL >= 1.1.0 */
|
||||||
|
#define HAS_FAST_PKCS5_PBKDF2_HMAC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
PyObject *name; /* name of this hash algorithm */
|
PyObject *name; /* name of this hash algorithm */
|
||||||
EVP_MD_CTX ctx; /* OpenSSL message digest context */
|
EVP_MD_CTX *ctx; /* OpenSSL message digest context */
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
PyThread_type_lock lock; /* OpenSSL context lock */
|
PyThread_type_lock lock; /* OpenSSL context lock */
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,7 +58,6 @@ static PyTypeObject EVPtype;
|
||||||
|
|
||||||
#define DEFINE_CONSTS_FOR_NEW(Name) \
|
#define DEFINE_CONSTS_FOR_NEW(Name) \
|
||||||
static PyObject *CONST_ ## Name ## _name_obj = NULL; \
|
static PyObject *CONST_ ## Name ## _name_obj = NULL; \
|
||||||
static EVP_MD_CTX CONST_new_ ## Name ## _ctx; \
|
|
||||||
static EVP_MD_CTX *CONST_new_ ## Name ## _ctx_p = NULL;
|
static EVP_MD_CTX *CONST_new_ ## Name ## _ctx_p = NULL;
|
||||||
|
|
||||||
DEFINE_CONSTS_FOR_NEW(md5)
|
DEFINE_CONSTS_FOR_NEW(md5)
|
||||||
|
@ -59,19 +68,57 @@ DEFINE_CONSTS_FOR_NEW(sha384)
|
||||||
DEFINE_CONSTS_FOR_NEW(sha512)
|
DEFINE_CONSTS_FOR_NEW(sha512)
|
||||||
|
|
||||||
|
|
||||||
|
/* LCOV_EXCL_START */
|
||||||
|
static PyObject *
|
||||||
|
_setException(PyObject *exc)
|
||||||
|
{
|
||||||
|
unsigned long errcode;
|
||||||
|
const char *lib, *func, *reason;
|
||||||
|
|
||||||
|
errcode = ERR_peek_last_error();
|
||||||
|
if (!errcode) {
|
||||||
|
PyErr_SetString(exc, "unknown reasons");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ERR_clear_error();
|
||||||
|
|
||||||
|
lib = ERR_lib_error_string(errcode);
|
||||||
|
func = ERR_func_error_string(errcode);
|
||||||
|
reason = ERR_reason_error_string(errcode);
|
||||||
|
|
||||||
|
if (lib && func) {
|
||||||
|
PyErr_Format(exc, "[%s: %s] %s", lib, func, reason);
|
||||||
|
}
|
||||||
|
else if (lib) {
|
||||||
|
PyErr_Format(exc, "[%s] %s", lib, reason);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PyErr_SetString(exc, reason);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* LCOV_EXCL_STOP */
|
||||||
|
|
||||||
static EVPobject *
|
static EVPobject *
|
||||||
newEVPobject(PyObject *name)
|
newEVPobject(PyObject *name)
|
||||||
{
|
{
|
||||||
EVPobject *retval = (EVPobject *)PyObject_New(EVPobject, &EVPtype);
|
EVPobject *retval = (EVPobject *)PyObject_New(EVPobject, &EVPtype);
|
||||||
|
if (retval == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval->ctx = EVP_MD_CTX_new();
|
||||||
|
if (retval->ctx == NULL) {
|
||||||
|
PyErr_NoMemory();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* save the name for .name to return */
|
/* save the name for .name to return */
|
||||||
if (retval != NULL) {
|
Py_INCREF(name);
|
||||||
Py_INCREF(name);
|
retval->name = name;
|
||||||
retval->name = name;
|
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
retval->lock = NULL;
|
retval->lock = NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -86,7 +133,7 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len)
|
||||||
process = MUNCH_SIZE;
|
process = MUNCH_SIZE;
|
||||||
else
|
else
|
||||||
process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int);
|
process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int);
|
||||||
EVP_DigestUpdate(&self->ctx, (const void*)cp, process);
|
EVP_DigestUpdate(self->ctx, (const void*)cp, process);
|
||||||
len -= process;
|
len -= process;
|
||||||
cp += process;
|
cp += process;
|
||||||
}
|
}
|
||||||
|
@ -101,16 +148,19 @@ EVP_dealloc(EVPobject *self)
|
||||||
if (self->lock != NULL)
|
if (self->lock != NULL)
|
||||||
PyThread_free_lock(self->lock);
|
PyThread_free_lock(self->lock);
|
||||||
#endif
|
#endif
|
||||||
EVP_MD_CTX_cleanup(&self->ctx);
|
EVP_MD_CTX_free(self->ctx);
|
||||||
Py_XDECREF(self->name);
|
Py_XDECREF(self->name);
|
||||||
PyObject_Del(self);
|
PyObject_Del(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self)
|
static int
|
||||||
|
locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self)
|
||||||
{
|
{
|
||||||
|
int result;
|
||||||
ENTER_HASHLIB(self);
|
ENTER_HASHLIB(self);
|
||||||
EVP_MD_CTX_copy(new_ctx_p, &self->ctx);
|
result = EVP_MD_CTX_copy(new_ctx_p, self->ctx);
|
||||||
LEAVE_HASHLIB(self);
|
LEAVE_HASHLIB(self);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* External methods for a hash object */
|
/* External methods for a hash object */
|
||||||
|
@ -126,7 +176,9 @@ EVP_copy(EVPobject *self, PyObject *unused)
|
||||||
if ( (newobj = newEVPobject(self->name))==NULL)
|
if ( (newobj = newEVPobject(self->name))==NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
locked_EVP_MD_CTX_copy(&newobj->ctx, self);
|
if (!locked_EVP_MD_CTX_copy(newobj->ctx, self)) {
|
||||||
|
return _setException(PyExc_ValueError);
|
||||||
|
}
|
||||||
return (PyObject *)newobj;
|
return (PyObject *)newobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,16 +189,24 @@ static PyObject *
|
||||||
EVP_digest(EVPobject *self, PyObject *unused)
|
EVP_digest(EVPobject *self, PyObject *unused)
|
||||||
{
|
{
|
||||||
unsigned char digest[EVP_MAX_MD_SIZE];
|
unsigned char digest[EVP_MAX_MD_SIZE];
|
||||||
EVP_MD_CTX temp_ctx;
|
EVP_MD_CTX *temp_ctx;
|
||||||
PyObject *retval;
|
PyObject *retval;
|
||||||
unsigned int digest_size;
|
unsigned int digest_size;
|
||||||
|
|
||||||
locked_EVP_MD_CTX_copy(&temp_ctx, self);
|
temp_ctx = EVP_MD_CTX_new();
|
||||||
digest_size = EVP_MD_CTX_size(&temp_ctx);
|
if (temp_ctx == NULL) {
|
||||||
EVP_DigestFinal(&temp_ctx, digest, NULL);
|
PyErr_NoMemory();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
|
||||||
|
return _setException(PyExc_ValueError);
|
||||||
|
}
|
||||||
|
digest_size = EVP_MD_CTX_size(temp_ctx);
|
||||||
|
EVP_DigestFinal(temp_ctx, digest, NULL);
|
||||||
|
|
||||||
retval = PyBytes_FromStringAndSize((const char *)digest, digest_size);
|
retval = PyBytes_FromStringAndSize((const char *)digest, digest_size);
|
||||||
EVP_MD_CTX_cleanup(&temp_ctx);
|
EVP_MD_CTX_free(temp_ctx);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,15 +217,23 @@ static PyObject *
|
||||||
EVP_hexdigest(EVPobject *self, PyObject *unused)
|
EVP_hexdigest(EVPobject *self, PyObject *unused)
|
||||||
{
|
{
|
||||||
unsigned char digest[EVP_MAX_MD_SIZE];
|
unsigned char digest[EVP_MAX_MD_SIZE];
|
||||||
EVP_MD_CTX temp_ctx;
|
EVP_MD_CTX *temp_ctx;
|
||||||
unsigned int digest_size;
|
unsigned int digest_size;
|
||||||
|
|
||||||
/* Get the raw (binary) digest value */
|
temp_ctx = EVP_MD_CTX_new();
|
||||||
locked_EVP_MD_CTX_copy(&temp_ctx, self);
|
if (temp_ctx == NULL) {
|
||||||
digest_size = EVP_MD_CTX_size(&temp_ctx);
|
PyErr_NoMemory();
|
||||||
EVP_DigestFinal(&temp_ctx, digest, NULL);
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
EVP_MD_CTX_cleanup(&temp_ctx);
|
/* Get the raw (binary) digest value */
|
||||||
|
if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
|
||||||
|
return _setException(PyExc_ValueError);
|
||||||
|
}
|
||||||
|
digest_size = EVP_MD_CTX_size(temp_ctx);
|
||||||
|
EVP_DigestFinal(temp_ctx, digest, NULL);
|
||||||
|
|
||||||
|
EVP_MD_CTX_free(temp_ctx);
|
||||||
|
|
||||||
return _Py_strhex((const char *)digest, digest_size);
|
return _Py_strhex((const char *)digest, digest_size);
|
||||||
}
|
}
|
||||||
|
@ -219,7 +287,7 @@ static PyObject *
|
||||||
EVP_get_block_size(EVPobject *self, void *closure)
|
EVP_get_block_size(EVPobject *self, void *closure)
|
||||||
{
|
{
|
||||||
long block_size;
|
long block_size;
|
||||||
block_size = EVP_MD_CTX_block_size(&self->ctx);
|
block_size = EVP_MD_CTX_block_size(self->ctx);
|
||||||
return PyLong_FromLong(block_size);
|
return PyLong_FromLong(block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +295,7 @@ static PyObject *
|
||||||
EVP_get_digest_size(EVPobject *self, void *closure)
|
EVP_get_digest_size(EVPobject *self, void *closure)
|
||||||
{
|
{
|
||||||
long size;
|
long size;
|
||||||
size = EVP_MD_CTX_size(&self->ctx);
|
size = EVP_MD_CTX_size(self->ctx);
|
||||||
return PyLong_FromLong(size);
|
return PyLong_FromLong(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +356,7 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
|
||||||
PyBuffer_Release(&view);
|
PyBuffer_Release(&view);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
EVP_DigestInit(&self->ctx, digest);
|
EVP_DigestInit(self->ctx, digest);
|
||||||
|
|
||||||
self->name = name_obj;
|
self->name = name_obj;
|
||||||
Py_INCREF(self->name);
|
Py_INCREF(self->name);
|
||||||
|
@ -385,9 +453,9 @@ EVPnew(PyObject *name_obj,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (initial_ctx) {
|
if (initial_ctx) {
|
||||||
EVP_MD_CTX_copy(&self->ctx, initial_ctx);
|
EVP_MD_CTX_copy(self->ctx, initial_ctx);
|
||||||
} else {
|
} else {
|
||||||
EVP_DigestInit(&self->ctx, digest);
|
EVP_DigestInit(self->ctx, digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cp && len) {
|
if (cp && len) {
|
||||||
|
@ -453,6 +521,7 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
|
||||||
|
|
||||||
#define PY_PBKDF2_HMAC 1
|
#define PY_PBKDF2_HMAC 1
|
||||||
|
|
||||||
|
#if !HAS_FAST_PKCS5_PBKDF2_HMAC
|
||||||
/* Improved implementation of PKCS5_PBKDF2_HMAC()
|
/* Improved implementation of PKCS5_PBKDF2_HMAC()
|
||||||
*
|
*
|
||||||
* PKCS5_PBKDF2_HMAC_fast() hashes the password exactly one time instead of
|
* PKCS5_PBKDF2_HMAC_fast() hashes the password exactly one time instead of
|
||||||
|
@ -534,37 +603,8 @@ PKCS5_PBKDF2_HMAC_fast(const char *pass, int passlen,
|
||||||
HMAC_CTX_cleanup(&hctx_tpl);
|
HMAC_CTX_cleanup(&hctx_tpl);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* LCOV_EXCL_START */
|
|
||||||
static PyObject *
|
|
||||||
_setException(PyObject *exc)
|
|
||||||
{
|
|
||||||
unsigned long errcode;
|
|
||||||
const char *lib, *func, *reason;
|
|
||||||
|
|
||||||
errcode = ERR_peek_last_error();
|
|
||||||
if (!errcode) {
|
|
||||||
PyErr_SetString(exc, "unknown reasons");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
ERR_clear_error();
|
|
||||||
|
|
||||||
lib = ERR_lib_error_string(errcode);
|
|
||||||
func = ERR_func_error_string(errcode);
|
|
||||||
reason = ERR_reason_error_string(errcode);
|
|
||||||
|
|
||||||
if (lib && func) {
|
|
||||||
PyErr_Format(exc, "[%s: %s] %s", lib, func, reason);
|
|
||||||
}
|
|
||||||
else if (lib) {
|
|
||||||
PyErr_Format(exc, "[%s] %s", lib, reason);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PyErr_SetString(exc, reason);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/* LCOV_EXCL_STOP */
|
|
||||||
|
|
||||||
PyDoc_STRVAR(pbkdf2_hmac__doc__,
|
PyDoc_STRVAR(pbkdf2_hmac__doc__,
|
||||||
"pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None) -> key\n\
|
"pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None) -> key\n\
|
||||||
|
@ -646,10 +686,17 @@ pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict)
|
||||||
key = PyBytes_AS_STRING(key_obj);
|
key = PyBytes_AS_STRING(key_obj);
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
#if HAS_FAST_PKCS5_PBKDF2_HMAC
|
||||||
|
retval = PKCS5_PBKDF2_HMAC((char*)password.buf, (int)password.len,
|
||||||
|
(unsigned char *)salt.buf, (int)salt.len,
|
||||||
|
iterations, digest, dklen,
|
||||||
|
(unsigned char *)key);
|
||||||
|
#else
|
||||||
retval = PKCS5_PBKDF2_HMAC_fast((char*)password.buf, (int)password.len,
|
retval = PKCS5_PBKDF2_HMAC_fast((char*)password.buf, (int)password.len,
|
||||||
(unsigned char *)salt.buf, (int)salt.len,
|
(unsigned char *)salt.buf, (int)salt.len,
|
||||||
iterations, digest, dklen,
|
iterations, digest, dklen,
|
||||||
(unsigned char *)key);
|
(unsigned char *)key);
|
||||||
|
#endif
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
if (!retval) {
|
if (!retval) {
|
||||||
|
@ -768,7 +815,7 @@ generate_hash_name_list(void)
|
||||||
if (CONST_ ## NAME ## _name_obj == NULL) { \
|
if (CONST_ ## NAME ## _name_obj == NULL) { \
|
||||||
CONST_ ## NAME ## _name_obj = PyUnicode_FromString(#NAME); \
|
CONST_ ## NAME ## _name_obj = PyUnicode_FromString(#NAME); \
|
||||||
if (EVP_get_digestbyname(#NAME)) { \
|
if (EVP_get_digestbyname(#NAME)) { \
|
||||||
CONST_new_ ## NAME ## _ctx_p = &CONST_new_ ## NAME ## _ctx; \
|
CONST_new_ ## NAME ## _ctx_p = EVP_MD_CTX_new(); \
|
||||||
EVP_DigestInit(CONST_new_ ## NAME ## _ctx_p, EVP_get_digestbyname(#NAME)); \
|
EVP_DigestInit(CONST_new_ ## NAME ## _ctx_p, EVP_get_digestbyname(#NAME)); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
|
181
Modules/_ssl.c
181
Modules/_ssl.c
|
@ -55,6 +55,14 @@ static PySocketModule_APIObject PySocketModule;
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Don't warn about deprecated functions */
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
#endif
|
||||||
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Include OpenSSL header files */
|
/* Include OpenSSL header files */
|
||||||
#include "openssl/rsa.h"
|
#include "openssl/rsa.h"
|
||||||
#include "openssl/crypto.h"
|
#include "openssl/crypto.h"
|
||||||
|
@ -91,6 +99,10 @@ struct py_ssl_library_code {
|
||||||
/* Include generated data (error codes) */
|
/* Include generated data (error codes) */
|
||||||
#include "_ssl_data.h"
|
#include "_ssl_data.h"
|
||||||
|
|
||||||
|
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
|
||||||
|
# define OPENSSL_VERSION_1_1 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Openssl comes with TLSv1.1 and TLSv1.2 between 1.0.0h and 1.0.1
|
/* Openssl comes with TLSv1.1 and TLSv1.2 between 1.0.0h and 1.0.1
|
||||||
http://www.openssl.org/news/changelog.html
|
http://www.openssl.org/news/changelog.html
|
||||||
*/
|
*/
|
||||||
|
@ -117,6 +129,72 @@ struct py_ssl_library_code {
|
||||||
#define INVALID_SOCKET (-1)
|
#define INVALID_SOCKET (-1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPENSSL_VERSION_1_1
|
||||||
|
/* OpenSSL 1.1.0+ */
|
||||||
|
#ifndef OPENSSL_NO_SSL2
|
||||||
|
#define OPENSSL_NO_SSL2
|
||||||
|
#endif
|
||||||
|
#else /* OpenSSL < 1.1.0 */
|
||||||
|
#if defined(WITH_THREAD)
|
||||||
|
#define HAVE_OPENSSL_CRYPTO_LOCK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TLS_method SSLv23_method
|
||||||
|
|
||||||
|
static int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne)
|
||||||
|
{
|
||||||
|
return ne->set;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef OPENSSL_NO_COMP
|
||||||
|
static int COMP_get_type(const COMP_METHOD *meth)
|
||||||
|
{
|
||||||
|
return meth->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *COMP_get_name(const COMP_METHOD *meth)
|
||||||
|
{
|
||||||
|
return meth->name;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx)
|
||||||
|
{
|
||||||
|
return ctx->default_passwd_callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx)
|
||||||
|
{
|
||||||
|
return ctx->default_passwd_callback_userdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int X509_OBJECT_get_type(X509_OBJECT *x)
|
||||||
|
{
|
||||||
|
return x->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static X509 *X509_OBJECT_get0_X509(X509_OBJECT *x)
|
||||||
|
{
|
||||||
|
return x->data.x509;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int BIO_up_ref(BIO *b)
|
||||||
|
{
|
||||||
|
CRYPTO_add(&b->references, 1, CRYPTO_LOCK_BIO);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *store) {
|
||||||
|
return store->objs;
|
||||||
|
}
|
||||||
|
|
||||||
|
static X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *store)
|
||||||
|
{
|
||||||
|
return store->param;
|
||||||
|
}
|
||||||
|
#endif /* OpenSSL < 1.1.0 or LibreSSL */
|
||||||
|
|
||||||
|
|
||||||
enum py_ssl_error {
|
enum py_ssl_error {
|
||||||
/* these mirror ssl.h */
|
/* these mirror ssl.h */
|
||||||
PY_SSL_ERROR_NONE,
|
PY_SSL_ERROR_NONE,
|
||||||
|
@ -147,7 +225,7 @@ enum py_ssl_cert_requirements {
|
||||||
enum py_ssl_version {
|
enum py_ssl_version {
|
||||||
PY_SSL_VERSION_SSL2,
|
PY_SSL_VERSION_SSL2,
|
||||||
PY_SSL_VERSION_SSL3=1,
|
PY_SSL_VERSION_SSL3=1,
|
||||||
PY_SSL_VERSION_SSL23,
|
PY_SSL_VERSION_TLS,
|
||||||
#if HAVE_TLSv1_2
|
#if HAVE_TLSv1_2
|
||||||
PY_SSL_VERSION_TLS1,
|
PY_SSL_VERSION_TLS1,
|
||||||
PY_SSL_VERSION_TLS1_1,
|
PY_SSL_VERSION_TLS1_1,
|
||||||
|
@ -527,8 +605,8 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
|
||||||
/* BIOs are reference counted and SSL_set_bio borrows our reference.
|
/* BIOs are reference counted and SSL_set_bio borrows our reference.
|
||||||
* To prevent a double free in memory_bio_dealloc() we need to take an
|
* To prevent a double free in memory_bio_dealloc() we need to take an
|
||||||
* extra reference here. */
|
* extra reference here. */
|
||||||
CRYPTO_add(&inbio->bio->references, 1, CRYPTO_LOCK_BIO);
|
BIO_up_ref(inbio->bio);
|
||||||
CRYPTO_add(&outbio->bio->references, 1, CRYPTO_LOCK_BIO);
|
BIO_up_ref(outbio->bio);
|
||||||
SSL_set_bio(self->ssl, inbio->bio, outbio->bio);
|
SSL_set_bio(self->ssl, inbio->bio, outbio->bio);
|
||||||
}
|
}
|
||||||
mode = SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER;
|
mode = SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER;
|
||||||
|
@ -738,7 +816,7 @@ _create_tuple_for_X509_NAME (X509_NAME *xname)
|
||||||
|
|
||||||
/* check to see if we've gotten to a new RDN */
|
/* check to see if we've gotten to a new RDN */
|
||||||
if (rdn_level >= 0) {
|
if (rdn_level >= 0) {
|
||||||
if (rdn_level != entry->set) {
|
if (rdn_level != X509_NAME_ENTRY_set(entry)) {
|
||||||
/* yes, new RDN */
|
/* yes, new RDN */
|
||||||
/* add old RDN to DN */
|
/* add old RDN to DN */
|
||||||
rdnt = PyList_AsTuple(rdn);
|
rdnt = PyList_AsTuple(rdn);
|
||||||
|
@ -755,7 +833,7 @@ _create_tuple_for_X509_NAME (X509_NAME *xname)
|
||||||
goto fail0;
|
goto fail0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rdn_level = entry->set;
|
rdn_level = X509_NAME_ENTRY_set(entry);
|
||||||
|
|
||||||
/* now add this attribute to the current RDN */
|
/* now add this attribute to the current RDN */
|
||||||
name = X509_NAME_ENTRY_get_object(entry);
|
name = X509_NAME_ENTRY_get_object(entry);
|
||||||
|
@ -853,18 +931,18 @@ _get_peer_alt_names (X509 *certificate) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = ext->value->data;
|
p = X509_EXTENSION_get_data(ext)->data;
|
||||||
if (method->it)
|
if (method->it)
|
||||||
names = (GENERAL_NAMES*)
|
names = (GENERAL_NAMES*)
|
||||||
(ASN1_item_d2i(NULL,
|
(ASN1_item_d2i(NULL,
|
||||||
&p,
|
&p,
|
||||||
ext->value->length,
|
X509_EXTENSION_get_data(ext)->length,
|
||||||
ASN1_ITEM_ptr(method->it)));
|
ASN1_ITEM_ptr(method->it)));
|
||||||
else
|
else
|
||||||
names = (GENERAL_NAMES*)
|
names = (GENERAL_NAMES*)
|
||||||
(method->d2i(NULL,
|
(method->d2i(NULL,
|
||||||
&p,
|
&p,
|
||||||
ext->value->length));
|
X509_EXTENSION_get_data(ext)->length));
|
||||||
|
|
||||||
for(j = 0; j < sk_GENERAL_NAME_num(names); j++) {
|
for(j = 0; j < sk_GENERAL_NAME_num(names); j++) {
|
||||||
/* get a rendering of each name in the set of names */
|
/* get a rendering of each name in the set of names */
|
||||||
|
@ -1075,13 +1153,11 @@ _get_crl_dp(X509 *certificate) {
|
||||||
int i, j;
|
int i, j;
|
||||||
PyObject *lst, *res = NULL;
|
PyObject *lst, *res = NULL;
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10001000L
|
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
|
||||||
dps = X509_get_ext_d2i(certificate, NID_crl_distribution_points, NULL, NULL);
|
|
||||||
#else
|
|
||||||
/* Calls x509v3_cache_extensions and sets up crldp */
|
/* Calls x509v3_cache_extensions and sets up crldp */
|
||||||
X509_check_ca(certificate);
|
X509_check_ca(certificate);
|
||||||
dps = certificate->crldp;
|
|
||||||
#endif
|
#endif
|
||||||
|
dps = X509_get_ext_d2i(certificate, NID_crl_distribution_points, NULL, NULL);
|
||||||
|
|
||||||
if (dps == NULL)
|
if (dps == NULL)
|
||||||
return Py_None;
|
return Py_None;
|
||||||
|
@ -1451,14 +1527,13 @@ static PyObject *
|
||||||
_ssl__SSLSocket_shared_ciphers_impl(PySSLSocket *self)
|
_ssl__SSLSocket_shared_ciphers_impl(PySSLSocket *self)
|
||||||
/*[clinic end generated code: output=3d174ead2e42c4fd input=0bfe149da8fe6306]*/
|
/*[clinic end generated code: output=3d174ead2e42c4fd input=0bfe149da8fe6306]*/
|
||||||
{
|
{
|
||||||
SSL_SESSION *sess = SSL_get_session(self->ssl);
|
|
||||||
STACK_OF(SSL_CIPHER) *ciphers;
|
STACK_OF(SSL_CIPHER) *ciphers;
|
||||||
int i;
|
int i;
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
|
|
||||||
if (!sess || !sess->ciphers)
|
ciphers = SSL_get_ciphers(self->ssl);
|
||||||
|
if (!ciphers)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
ciphers = sess->ciphers;
|
|
||||||
res = PyList_New(sk_SSL_CIPHER_num(ciphers));
|
res = PyList_New(sk_SSL_CIPHER_num(ciphers));
|
||||||
if (!res)
|
if (!res)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1567,9 +1642,9 @@ _ssl__SSLSocket_compression_impl(PySSLSocket *self)
|
||||||
if (self->ssl == NULL)
|
if (self->ssl == NULL)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
comp_method = SSL_get_current_compression(self->ssl);
|
comp_method = SSL_get_current_compression(self->ssl);
|
||||||
if (comp_method == NULL || comp_method->type == NID_undef)
|
if (comp_method == NULL || COMP_get_type(comp_method) == NID_undef)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
short_name = OBJ_nid2sn(comp_method->type);
|
short_name = COMP_get_name(comp_method);
|
||||||
if (short_name == NULL)
|
if (short_name == NULL)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
return PyUnicode_DecodeFSDefault(short_name);
|
return PyUnicode_DecodeFSDefault(short_name);
|
||||||
|
@ -2255,8 +2330,8 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
|
||||||
else if (proto_version == PY_SSL_VERSION_SSL2)
|
else if (proto_version == PY_SSL_VERSION_SSL2)
|
||||||
ctx = SSL_CTX_new(SSLv2_method());
|
ctx = SSL_CTX_new(SSLv2_method());
|
||||||
#endif
|
#endif
|
||||||
else if (proto_version == PY_SSL_VERSION_SSL23)
|
else if (proto_version == PY_SSL_VERSION_TLS)
|
||||||
ctx = SSL_CTX_new(SSLv23_method());
|
ctx = SSL_CTX_new(TLS_method());
|
||||||
else
|
else
|
||||||
proto_version = -1;
|
proto_version = -1;
|
||||||
PySSL_END_ALLOW_THREADS
|
PySSL_END_ALLOW_THREADS
|
||||||
|
@ -2318,8 +2393,9 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
|
||||||
#ifndef OPENSSL_NO_ECDH
|
#ifndef OPENSSL_NO_ECDH
|
||||||
/* Allow automatic ECDH curve selection (on OpenSSL 1.0.2+), or use
|
/* Allow automatic ECDH curve selection (on OpenSSL 1.0.2+), or use
|
||||||
prime256v1 by default. This is Apache mod_ssl's initialization
|
prime256v1 by default. This is Apache mod_ssl's initialization
|
||||||
policy, so we should be safe. */
|
policy, so we should be safe. OpenSSL 1.1 has it enabled by default.
|
||||||
#if defined(SSL_CTX_set_ecdh_auto)
|
*/
|
||||||
|
#if defined(SSL_CTX_set_ecdh_auto) && !defined(OPENSSL_VERSION_1_1)
|
||||||
SSL_CTX_set_ecdh_auto(self->ctx, 1);
|
SSL_CTX_set_ecdh_auto(self->ctx, 1);
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
|
@ -2586,10 +2662,12 @@ static PyObject *
|
||||||
get_verify_flags(PySSLContext *self, void *c)
|
get_verify_flags(PySSLContext *self, void *c)
|
||||||
{
|
{
|
||||||
X509_STORE *store;
|
X509_STORE *store;
|
||||||
|
X509_VERIFY_PARAM *param;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
store = SSL_CTX_get_cert_store(self->ctx);
|
store = SSL_CTX_get_cert_store(self->ctx);
|
||||||
flags = X509_VERIFY_PARAM_get_flags(store->param);
|
param = X509_STORE_get0_param(store);
|
||||||
|
flags = X509_VERIFY_PARAM_get_flags(param);
|
||||||
return PyLong_FromUnsignedLong(flags);
|
return PyLong_FromUnsignedLong(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2597,22 +2675,24 @@ static int
|
||||||
set_verify_flags(PySSLContext *self, PyObject *arg, void *c)
|
set_verify_flags(PySSLContext *self, PyObject *arg, void *c)
|
||||||
{
|
{
|
||||||
X509_STORE *store;
|
X509_STORE *store;
|
||||||
|
X509_VERIFY_PARAM *param;
|
||||||
unsigned long new_flags, flags, set, clear;
|
unsigned long new_flags, flags, set, clear;
|
||||||
|
|
||||||
if (!PyArg_Parse(arg, "k", &new_flags))
|
if (!PyArg_Parse(arg, "k", &new_flags))
|
||||||
return -1;
|
return -1;
|
||||||
store = SSL_CTX_get_cert_store(self->ctx);
|
store = SSL_CTX_get_cert_store(self->ctx);
|
||||||
flags = X509_VERIFY_PARAM_get_flags(store->param);
|
param = X509_STORE_get0_param(store);
|
||||||
|
flags = X509_VERIFY_PARAM_get_flags(param);
|
||||||
clear = flags & ~new_flags;
|
clear = flags & ~new_flags;
|
||||||
set = ~flags & new_flags;
|
set = ~flags & new_flags;
|
||||||
if (clear) {
|
if (clear) {
|
||||||
if (!X509_VERIFY_PARAM_clear_flags(store->param, clear)) {
|
if (!X509_VERIFY_PARAM_clear_flags(param, clear)) {
|
||||||
_setSSLError(NULL, 0, __FILE__, __LINE__);
|
_setSSLError(NULL, 0, __FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (set) {
|
if (set) {
|
||||||
if (!X509_VERIFY_PARAM_set_flags(store->param, set)) {
|
if (!X509_VERIFY_PARAM_set_flags(param, set)) {
|
||||||
_setSSLError(NULL, 0, __FILE__, __LINE__);
|
_setSSLError(NULL, 0, __FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -2789,8 +2869,8 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile,
|
||||||
/*[clinic end generated code: output=9480bc1c380e2095 input=7cf9ac673cbee6fc]*/
|
/*[clinic end generated code: output=9480bc1c380e2095 input=7cf9ac673cbee6fc]*/
|
||||||
{
|
{
|
||||||
PyObject *certfile_bytes = NULL, *keyfile_bytes = NULL;
|
PyObject *certfile_bytes = NULL, *keyfile_bytes = NULL;
|
||||||
pem_password_cb *orig_passwd_cb = self->ctx->default_passwd_callback;
|
pem_password_cb *orig_passwd_cb = SSL_CTX_get_default_passwd_cb(self->ctx);
|
||||||
void *orig_passwd_userdata = self->ctx->default_passwd_callback_userdata;
|
void *orig_passwd_userdata = SSL_CTX_get_default_passwd_cb_userdata(self->ctx);
|
||||||
_PySSLPasswordInfo pw_info = { NULL, NULL, NULL, 0, 0 };
|
_PySSLPasswordInfo pw_info = { NULL, NULL, NULL, 0, 0 };
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -2917,8 +2997,9 @@ _add_ca_certs(PySSLContext *self, void *data, Py_ssize_t len,
|
||||||
cert = d2i_X509_bio(biobuf, NULL);
|
cert = d2i_X509_bio(biobuf, NULL);
|
||||||
} else {
|
} else {
|
||||||
cert = PEM_read_bio_X509(biobuf, NULL,
|
cert = PEM_read_bio_X509(biobuf, NULL,
|
||||||
self->ctx->default_passwd_callback,
|
SSL_CTX_get_default_passwd_cb(self->ctx),
|
||||||
self->ctx->default_passwd_callback_userdata);
|
SSL_CTX_get_default_passwd_cb_userdata(self->ctx)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (cert == NULL) {
|
if (cert == NULL) {
|
||||||
break;
|
break;
|
||||||
|
@ -3444,25 +3525,24 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self)
|
||||||
/*[clinic end generated code: output=5f356f4d9cca874d input=eb40dd0f6d0e40cf]*/
|
/*[clinic end generated code: output=5f356f4d9cca874d input=eb40dd0f6d0e40cf]*/
|
||||||
{
|
{
|
||||||
X509_STORE *store;
|
X509_STORE *store;
|
||||||
|
STACK_OF(X509_OBJECT) *objs;
|
||||||
X509_OBJECT *obj;
|
X509_OBJECT *obj;
|
||||||
int x509 = 0, crl = 0, pkey = 0, ca = 0, i;
|
int x509 = 0, crl = 0, ca = 0, i;
|
||||||
|
|
||||||
store = SSL_CTX_get_cert_store(self->ctx);
|
store = SSL_CTX_get_cert_store(self->ctx);
|
||||||
for (i = 0; i < sk_X509_OBJECT_num(store->objs); i++) {
|
objs = X509_STORE_get0_objects(store);
|
||||||
obj = sk_X509_OBJECT_value(store->objs, i);
|
for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
|
||||||
switch (obj->type) {
|
obj = sk_X509_OBJECT_value(objs, i);
|
||||||
|
switch (X509_OBJECT_get_type(obj)) {
|
||||||
case X509_LU_X509:
|
case X509_LU_X509:
|
||||||
x509++;
|
x509++;
|
||||||
if (X509_check_ca(obj->data.x509)) {
|
if (X509_check_ca(X509_OBJECT_get0_X509(obj))) {
|
||||||
ca++;
|
ca++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case X509_LU_CRL:
|
case X509_LU_CRL:
|
||||||
crl++;
|
crl++;
|
||||||
break;
|
break;
|
||||||
case X509_LU_PKEY:
|
|
||||||
pkey++;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
/* Ignore X509_LU_FAIL, X509_LU_RETRY, X509_LU_PKEY.
|
/* Ignore X509_LU_FAIL, X509_LU_RETRY, X509_LU_PKEY.
|
||||||
* As far as I can tell they are internal states and never
|
* As far as I can tell they are internal states and never
|
||||||
|
@ -3492,6 +3572,7 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form)
|
||||||
/*[clinic end generated code: output=0d58f148f37e2938 input=6887b5a09b7f9076]*/
|
/*[clinic end generated code: output=0d58f148f37e2938 input=6887b5a09b7f9076]*/
|
||||||
{
|
{
|
||||||
X509_STORE *store;
|
X509_STORE *store;
|
||||||
|
STACK_OF(X509_OBJECT) *objs;
|
||||||
PyObject *ci = NULL, *rlist = NULL;
|
PyObject *ci = NULL, *rlist = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -3500,17 +3581,18 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form)
|
||||||
}
|
}
|
||||||
|
|
||||||
store = SSL_CTX_get_cert_store(self->ctx);
|
store = SSL_CTX_get_cert_store(self->ctx);
|
||||||
for (i = 0; i < sk_X509_OBJECT_num(store->objs); i++) {
|
objs = X509_STORE_get0_objects(store);
|
||||||
|
for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
|
||||||
X509_OBJECT *obj;
|
X509_OBJECT *obj;
|
||||||
X509 *cert;
|
X509 *cert;
|
||||||
|
|
||||||
obj = sk_X509_OBJECT_value(store->objs, i);
|
obj = sk_X509_OBJECT_value(objs, i);
|
||||||
if (obj->type != X509_LU_X509) {
|
if (X509_OBJECT_get_type(obj) != X509_LU_X509) {
|
||||||
/* not a x509 cert */
|
/* not a x509 cert */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* CA for any purpose */
|
/* CA for any purpose */
|
||||||
cert = obj->data.x509;
|
cert = X509_OBJECT_get0_X509(obj);
|
||||||
if (!X509_check_ca(cert)) {
|
if (!X509_check_ca(cert)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -4374,10 +4456,12 @@ static PyMethodDef PySSL_methods[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
#ifdef HAVE_OPENSSL_CRYPTO_LOCK
|
||||||
|
|
||||||
/* an implementation of OpenSSL threading operations in terms
|
/* an implementation of OpenSSL threading operations in terms
|
||||||
of the Python C thread library */
|
* of the Python C thread library
|
||||||
|
* Only used up to 1.0.2. OpenSSL 1.1.0+ has its own locking code.
|
||||||
|
*/
|
||||||
|
|
||||||
static PyThread_type_lock *_ssl_locks = NULL;
|
static PyThread_type_lock *_ssl_locks = NULL;
|
||||||
|
|
||||||
|
@ -4458,7 +4542,7 @@ static int _setup_ssl_threads(void) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* def HAVE_THREAD */
|
#endif /* HAVE_OPENSSL_CRYPTO_LOCK for WITH_THREAD && OpenSSL < 1.1.0 */
|
||||||
|
|
||||||
PyDoc_STRVAR(module_doc,
|
PyDoc_STRVAR(module_doc,
|
||||||
"Implementation module for SSL socket operations. See the socket module\n\
|
"Implementation module for SSL socket operations. See the socket module\n\
|
||||||
|
@ -4527,11 +4611,16 @@ PyInit__ssl(void)
|
||||||
SSL_load_error_strings();
|
SSL_load_error_strings();
|
||||||
SSL_library_init();
|
SSL_library_init();
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
|
#ifdef HAVE_OPENSSL_CRYPTO_LOCK
|
||||||
/* note that this will start threading if not already started */
|
/* note that this will start threading if not already started */
|
||||||
if (!_setup_ssl_threads()) {
|
if (!_setup_ssl_threads()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#elif OPENSSL_VERSION_1_1 && defined(OPENSSL_THREADS)
|
||||||
|
/* OpenSSL 1.1.0 builtin thread support is enabled */
|
||||||
|
_ssl_locks_count++;
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* WITH_THREAD */
|
||||||
OpenSSL_add_all_algorithms();
|
OpenSSL_add_all_algorithms();
|
||||||
|
|
||||||
/* Add symbols to module dict */
|
/* Add symbols to module dict */
|
||||||
|
@ -4678,7 +4767,9 @@ PyInit__ssl(void)
|
||||||
PY_SSL_VERSION_SSL3);
|
PY_SSL_VERSION_SSL3);
|
||||||
#endif
|
#endif
|
||||||
PyModule_AddIntConstant(m, "PROTOCOL_SSLv23",
|
PyModule_AddIntConstant(m, "PROTOCOL_SSLv23",
|
||||||
PY_SSL_VERSION_SSL23);
|
PY_SSL_VERSION_TLS);
|
||||||
|
PyModule_AddIntConstant(m, "PROTOCOL_TLS",
|
||||||
|
PY_SSL_VERSION_TLS);
|
||||||
PyModule_AddIntConstant(m, "PROTOCOL_TLSv1",
|
PyModule_AddIntConstant(m, "PROTOCOL_TLSv1",
|
||||||
PY_SSL_VERSION_TLS1);
|
PY_SSL_VERSION_TLS1);
|
||||||
#if HAVE_TLSv1_2
|
#if HAVE_TLSv1_2
|
||||||
|
|
Loading…
Reference in New Issue