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