PEP-644: Require OpenSSL 1.1 or newer (#1692)
Signed-off-by: Christian Heimes <christian@python.org>
This commit is contained in:
parent
c9a0f76dd4
commit
08abdc8d14
|
@ -0,0 +1,349 @@
|
||||||
|
PEP: 644
|
||||||
|
Title: Require OpenSSL 1.1 or newer
|
||||||
|
Author: Christian Heimes <christian@python.org>
|
||||||
|
BDFL-Delegate: n/a
|
||||||
|
Discussions-To: https://discuss.python.org/t/pep-644-require-openssl-1-1-or-newer/5584
|
||||||
|
Status: Draft
|
||||||
|
Type: Standards Track
|
||||||
|
Content-Type: text/x-rst
|
||||||
|
Created: 27-Oct-2020
|
||||||
|
Python-Version: 3.10
|
||||||
|
Post-History: 27-Oct-2020
|
||||||
|
|
||||||
|
|
||||||
|
Abstract
|
||||||
|
========
|
||||||
|
|
||||||
|
This PEP proposes for CPython’s standard library to support only OpenSSL
|
||||||
|
1.1.1 LTS or newer. Support for OpenSSL versions past end-of-lifetime,
|
||||||
|
incompatible forks, and other TLS libraries are dropped.
|
||||||
|
|
||||||
|
|
||||||
|
Motivation
|
||||||
|
==========
|
||||||
|
|
||||||
|
Python makes use of OpenSSL in `hashlib`, `hmac`, and `ssl` modules. OpenSSL
|
||||||
|
provides fast implementations of cryptographic primitives and a full TLS
|
||||||
|
stack including handling of X.509 certificates. The `ssl` module is used by
|
||||||
|
standard library modules like `urllib` and 3rd party modules like `urllib3`
|
||||||
|
to implement secure variants of internet protocols. `pip` uses the `ssl`
|
||||||
|
module to securely download packages from PyPI. Any bug in the ssl module's
|
||||||
|
bindings to OpenSSL can lead to a severe security issue.
|
||||||
|
|
||||||
|
Over time OpenSSL's public API has evolved and changed. Version 1.0.2
|
||||||
|
introduced new APIs to verify and match hostnames. OpenSSL 1.1.0 made
|
||||||
|
internal structs opaque and introduced new APIs that replace direct access of
|
||||||
|
struct members. Version 3.0.0 will deprecate more APIs due to internal
|
||||||
|
reorganization that moves cryptographic algorithms out of the core and into
|
||||||
|
providers. Forks like LibreSSL and BoringSSL have diverged in different
|
||||||
|
directions.
|
||||||
|
|
||||||
|
Currently Python versions 3.6 to 3.9 are compatible with OpenSSL 1.0.2,
|
||||||
|
1.1.0, and 1.1.1. For the most part Python also works with LibreSSL >= 2.7.1
|
||||||
|
with some missing features and broken tests.
|
||||||
|
|
||||||
|
Due to limited resources and time it becomes increasingly hard to support
|
||||||
|
multiple versions and forks as well as test and verify correctness. Besides
|
||||||
|
multiple incompatible APIs there are build time flags,
|
||||||
|
distribution-specific patches, and local crypto-policy settings that add to
|
||||||
|
plethora of combinations. On the other hand, the Python core team has only
|
||||||
|
a couple of domain experts who are familiar with TLS and OpenSSL internals
|
||||||
|
and even fewer who are active maintainers.
|
||||||
|
|
||||||
|
Requiring OpenSSL 1.1.1 would allow us to give the vast majority of users a
|
||||||
|
better experience, reduce our maintenance overhead and thus free resources
|
||||||
|
to implement new features. Users would be able to rely on the presence of
|
||||||
|
new features and consistent behavior, ultimately resulting in a more robust
|
||||||
|
experience.
|
||||||
|
|
||||||
|
|
||||||
|
Impact
|
||||||
|
======
|
||||||
|
|
||||||
|
OpenSSL 1.1.1 is the default variant and version of OpenSSL on almost all
|
||||||
|
supported platforms and distributions. It’s also the only version that still
|
||||||
|
receives security support from upstream [9]_.
|
||||||
|
|
||||||
|
No macOS and Windows user will be affected by the deprecation. The python.org
|
||||||
|
installer and alternative distributions like Conda ship with most recent
|
||||||
|
OpenSSL version.
|
||||||
|
|
||||||
|
As of October 2020 and according to DistroWatch [1]_ most current BSD and
|
||||||
|
Linux distributions ship with OpenSSL 1.1.1 as well. Some older releases of
|
||||||
|
long term support (LTS) and enterprise distributions have older versions of
|
||||||
|
OpenSSL or LibreSSL. By the time Python 3.10 will be generally available,
|
||||||
|
several of these distributions will have reached end of lifetime, end of
|
||||||
|
general support, or moved from LibreSSL to OpenSSL.
|
||||||
|
|
||||||
|
Other software has dropped support for OpenSSL 1.0.2 as well. For example
|
||||||
|
PyCA cryptography 3.2 (2020-10-25) removed compatibility with OpenSSL 1.0.2.
|
||||||
|
|
||||||
|
|
||||||
|
OpenSSL 1.0.2 LTS
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
released: 2015-02
|
||||||
|
end of lifetime: 2019-12
|
||||||
|
|
||||||
|
OpenSSL 1.0.2 added hostname verification, ALPN support, and elliptic curves.
|
||||||
|
|
||||||
|
- CentOS 7 (EOL 2024-06)
|
||||||
|
- Debian 8 Jessie (EOL 2020-07)
|
||||||
|
- Linux Mint 18.3 (EOL 2021-04)
|
||||||
|
- RHEL 7 (full support ends 2019-08, maintenance 2 support ends 2024-06)
|
||||||
|
- SUSE Enterprise Linux 12-SP5 (general supports ends 2024-10)
|
||||||
|
- Ubuntu 16.04 LTS / Xenial (general support ends 2021-04)
|
||||||
|
|
||||||
|
|
||||||
|
OpenSSL 1.1.0
|
||||||
|
-------------
|
||||||
|
|
||||||
|
released: 2016-08
|
||||||
|
end of lifetime: 2019-09
|
||||||
|
|
||||||
|
OpenSSL 1.1.0 removed or disabled insecure ciphers by default and added
|
||||||
|
support for ChaCha20-Poly1305, BLAKE2 (basic features), X25519 and CT. The
|
||||||
|
majority of structs were made opaque and new APIs were introduced. OpenSSL
|
||||||
|
1.1.0 is not API compatible with 1.0.2.
|
||||||
|
|
||||||
|
- Debian 9 Stretch (estimated EOL 2022-06)
|
||||||
|
- Ubuntu 18.04 LTS / Bionic (general support ends 2023-04)
|
||||||
|
|
||||||
|
|
||||||
|
OpenSSL 1.1.1 LTS
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
released: 2018-08
|
||||||
|
end of lifetime: 2023-09 (planned)
|
||||||
|
|
||||||
|
OpenSSL 1.1.1 added TLS 1.3, SHA-3, X448 and Ed448.
|
||||||
|
|
||||||
|
- Alpine (switched back to OpenSSL in 2018 [4]_)
|
||||||
|
- Arch Linux current
|
||||||
|
- CentOS 8.0+
|
||||||
|
- Debian 10 Buster
|
||||||
|
- Fedora 29+
|
||||||
|
- FreeBSD 11.3+
|
||||||
|
- Gentoo Linux stable
|
||||||
|
- HardenedBSD (switched back to OpenSSL in 2018 [3]_)
|
||||||
|
- Linux Mint 19.3+
|
||||||
|
- macOS (python.org installer)
|
||||||
|
- NetBSD 8.2+
|
||||||
|
- openSUSE 15.2+
|
||||||
|
- RHEL 8.0+
|
||||||
|
- Slackware current
|
||||||
|
- SUSE Enterprise Linux 15-SP2
|
||||||
|
- Ubuntu 18.10+
|
||||||
|
- Ubuntu 20.04 LTS / Focal
|
||||||
|
- Windows (python.org installer, Conda)
|
||||||
|
|
||||||
|
|
||||||
|
OpenSSL 3.0.0
|
||||||
|
-------------
|
||||||
|
|
||||||
|
released: n/a (planned for early 2021)
|
||||||
|
|
||||||
|
OpenSSL 3.0.0 is currently under development. Major changes include
|
||||||
|
relicensing to Apache License 2.0 and a new API for cryptographic algorithms
|
||||||
|
providers. Most changes are internal refactorings and don’t affect public
|
||||||
|
APIs. [8]_
|
||||||
|
|
||||||
|
|
||||||
|
LibreSSL
|
||||||
|
--------
|
||||||
|
|
||||||
|
created: 2014-04 (forked from OpenSSL 1.0.1g)
|
||||||
|
|
||||||
|
- DragonFly BSD
|
||||||
|
- Hyperbola GNU/Linux-libre
|
||||||
|
- OpenBSD
|
||||||
|
- OpenELEC (discontinued)
|
||||||
|
- TrueOS (discontinued)
|
||||||
|
- VOID Linux (currently moving back to OpenSSL [5]_)
|
||||||
|
|
||||||
|
Some distributions like FreeBSD, Gentoo, and OPNsense also feature LibreSSL
|
||||||
|
instead of OpenSSL as non-standard TLS libraries.
|
||||||
|
|
||||||
|
OpenBSD ports has a port `security/openssl/1.1` which is documented as
|
||||||
|
"[...] is present to provide support for applications which cannot be made
|
||||||
|
compatible with LibReSSL" [7]_. The package could be used by OpenBSD to
|
||||||
|
provide a working ssl module.
|
||||||
|
|
||||||
|
|
||||||
|
BoringSSL
|
||||||
|
---------
|
||||||
|
|
||||||
|
created: 2014-06
|
||||||
|
|
||||||
|
BoringSSL is Google’s fork of OpenSSL. It’s not intended for general use and
|
||||||
|
therefore not supported by Python. There are no guarantees of API or ABI
|
||||||
|
stability. Vendored copies of BoringSSL are used in Chrome/Chromium browser,
|
||||||
|
Android, and on Apple platforms [6]_.
|
||||||
|
|
||||||
|
|
||||||
|
Benefits
|
||||||
|
========
|
||||||
|
|
||||||
|
TLS 1.3
|
||||||
|
-------
|
||||||
|
|
||||||
|
OpenSSL 1.1.1 introduced support for the new TLS 1.3 version. The latest
|
||||||
|
version of the TLS protocol has a faster handshake and is more secure than
|
||||||
|
the previous versions.
|
||||||
|
|
||||||
|
Thread and fork safety
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Starting with release 1.1.0c, OpenSSL is fully fork and thread safe.
|
||||||
|
Bindings no longer need any workarounds or additional callbacks to support
|
||||||
|
multithreading.
|
||||||
|
|
||||||
|
SHA-3
|
||||||
|
-----
|
||||||
|
|
||||||
|
Since 1.1.0, OpenSSL ships with SHA-3 and SHAKE implementations.
|
||||||
|
Python's builtin SHA-3 support is based on the reference implementation. The
|
||||||
|
internal `_sha3` code is fairly large and the resulting shared library close
|
||||||
|
to 0.5 MB. Python could drop the builtin implementation and rely on OpenSSL's
|
||||||
|
`libcrypto` instead.
|
||||||
|
|
||||||
|
So far LibreSSL upstream development has refused to add SHA-3 support. [2]_
|
||||||
|
|
||||||
|
|
||||||
|
Compatibility
|
||||||
|
=============
|
||||||
|
|
||||||
|
OpenSSL downstream patches and options
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
OpenSSL features more than 70 configure and build time options in the form
|
||||||
|
of `OPENSSL_NO_*` macros. Around 60 options affect the presence of features
|
||||||
|
like cryptographic algorithms and TLS versions. Some distributions apply
|
||||||
|
patches to alter settings. Furthermore default values for settings like
|
||||||
|
security level, ciphers, TLS version range, and signature algorithms can
|
||||||
|
be set in OpenSSL config file.
|
||||||
|
|
||||||
|
The Python core team lacks resources to test all possible combinations.
|
||||||
|
This PEP proposes that Python only supports OpenSSL builds that have
|
||||||
|
standard features enabled. Vendors shall disable deprecated or insecure
|
||||||
|
algorithms and TLS versions with build time options like
|
||||||
|
`OPENSSL_NO_TLS1_1_METHOD` or OpenSSL config options like
|
||||||
|
`MinProtocol = TLSv1.2`.
|
||||||
|
|
||||||
|
Python assumes that OpenSSL is built with
|
||||||
|
|
||||||
|
- hashlib’s default algorithms such as MD5, SHA-1, SHA-2 family,
|
||||||
|
SHA-3/SHAKE family, BLAKE2
|
||||||
|
- TLS 1.2 and TLS 1.3 protocols
|
||||||
|
- current key agreement, signature, and encryption algorithms for TLS 1.2
|
||||||
|
and 1.3 (ECDH, RSA, ECDSA, Curve25519, AES, Poly1309-ChaCha20, ...)
|
||||||
|
- threading, file I/O, socket I/O, and error messages
|
||||||
|
|
||||||
|
Weak algorithms (MD5, SHA-1 signatures) and short keys (RSA < 2024 bits) may
|
||||||
|
be disabled at runtime. Algorithms may also be blocked when they are
|
||||||
|
disabled by a crypto policy such as FIPS. The PEP is not more specific on
|
||||||
|
purpose to give room for new features as well as countermeasures against
|
||||||
|
vulnerabilities. As a rule of thumb, Python should be able to connect to
|
||||||
|
PyPI and the test suite should pass.
|
||||||
|
|
||||||
|
LibreSSL support
|
||||||
|
----------------
|
||||||
|
|
||||||
|
LibreSSL is a fork of OpenSSL. The fork was created off OpenSSL 1.0.1g by
|
||||||
|
members of the OpenBSD team in 2014 in light of the heartbleed vulnerability.
|
||||||
|
Since its inception several features deemed problematic or insecure were
|
||||||
|
removed or replaced (SSL 2.0, SSL 3.0, improved CPRNG) or backported
|
||||||
|
from OpenSSL and BoringSSL.
|
||||||
|
|
||||||
|
At the moment LibreSSL is not fully API compatible with OpenSSL 1.1.1. The
|
||||||
|
latest release LibreSSL 3.3.2 is missing features and behaves differently
|
||||||
|
in some cases. Mentionable missing or incompatible features include
|
||||||
|
|
||||||
|
- SHA-3, SHAKE, BLAKE2
|
||||||
|
- `SSL_CERT_*` environment variables
|
||||||
|
- security level APIs
|
||||||
|
- session handling APIs
|
||||||
|
- key logging API
|
||||||
|
- verified cert chain APIs
|
||||||
|
- OPENSSL_VERSION macro
|
||||||
|
|
||||||
|
This PEP proposed to remove any and all LibreSSL related workarounds from
|
||||||
|
Python. In the future Python will not actively prohibit LibreSSL support
|
||||||
|
with configure and compile time checks. But Python will not accept patches
|
||||||
|
that add non-trivial workarounds or disable tests either.
|
||||||
|
|
||||||
|
|
||||||
|
BoringSSL
|
||||||
|
---------
|
||||||
|
|
||||||
|
There are currently no plans to support BoringSSL.
|
||||||
|
|
||||||
|
|
||||||
|
Rejected Ideas
|
||||||
|
==============
|
||||||
|
|
||||||
|
Formalize supported OpenSSL versions
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
This PEP does not provide a set of formal rules and conditions under which
|
||||||
|
an OpenSSL version is supported.
|
||||||
|
|
||||||
|
In general Python aims to be compatible with commonly used and officially
|
||||||
|
supported OpenSSL versions. Patch releases of Python may not be compatible
|
||||||
|
with new major releases of OpenSSL. Users should not expect that a new major
|
||||||
|
or minor release of Python works with an OpenSSL version that is past its
|
||||||
|
end-of-lifetime. Python core development may backport fixes for new releases
|
||||||
|
or extend compatibility with EOLed releases as we see fit.
|
||||||
|
|
||||||
|
The new ABI stability and LTS policies of OpenSSL [9]_ should help, too.
|
||||||
|
|
||||||
|
|
||||||
|
Backwards Compatibility
|
||||||
|
=======================
|
||||||
|
|
||||||
|
Python 3.10 will no longer support TLS/SSL and fast hashing on platforms
|
||||||
|
with OpenSSL 1.0.2 or LibreSSL. This PEP is published at the beginning of
|
||||||
|
the 3.10 release cycles. It gives vendors like Linux distributors or CI
|
||||||
|
providers roughly 11 months to react.
|
||||||
|
|
||||||
|
|
||||||
|
Disclaimer and special thanks
|
||||||
|
=============================
|
||||||
|
|
||||||
|
The author of this PEP is a contributor to OpenSSL project and employed by
|
||||||
|
a major Linux distributor that uses OpenSSL.
|
||||||
|
|
||||||
|
Thanks to Alex Gaynor, Gregory P. Smith, Nathaniel J. Smith, Paul Kehrer,
|
||||||
|
and Seth Larson for their review and feedback on the initial draft.
|
||||||
|
|
||||||
|
|
||||||
|
References
|
||||||
|
==========
|
||||||
|
|
||||||
|
.. [1] https://distrowatch.com/
|
||||||
|
.. [2] https://github.com/libressl-portable/portable/issues/455
|
||||||
|
.. [3] https://hardenedbsd.org/article/shawn-webb/2018-04-30/hardenedbsd-switching-back-openssl
|
||||||
|
.. [4] https://lists.alpinelinux.org/~alpine/devel/%3CCA%2BT2pCGFeh30aEi43hAvJ3yoHBijABy_U62wfjhVmf3FmbNUUg%40mail.gmail.com%3E
|
||||||
|
.. [5] https://github.com/void-linux/void-packages/issues/20935
|
||||||
|
.. [6] https://forums.swift.org/t/rfc-moving-swiftnio-ssl-to-boringssl/18280
|
||||||
|
.. [7] https://openports.se/security/openssl/1.1
|
||||||
|
.. [8] https://www.openssl.org/docs/OpenSSL300Design.html
|
||||||
|
.. [9] https://www.openssl.org/policies/releasestrat.html
|
||||||
|
|
||||||
|
|
||||||
|
Copyright
|
||||||
|
=========
|
||||||
|
|
||||||
|
This document is placed in the public domain or under the
|
||||||
|
CC0-1.0-Universal license, whichever is more permissive.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
..
|
||||||
|
Local Variables:
|
||||||
|
mode: indented-text
|
||||||
|
indent-tabs-mode: nil
|
||||||
|
sentence-end-double-space: t
|
||||||
|
fill-column: 70
|
||||||
|
coding: utf-8
|
||||||
|
End:
|
Loading…
Reference in New Issue