mirror of
https://github.com/saymrwulf/cryptography.git
synced 2026-05-14 20:37:55 +00:00
drop support for openssl < 1.1.1d (#8449)
This removes the OS random engine, which contained the only CPython PSF licensed code in the repository. Accordingly, that license has now been removed.
This commit is contained in:
parent
4c24dd05eb
commit
5e6476a4c6
20 changed files with 20 additions and 1194 deletions
16
.github/workflows/ci.yml
vendored
16
.github/workflows/ci.yml
vendored
|
|
@ -136,7 +136,6 @@ jobs:
|
|||
- {IMAGE: "bullseye", TOXENV: "py39", RUNNER: "ubuntu-latest"}
|
||||
- {IMAGE: "bookworm", TOXENV: "py311", RUNNER: "ubuntu-latest"}
|
||||
- {IMAGE: "sid", TOXENV: "py311", RUNNER: "ubuntu-latest"}
|
||||
- {IMAGE: "ubuntu-bionic", TOXENV: "py36", RUNNER: "ubuntu-latest"}
|
||||
- {IMAGE: "ubuntu-focal", TOXENV: "py38", RUNNER: "ubuntu-latest"}
|
||||
- {IMAGE: "ubuntu-jammy", TOXENV: "py310", RUNNER: "ubuntu-latest"}
|
||||
- {IMAGE: "ubuntu-rolling", TOXENV: "py310", RUNNER: "ubuntu-latest"}
|
||||
|
|
@ -182,7 +181,6 @@ jobs:
|
|||
run: mkdir -p "${HOME}/.cache/pip"
|
||||
- run: |
|
||||
echo "OPENSSL_FORCE_FIPS_MODE=1" >> $GITHUB_ENV
|
||||
echo "CFLAGS=-DUSE_OSRANDOM_RNG_FOR_TESTING" >> $GITHUB_ENV
|
||||
if: matrix.IMAGE.FIPS
|
||||
- run: /venv/bin/python -m pip install -c ci-constraints-requirements.txt 'tox>3' coverage
|
||||
- run: '/venv/bin/tox -vvv --notest'
|
||||
|
|
@ -373,11 +371,11 @@ jobs:
|
|||
- {OS: 'macos-12', ARCH: 'x86_64'}
|
||||
- {OS: [self-hosted, macos, ARM64, tart], ARCH: 'arm64'}
|
||||
PYTHON:
|
||||
- {VERSION: "3.6", TOXENV: "py36-nocoverage", EXTRA_CFLAGS: ""}
|
||||
- {VERSION: "3.11", TOXENV: "py311", EXTRA_CFLAGS: "-DUSE_OSRANDOM_RNG_FOR_TESTING"}
|
||||
- {VERSION: "3.6", TOXENV: "py36-nocoverage"}
|
||||
- {VERSION: "3.11", TOXENV: "py311"}
|
||||
exclude:
|
||||
# We only test latest Python on arm64. The py36 won't work since there's no universal2 binary
|
||||
- PYTHON: {VERSION: "3.6", TOXENV: "py36-nocoverage", EXTRA_CFLAGS: ""}
|
||||
- PYTHON: {VERSION: "3.6", TOXENV: "py36-nocoverage"}
|
||||
RUNNER: {OS: [self-hosted, macos, ARM64, tart], ARCH: 'arm64'}
|
||||
name: "${{ matrix.PYTHON.TOXENV }} on macOS ${{ matrix.RUNNER.ARCH }}"
|
||||
timeout-minutes: 15
|
||||
|
|
@ -420,11 +418,10 @@ jobs:
|
|||
run: |
|
||||
OPENSSL_DIR=$(readlink -f ../openssl-macos-universal2/) \
|
||||
OPENSSL_STATIC=1 \
|
||||
CFLAGS="-Werror -Wno-error=deprecated-declarations -Wno-error=incompatible-pointer-types-discards-qualifiers -Wno-error=unused-function -mmacosx-version-min=10.12 $EXTRA_CFLAGS" \
|
||||
CFLAGS="-Werror -Wno-error=deprecated-declarations -Wno-error=incompatible-pointer-types-discards-qualifiers -Wno-error=unused-function -mmacosx-version-min=10.12" \
|
||||
tox -vvv --notest
|
||||
env:
|
||||
TOXENV: ${{ matrix.PYTHON.TOXENV }}
|
||||
EXTRA_CFLAGS: ${{ matrix.PYTHON.EXTRA_CFLAGS }}
|
||||
CARGO_TARGET_DIR: ${{ format('{0}/src/rust/target/', github.workspace) }}
|
||||
- name: Tests
|
||||
run: tox --skip-pkg-install -- --color=yes --wycheproof-root=wycheproof
|
||||
|
|
@ -443,8 +440,8 @@ jobs:
|
|||
- {ARCH: 'x86', WINDOWS: 'win32'}
|
||||
- {ARCH: 'x64', WINDOWS: 'win64'}
|
||||
PYTHON:
|
||||
- {VERSION: "3.6", TOXENV: "py36-nocoverage", CL_FLAGS: ""}
|
||||
- {VERSION: "3.11", TOXENV: "py311", CL_FLAGS: "/D USE_OSRANDOM_RNG_FOR_TESTING"}
|
||||
- {VERSION: "3.6", TOXENV: "py36-nocoverage"}
|
||||
- {VERSION: "3.11", TOXENV: "py311"}
|
||||
JOB_NUMBER: [0, 1]
|
||||
name: "${{ matrix.PYTHON.TOXENV }} on ${{ matrix.WINDOWS.WINDOWS }} (part ${{ matrix.JOB_NUMBER }})"
|
||||
timeout-minutes: 15
|
||||
|
|
@ -481,7 +478,6 @@ jobs:
|
|||
- name: Configure
|
||||
run: |
|
||||
echo "OPENSSL_DIR=C:/openssl-${{ matrix.WINDOWS.WINDOWS }}" >> $GITHUB_ENV
|
||||
echo "CL=${{ matrix.PYTHON.CL_FLAGS }}" >> $GITHUB_ENV
|
||||
shell: bash
|
||||
|
||||
- name: Clone wycheproof
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@ Changelog
|
|||
|
||||
.. note:: This version is not yet released and is under active development.
|
||||
|
||||
* **BACKWARDS INCOMPATIBLE:** Support for OpenSSL less than 1.1.1d has been
|
||||
removed. Users on older version of OpenSSL will need to upgrade.
|
||||
|
||||
.. _v40-0-0:
|
||||
|
||||
40.0.0 - 2023-03-24
|
||||
|
|
|
|||
3
LICENSE
3
LICENSE
|
|
@ -1,6 +1,3 @@
|
|||
This software is made available under the terms of *either* of the licenses
|
||||
found in LICENSE.APACHE or LICENSE.BSD. Contributions to cryptography are made
|
||||
under the terms of *both* these licenses.
|
||||
|
||||
The code used in the OS random engine is derived from CPython, and is licensed
|
||||
under the terms of the PSF License Agreement.
|
||||
|
|
|
|||
41
LICENSE.PSF
41
LICENSE.PSF
|
|
@ -1,41 +0,0 @@
|
|||
1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and
|
||||
the Individual or Organization ("Licensee") accessing and otherwise using Python
|
||||
2.7.12 software in source or binary form and its associated documentation.
|
||||
|
||||
2. Subject to the terms and conditions of this License Agreement, PSF hereby
|
||||
grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
|
||||
analyze, test, perform and/or display publicly, prepare derivative works,
|
||||
distribute, and otherwise use Python 2.7.12 alone or in any derivative
|
||||
version, provided, however, that PSF's License Agreement and PSF's notice of
|
||||
copyright, i.e., "Copyright © 2001-2016 Python Software Foundation; All Rights
|
||||
Reserved" are retained in Python 2.7.12 alone or in any derivative version
|
||||
prepared by Licensee.
|
||||
|
||||
3. In the event Licensee prepares a derivative work that is based on or
|
||||
incorporates Python 2.7.12 or any part thereof, and wants to make the
|
||||
derivative work available to others as provided herein, then Licensee hereby
|
||||
agrees to include in any such work a brief summary of the changes made to Python
|
||||
2.7.12.
|
||||
|
||||
4. PSF is making Python 2.7.12 available to Licensee on an "AS IS" basis.
|
||||
PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF
|
||||
EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR
|
||||
WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE
|
||||
USE OF PYTHON 2.7.12 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
|
||||
|
||||
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 2.7.12
|
||||
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF
|
||||
MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.7.12, OR ANY DERIVATIVE
|
||||
THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||
|
||||
6. This License Agreement will automatically terminate upon a material breach of
|
||||
its terms and conditions.
|
||||
|
||||
7. Nothing in this License Agreement shall be deemed to create any relationship
|
||||
of agency, partnership, or joint venture between PSF and Licensee. This License
|
||||
Agreement does not grant permission to use PSF trademarks or trade name in a
|
||||
trademark sense to endorse or promote products or services of Licensee, or any
|
||||
third party.
|
||||
|
||||
8. By copying, installing or otherwise using Python 2.7.12, Licensee agrees
|
||||
to be bound by the terms and conditions of this License Agreement.
|
||||
|
|
@ -3,7 +3,6 @@ include CONTRIBUTING.rst
|
|||
include LICENSE
|
||||
include LICENSE.APACHE
|
||||
include LICENSE.BSD
|
||||
include LICENSE.PSF
|
||||
include README.rst
|
||||
include tox.ini
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ A list of supported versions can be found in our :doc:`/installation`
|
|||
documentation.
|
||||
|
||||
In general the backend should be considered an internal implementation detail
|
||||
of the project, but there are some public methods available for more advanced
|
||||
control.
|
||||
of the project, but there are some public methods available for debugging
|
||||
purposes.
|
||||
|
||||
.. data:: cryptography.hazmat.backends.openssl.backend
|
||||
|
||||
|
|
@ -29,21 +29,6 @@ control.
|
|||
typically shown in hexadecimal (e.g. ``0x1010003f``). This is
|
||||
not necessarily the same version as it was compiled against.
|
||||
|
||||
.. method:: activate_osrandom_engine()
|
||||
|
||||
Activates the OS random engine. This will effectively disable OpenSSL's
|
||||
default CSPRNG.
|
||||
|
||||
.. method:: osrandom_engine_implementation()
|
||||
|
||||
.. versionadded:: 1.7
|
||||
|
||||
Returns the implementation of OS random engine.
|
||||
|
||||
.. method:: activate_builtin_random()
|
||||
|
||||
This will activate the default OpenSSL CSPRNG.
|
||||
|
||||
.. _legacy-provider:
|
||||
|
||||
Legacy provider in OpenSSL 3.x
|
||||
|
|
@ -56,68 +41,5 @@ disable the legacy provider in OpenSSL 3.x. This will disable legacy
|
|||
cryptographic algorithms, including ``Blowfish``, ``CAST5``, ``SEED``,
|
||||
``ARC4``, and ``RC2`` (which is used by some encrypted serialization formats).
|
||||
|
||||
OS random engine
|
||||
----------------
|
||||
|
||||
.. note::
|
||||
|
||||
As of OpenSSL 1.1.1d its CSPRNG is fork-safe by default.
|
||||
``cryptography`` does not compile or load the custom engine on
|
||||
>= 1.1.1d.
|
||||
|
||||
By default OpenSSL uses a user-space CSPRNG that is seeded from system random (
|
||||
``/dev/urandom`` or ``CryptGenRandom``). This CSPRNG is not reseeded
|
||||
automatically when a process calls ``fork()``. This can result in situations
|
||||
where two different processes can return similar or identical keys and
|
||||
compromise the security of the system.
|
||||
|
||||
The approach this project has chosen to mitigate this vulnerability is to
|
||||
include an engine that replaces the OpenSSL default CSPRNG with one that
|
||||
sources its entropy from ``/dev/urandom`` on UNIX-like operating systems and
|
||||
uses ``CryptGenRandom`` on Windows. This method of pulling from the system pool
|
||||
allows us to avoid potential issues with `initializing the RNG`_ as well as
|
||||
protecting us from the ``fork()`` weakness.
|
||||
|
||||
This engine is **active** by default when importing the OpenSSL backend. When
|
||||
active this engine will be used to generate all the random data OpenSSL
|
||||
requests.
|
||||
|
||||
When importing only the binding it is added to the engine list but
|
||||
**not activated**.
|
||||
|
||||
|
||||
OS random sources
|
||||
-----------------
|
||||
|
||||
On macOS and FreeBSD ``/dev/urandom`` is an alias for ``/dev/random``. The
|
||||
implementation on macOS uses the `Yarrow`_ algorithm. FreeBSD uses the
|
||||
`Fortuna`_ algorithm.
|
||||
|
||||
On Windows the implementation of ``CryptGenRandom`` depends on which version of
|
||||
the operation system you are using. See the `Microsoft documentation`_ for more
|
||||
details.
|
||||
|
||||
Linux uses its own PRNG design. ``/dev/urandom`` is a non-blocking source
|
||||
seeded from the same pool as ``/dev/random``.
|
||||
|
||||
+------------------------------------------+------------------------------+
|
||||
| Windows | ``CryptGenRandom()`` |
|
||||
+------------------------------------------+------------------------------+
|
||||
| Linux >= 3.17 with working | ``getrandom()`` |
|
||||
| ``SYS_getrandom`` syscall | |
|
||||
+------------------------------------------+------------------------------+
|
||||
| OpenBSD >= 5.6 | ``getentropy()`` |
|
||||
+------------------------------------------+------------------------------+
|
||||
| BSD family (including macOS 10.12+) with | ``getentropy()`` |
|
||||
| ``SYS_getentropy`` in ``sys/syscall.h`` | |
|
||||
+------------------------------------------+------------------------------+
|
||||
| fallback | ``/dev/urandom`` with |
|
||||
| | cached file descriptor |
|
||||
+------------------------------------------+------------------------------+
|
||||
|
||||
|
||||
.. _`OpenSSL`: https://www.openssl.org/
|
||||
.. _`initializing the RNG`: https://en.wikipedia.org/wiki/OpenSSL#Predictable_private_keys_.28Debian-specific.29
|
||||
.. _`Fortuna`: https://en.wikipedia.org/wiki/Fortuna_(PRNG)
|
||||
.. _`Yarrow`: https://en.wikipedia.org/wiki/Yarrow_algorithm
|
||||
.. _`Microsoft documentation`: https://docs.microsoft.com/en-us/windows/desktop/api/wincrypt/nf-wincrypt-cryptgenrandom
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ version = attr: cryptography.__version__
|
|||
description = cryptography is a package which provides cryptographic recipes and primitives to Python developers.
|
||||
long_description = file: README.rst
|
||||
long_description_content_type = text/x-rst
|
||||
license = (Apache-2.0 OR BSD-3-Clause) AND PSF-2.0
|
||||
license = Apache-2.0 OR BSD-3-Clause
|
||||
url = https://github.com/pyca/cryptography
|
||||
author = The Python Cryptographic Authority and individual contributors
|
||||
author_email = cryptography-dev@python.org
|
||||
|
|
|
|||
|
|
@ -100,7 +100,6 @@ ffi = build_ffi_for_binding(
|
|||
"nid",
|
||||
"objects",
|
||||
"opensslv",
|
||||
"osrandom_engine",
|
||||
"pem",
|
||||
"pkcs12",
|
||||
"rand",
|
||||
|
|
|
|||
|
|
@ -52,40 +52,25 @@ INCLUDES = """
|
|||
#define CRYPTOGRAPHY_LIBRESSL_LESS_THAN_370 (0)
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10101000
|
||||
#error "pyca/cryptography MUST be linked with Openssl 1.1.1 or later"
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10101040
|
||||
#error "pyca/cryptography MUST be linked with Openssl 1.1.1d or later"
|
||||
#endif
|
||||
|
||||
#define CRYPTOGRAPHY_OPENSSL_111D_OR_GREATER \
|
||||
(OPENSSL_VERSION_NUMBER >= 0x10101040 && !CRYPTOGRAPHY_IS_LIBRESSL)
|
||||
#define CRYPTOGRAPHY_OPENSSL_300_OR_GREATER \
|
||||
(OPENSSL_VERSION_NUMBER >= 0x30000000 && !CRYPTOGRAPHY_IS_LIBRESSL)
|
||||
|
||||
#define CRYPTOGRAPHY_OPENSSL_LESS_THAN_111B \
|
||||
(OPENSSL_VERSION_NUMBER < 0x10101020 || CRYPTOGRAPHY_IS_LIBRESSL)
|
||||
#define CRYPTOGRAPHY_OPENSSL_LESS_THAN_111D \
|
||||
(OPENSSL_VERSION_NUMBER < 0x10101040 || CRYPTOGRAPHY_IS_LIBRESSL)
|
||||
#define CRYPTOGRAPHY_OPENSSL_LESS_THAN_111E \
|
||||
(OPENSSL_VERSION_NUMBER < 0x10101050 || CRYPTOGRAPHY_IS_LIBRESSL)
|
||||
#if (CRYPTOGRAPHY_OPENSSL_LESS_THAN_111D && !CRYPTOGRAPHY_IS_LIBRESSL && \
|
||||
!defined(OPENSSL_NO_ENGINE)) || defined(USE_OSRANDOM_RNG_FOR_TESTING)
|
||||
#define CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE 1
|
||||
#else
|
||||
#define CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE 0
|
||||
#endif
|
||||
/* Ed25519 support is available from OpenSSL 1.1.1b and LibreSSL 3.7.0. */
|
||||
/* Ed25519 support is in all supported OpenSSLs as well as LibreSSL 3.7.0. */
|
||||
#define CRYPTOGRAPHY_HAS_WORKING_ED25519 \
|
||||
(!CRYPTOGRAPHY_OPENSSL_LESS_THAN_111B || \
|
||||
(!CRYPTOGRAPHY_IS_LIBRESSL || \
|
||||
(CRYPTOGRAPHY_IS_LIBRESSL && !CRYPTOGRAPHY_LIBRESSL_LESS_THAN_370))
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
static const int CRYPTOGRAPHY_OPENSSL_111D_OR_GREATER;
|
||||
static const int CRYPTOGRAPHY_OPENSSL_300_OR_GREATER;
|
||||
|
||||
static const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_111B;
|
||||
static const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_111E;
|
||||
static const int CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE;
|
||||
static const int CRYPTOGRAPHY_HAS_WORKING_ED25519;
|
||||
|
||||
static const int CRYPTOGRAPHY_LIBRESSL_LESS_THAN_370;
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ CUSTOMIZATIONS = """
|
|||
#define ERR_LIB_PROV 0
|
||||
#endif
|
||||
|
||||
#if !CRYPTOGRAPHY_OPENSSL_111D_OR_GREATER || CRYPTOGRAPHY_IS_BORINGSSL
|
||||
#ifndef EVP_R_XTS_DUPLICATED_KEYS
|
||||
static const int EVP_R_XTS_DUPLICATED_KEYS = 0;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
|
||||
import os
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
with open(os.path.join(HERE, "src/osrandom_engine.h")) as f:
|
||||
INCLUDES = f.read()
|
||||
|
||||
TYPES = """
|
||||
static const char *const Cryptography_osrandom_engine_name;
|
||||
static const char *const Cryptography_osrandom_engine_id;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
int Cryptography_add_osrandom_engine(void);
|
||||
"""
|
||||
|
||||
with open(os.path.join(HERE, "src/osrandom_engine.c")) as f:
|
||||
CUSTOMIZATIONS = f.read()
|
||||
|
|
@ -1,627 +0,0 @@
|
|||
/* osurandom engine
|
||||
*
|
||||
* Windows CryptGenRandom()
|
||||
* macOS >= 10.12 getentropy()
|
||||
* OpenBSD 5.6+ getentropy()
|
||||
* other BSD getentropy() if SYS_getentropy is defined
|
||||
* Linux 3.17+ getrandom() with fallback to /dev/urandom
|
||||
* other /dev/urandom with cached fd
|
||||
*
|
||||
* The /dev/urandom, getrandom and getentropy code is derived from Python's
|
||||
* Python/random.c, written by Antoine Pitrou and Victor Stinner.
|
||||
*
|
||||
* Copyright 2001-2016 Python Software Foundation; All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifdef __linux__
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#if CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE
|
||||
/* OpenSSL has ENGINE support and is older than 1.1.1d (the first version that
|
||||
* properly implements fork safety in its RNG) so build the engine. */
|
||||
static const char *Cryptography_osrandom_engine_id = "osrandom";
|
||||
|
||||
/****************************************************************************
|
||||
* Windows
|
||||
*/
|
||||
#if CRYPTOGRAPHY_OSRANDOM_ENGINE == CRYPTOGRAPHY_OSRANDOM_ENGINE_CRYPTGENRANDOM
|
||||
static const char *Cryptography_osrandom_engine_name = "osrandom_engine CryptGenRandom()";
|
||||
static HCRYPTPROV hCryptProv = 0;
|
||||
|
||||
static int osrandom_init(ENGINE *e) {
|
||||
if (hCryptProv != 0) {
|
||||
return 1;
|
||||
}
|
||||
if (CryptAcquireContext(&hCryptProv, NULL, NULL,
|
||||
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
|
||||
return 1;
|
||||
} else {
|
||||
ERR_Cryptography_OSRandom_error(
|
||||
CRYPTOGRAPHY_OSRANDOM_F_INIT,
|
||||
CRYPTOGRAPHY_OSRANDOM_R_CRYPTACQUIRECONTEXT,
|
||||
__FILE__, __LINE__
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int osrandom_rand_bytes(unsigned char *buffer, int size) {
|
||||
if (hCryptProv == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!CryptGenRandom(hCryptProv, (DWORD)size, buffer)) {
|
||||
ERR_Cryptography_OSRandom_error(
|
||||
CRYPTOGRAPHY_OSRANDOM_F_RAND_BYTES,
|
||||
CRYPTOGRAPHY_OSRANDOM_R_CRYPTGENRANDOM,
|
||||
__FILE__, __LINE__
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int osrandom_finish(ENGINE *e) {
|
||||
if (CryptReleaseContext(hCryptProv, 0)) {
|
||||
hCryptProv = 0;
|
||||
return 1;
|
||||
} else {
|
||||
ERR_Cryptography_OSRandom_error(
|
||||
CRYPTOGRAPHY_OSRANDOM_F_FINISH,
|
||||
CRYPTOGRAPHY_OSRANDOM_R_CRYPTRELEASECONTEXT,
|
||||
__FILE__, __LINE__
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int osrandom_rand_status(void) {
|
||||
return hCryptProv != 0;
|
||||
}
|
||||
|
||||
static const char *osurandom_get_implementation(void) {
|
||||
return "CryptGenRandom";
|
||||
}
|
||||
|
||||
#endif /* CRYPTOGRAPHY_OSRANDOM_ENGINE_CRYPTGENRANDOM */
|
||||
|
||||
/****************************************************************************
|
||||
* /dev/urandom helpers for all non-BSD Unix platforms
|
||||
*/
|
||||
#ifdef CRYPTOGRAPHY_OSRANDOM_NEEDS_DEV_URANDOM
|
||||
|
||||
static struct {
|
||||
int fd;
|
||||
dev_t st_dev;
|
||||
ino_t st_ino;
|
||||
} urandom_cache = { -1 };
|
||||
|
||||
static int open_cloexec(const char *path) {
|
||||
int open_flags = O_RDONLY;
|
||||
#ifdef O_CLOEXEC
|
||||
open_flags |= O_CLOEXEC;
|
||||
#endif
|
||||
|
||||
int fd = open(path, open_flags);
|
||||
if (fd == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifndef O_CLOEXEC
|
||||
int flags = fcntl(fd, F_GETFD);
|
||||
if (flags == -1) {
|
||||
return -1;
|
||||
}
|
||||
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return fd;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
/* On Linux, we open("/dev/random") and use poll() to wait until it's readable
|
||||
* before we read from /dev/urandom, this ensures that we don't read from
|
||||
* /dev/urandom before the kernel CSPRNG is initialized. This isn't necessary on
|
||||
* other platforms because they don't have the same _bug_ as Linux does with
|
||||
* /dev/urandom and early boot. */
|
||||
static int wait_on_devrandom(void) {
|
||||
struct pollfd pfd = {};
|
||||
int ret = 0;
|
||||
int random_fd = open_cloexec("/dev/random");
|
||||
if (random_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
pfd.fd = random_fd;
|
||||
pfd.events = POLLIN;
|
||||
pfd.revents = 0;
|
||||
do {
|
||||
ret = poll(&pfd, 1, -1);
|
||||
} while (ret < 0 && (errno == EINTR || errno == EAGAIN));
|
||||
close(random_fd);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* return -1 on error */
|
||||
static int dev_urandom_fd(void) {
|
||||
int fd = -1;
|
||||
struct stat st;
|
||||
|
||||
/* Check that fd still points to the correct device */
|
||||
if (urandom_cache.fd >= 0) {
|
||||
if (fstat(urandom_cache.fd, &st)
|
||||
|| st.st_dev != urandom_cache.st_dev
|
||||
|| st.st_ino != urandom_cache.st_ino) {
|
||||
/* Somebody replaced our FD. Invalidate our cache but don't
|
||||
* close the fd. */
|
||||
urandom_cache.fd = -1;
|
||||
}
|
||||
}
|
||||
if (urandom_cache.fd < 0) {
|
||||
#ifdef __linux__
|
||||
if (wait_on_devrandom() < 0) {
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
|
||||
fd = open_cloexec("/dev/urandom");
|
||||
if (fd < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (fstat(fd, &st)) {
|
||||
goto error;
|
||||
}
|
||||
/* Another thread initialized the fd */
|
||||
if (urandom_cache.fd >= 0) {
|
||||
close(fd);
|
||||
return urandom_cache.fd;
|
||||
}
|
||||
urandom_cache.st_dev = st.st_dev;
|
||||
urandom_cache.st_ino = st.st_ino;
|
||||
urandom_cache.fd = fd;
|
||||
}
|
||||
return urandom_cache.fd;
|
||||
|
||||
error:
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
}
|
||||
ERR_Cryptography_OSRandom_error(
|
||||
CRYPTOGRAPHY_OSRANDOM_F_DEV_URANDOM_FD,
|
||||
CRYPTOGRAPHY_OSRANDOM_R_DEV_URANDOM_OPEN_FAILED,
|
||||
__FILE__, __LINE__
|
||||
);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int dev_urandom_read(unsigned char *buffer, int size) {
|
||||
int fd;
|
||||
int n;
|
||||
|
||||
fd = dev_urandom_fd();
|
||||
if (fd < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
do {
|
||||
n = (int)read(fd, buffer, (size_t)size);
|
||||
} while (n < 0 && errno == EINTR);
|
||||
|
||||
if (n <= 0) {
|
||||
ERR_Cryptography_OSRandom_error(
|
||||
CRYPTOGRAPHY_OSRANDOM_F_DEV_URANDOM_READ,
|
||||
CRYPTOGRAPHY_OSRANDOM_R_DEV_URANDOM_READ_FAILED,
|
||||
__FILE__, __LINE__
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
buffer += n;
|
||||
size -= n;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void dev_urandom_close(void) {
|
||||
if (urandom_cache.fd >= 0) {
|
||||
int fd;
|
||||
struct stat st;
|
||||
|
||||
if (fstat(urandom_cache.fd, &st)
|
||||
&& st.st_dev == urandom_cache.st_dev
|
||||
&& st.st_ino == urandom_cache.st_ino) {
|
||||
fd = urandom_cache.fd;
|
||||
urandom_cache.fd = -1;
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CRYPTOGRAPHY_OSRANDOM_NEEDS_DEV_URANDOM */
|
||||
|
||||
/****************************************************************************
|
||||
* BSD getentropy
|
||||
*/
|
||||
#if CRYPTOGRAPHY_OSRANDOM_ENGINE == CRYPTOGRAPHY_OSRANDOM_ENGINE_GETENTROPY
|
||||
static const char *Cryptography_osrandom_engine_name = "osrandom_engine getentropy()";
|
||||
|
||||
static int osrandom_init(ENGINE *e) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int osrandom_rand_bytes(unsigned char *buffer, int size) {
|
||||
int len;
|
||||
int res;
|
||||
|
||||
while (size > 0) {
|
||||
/* OpenBSD and macOS restrict maximum buffer size to 256. */
|
||||
len = size > 256 ? 256 : size;
|
||||
res = getentropy(buffer, (size_t)len);
|
||||
if (res < 0) {
|
||||
ERR_Cryptography_OSRandom_error(
|
||||
CRYPTOGRAPHY_OSRANDOM_F_RAND_BYTES,
|
||||
CRYPTOGRAPHY_OSRANDOM_R_GETENTROPY_FAILED,
|
||||
__FILE__, __LINE__
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
buffer += len;
|
||||
size -= len;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int osrandom_finish(ENGINE *e) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int osrandom_rand_status(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const char *osurandom_get_implementation(void) {
|
||||
return "getentropy";
|
||||
}
|
||||
#endif /* CRYPTOGRAPHY_OSRANDOM_ENGINE_GETENTROPY */
|
||||
|
||||
/****************************************************************************
|
||||
* Linux getrandom engine with fallback to dev_urandom
|
||||
*/
|
||||
|
||||
#if CRYPTOGRAPHY_OSRANDOM_ENGINE == CRYPTOGRAPHY_OSRANDOM_ENGINE_GETRANDOM
|
||||
static const char *Cryptography_osrandom_engine_name = "osrandom_engine getrandom()";
|
||||
|
||||
static int getrandom_works = CRYPTOGRAPHY_OSRANDOM_GETRANDOM_NOT_INIT;
|
||||
|
||||
static int osrandom_init(ENGINE *e) {
|
||||
/* We try to detect working getrandom until we succeed. */
|
||||
if (getrandom_works != CRYPTOGRAPHY_OSRANDOM_GETRANDOM_WORKS) {
|
||||
long n;
|
||||
char dest[1];
|
||||
/* if the kernel CSPRNG is not initialized this will block */
|
||||
n = syscall(SYS_getrandom, dest, sizeof(dest), 0);
|
||||
if (n == sizeof(dest)) {
|
||||
getrandom_works = CRYPTOGRAPHY_OSRANDOM_GETRANDOM_WORKS;
|
||||
} else {
|
||||
int e = errno;
|
||||
switch(e) {
|
||||
case ENOSYS:
|
||||
/* Fallback: Kernel does not support the syscall. */
|
||||
getrandom_works = CRYPTOGRAPHY_OSRANDOM_GETRANDOM_FALLBACK;
|
||||
break;
|
||||
case EPERM:
|
||||
/* Fallback: seccomp prevents syscall */
|
||||
getrandom_works = CRYPTOGRAPHY_OSRANDOM_GETRANDOM_FALLBACK;
|
||||
break;
|
||||
default:
|
||||
/* EINTR cannot occur for buflen < 256. */
|
||||
ERR_Cryptography_OSRandom_error(
|
||||
CRYPTOGRAPHY_OSRANDOM_F_INIT,
|
||||
CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_INIT_FAILED_UNEXPECTED,
|
||||
"errno", e
|
||||
);
|
||||
getrandom_works = CRYPTOGRAPHY_OSRANDOM_GETRANDOM_INIT_FAILED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* fallback to dev urandom */
|
||||
if (getrandom_works == CRYPTOGRAPHY_OSRANDOM_GETRANDOM_FALLBACK) {
|
||||
int fd = dev_urandom_fd();
|
||||
if (fd < 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int osrandom_rand_bytes(unsigned char *buffer, int size) {
|
||||
long n;
|
||||
|
||||
switch(getrandom_works) {
|
||||
case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_INIT_FAILED:
|
||||
ERR_Cryptography_OSRandom_error(
|
||||
CRYPTOGRAPHY_OSRANDOM_F_RAND_BYTES,
|
||||
CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_INIT_FAILED,
|
||||
__FILE__, __LINE__
|
||||
);
|
||||
return 0;
|
||||
case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_NOT_INIT:
|
||||
ERR_Cryptography_OSRandom_error(
|
||||
CRYPTOGRAPHY_OSRANDOM_F_RAND_BYTES,
|
||||
CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_NOT_INIT,
|
||||
__FILE__, __LINE__
|
||||
);
|
||||
return 0;
|
||||
case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_FALLBACK:
|
||||
return dev_urandom_read(buffer, size);
|
||||
case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_WORKS:
|
||||
while (size > 0) {
|
||||
do {
|
||||
n = syscall(SYS_getrandom, buffer, size, 0);
|
||||
} while (n < 0 && errno == EINTR);
|
||||
|
||||
if (n <= 0) {
|
||||
ERR_Cryptography_OSRandom_error(
|
||||
CRYPTOGRAPHY_OSRANDOM_F_RAND_BYTES,
|
||||
CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_FAILED,
|
||||
__FILE__, __LINE__
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
buffer += n;
|
||||
size -= (int)n;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
static int osrandom_finish(ENGINE *e) {
|
||||
dev_urandom_close();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int osrandom_rand_status(void) {
|
||||
switch(getrandom_works) {
|
||||
case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_INIT_FAILED:
|
||||
return 0;
|
||||
case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_NOT_INIT:
|
||||
return 0;
|
||||
case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_FALLBACK:
|
||||
return urandom_cache.fd >= 0;
|
||||
case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_WORKS:
|
||||
return 1;
|
||||
}
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
static const char *osurandom_get_implementation(void) {
|
||||
switch(getrandom_works) {
|
||||
case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_INIT_FAILED:
|
||||
return "<failed>";
|
||||
case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_NOT_INIT:
|
||||
return "<not initialized>";
|
||||
case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_FALLBACK:
|
||||
return "/dev/urandom";
|
||||
case CRYPTOGRAPHY_OSRANDOM_GETRANDOM_WORKS:
|
||||
return "getrandom";
|
||||
}
|
||||
__builtin_unreachable();
|
||||
}
|
||||
#endif /* CRYPTOGRAPHY_OSRANDOM_ENGINE_GETRANDOM */
|
||||
|
||||
/****************************************************************************
|
||||
* dev_urandom engine for all remaining platforms
|
||||
*/
|
||||
|
||||
#if CRYPTOGRAPHY_OSRANDOM_ENGINE == CRYPTOGRAPHY_OSRANDOM_ENGINE_DEV_URANDOM
|
||||
static const char *Cryptography_osrandom_engine_name = "osrandom_engine /dev/urandom";
|
||||
|
||||
static int osrandom_init(ENGINE *e) {
|
||||
int fd = dev_urandom_fd();
|
||||
if (fd < 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int osrandom_rand_bytes(unsigned char *buffer, int size) {
|
||||
return dev_urandom_read(buffer, size);
|
||||
}
|
||||
|
||||
static int osrandom_finish(ENGINE *e) {
|
||||
dev_urandom_close();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int osrandom_rand_status(void) {
|
||||
return urandom_cache.fd >= 0;
|
||||
}
|
||||
|
||||
static const char *osurandom_get_implementation(void) {
|
||||
return "/dev/urandom";
|
||||
}
|
||||
#endif /* CRYPTOGRAPHY_OSRANDOM_ENGINE_DEV_URANDOM */
|
||||
|
||||
/****************************************************************************
|
||||
* ENGINE boiler plate
|
||||
*/
|
||||
|
||||
/* This replicates the behavior of the OpenSSL FIPS RNG, which returns a
|
||||
-1 in the event that there is an error when calling RAND_pseudo_bytes. */
|
||||
static int osrandom_pseudo_rand_bytes(unsigned char *buffer, int size) {
|
||||
int res = osrandom_rand_bytes(buffer, size);
|
||||
if (res == 0) {
|
||||
return -1;
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
static RAND_METHOD osrandom_rand = {
|
||||
NULL,
|
||||
osrandom_rand_bytes,
|
||||
NULL,
|
||||
NULL,
|
||||
osrandom_pseudo_rand_bytes,
|
||||
osrandom_rand_status,
|
||||
};
|
||||
|
||||
static const ENGINE_CMD_DEFN osrandom_cmd_defns[] = {
|
||||
{CRYPTOGRAPHY_OSRANDOM_GET_IMPLEMENTATION,
|
||||
"get_implementation",
|
||||
"Get CPRNG implementation.",
|
||||
ENGINE_CMD_FLAG_NO_INPUT},
|
||||
{0, NULL, NULL, 0}
|
||||
};
|
||||
|
||||
static int osrandom_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) {
|
||||
const char *name;
|
||||
size_t len;
|
||||
|
||||
switch (cmd) {
|
||||
case CRYPTOGRAPHY_OSRANDOM_GET_IMPLEMENTATION:
|
||||
/* i: buffer size, p: char* buffer */
|
||||
name = osurandom_get_implementation();
|
||||
len = strlen(name);
|
||||
if ((p == NULL) && (i == 0)) {
|
||||
/* return required buffer len */
|
||||
return (int)len;
|
||||
}
|
||||
if ((p == NULL) || i < 0 || ((size_t)i <= len)) {
|
||||
/* no buffer or buffer too small */
|
||||
ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_INVALID_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
strcpy((char *)p, name);
|
||||
return (int)len;
|
||||
default:
|
||||
ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* error reporting */
|
||||
#define ERR_FUNC(func) ERR_PACK(0, func, 0)
|
||||
#define ERR_REASON(reason) ERR_PACK(0, 0, reason)
|
||||
|
||||
static ERR_STRING_DATA CRYPTOGRAPHY_OSRANDOM_lib_name[] = {
|
||||
{0, "osrandom_engine"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static ERR_STRING_DATA CRYPTOGRAPHY_OSRANDOM_str_funcs[] = {
|
||||
{ERR_FUNC(CRYPTOGRAPHY_OSRANDOM_F_INIT),
|
||||
"osrandom_init"},
|
||||
{ERR_FUNC(CRYPTOGRAPHY_OSRANDOM_F_RAND_BYTES),
|
||||
"osrandom_rand_bytes"},
|
||||
{ERR_FUNC(CRYPTOGRAPHY_OSRANDOM_F_FINISH),
|
||||
"osrandom_finish"},
|
||||
{ERR_FUNC(CRYPTOGRAPHY_OSRANDOM_F_DEV_URANDOM_FD),
|
||||
"dev_urandom_fd"},
|
||||
{ERR_FUNC(CRYPTOGRAPHY_OSRANDOM_F_DEV_URANDOM_READ),
|
||||
"dev_urandom_read"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static ERR_STRING_DATA CRYPTOGRAPHY_OSRANDOM_str_reasons[] = {
|
||||
{ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_CRYPTACQUIRECONTEXT),
|
||||
"CryptAcquireContext() failed."},
|
||||
{ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_CRYPTGENRANDOM),
|
||||
"CryptGenRandom() failed."},
|
||||
{ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_CRYPTRELEASECONTEXT),
|
||||
"CryptReleaseContext() failed."},
|
||||
{ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_GETENTROPY_FAILED),
|
||||
"getentropy() failed"},
|
||||
{ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_DEV_URANDOM_OPEN_FAILED),
|
||||
"open('/dev/urandom') failed."},
|
||||
{ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_DEV_URANDOM_READ_FAILED),
|
||||
"Reading from /dev/urandom fd failed."},
|
||||
{ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_INIT_FAILED),
|
||||
"getrandom() initialization failed."},
|
||||
{ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_INIT_FAILED_UNEXPECTED),
|
||||
"getrandom() initialization failed with unexpected errno."},
|
||||
{ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_FAILED),
|
||||
"getrandom() syscall failed."},
|
||||
{ERR_REASON(CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_NOT_INIT),
|
||||
"getrandom() engine was not properly initialized."},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static int Cryptography_OSRandom_lib_error_code = 0;
|
||||
|
||||
static void ERR_load_Cryptography_OSRandom_strings(void)
|
||||
{
|
||||
if (Cryptography_OSRandom_lib_error_code == 0) {
|
||||
Cryptography_OSRandom_lib_error_code = ERR_get_next_error_library();
|
||||
ERR_load_strings(Cryptography_OSRandom_lib_error_code,
|
||||
CRYPTOGRAPHY_OSRANDOM_lib_name);
|
||||
ERR_load_strings(Cryptography_OSRandom_lib_error_code,
|
||||
CRYPTOGRAPHY_OSRANDOM_str_funcs);
|
||||
ERR_load_strings(Cryptography_OSRandom_lib_error_code,
|
||||
CRYPTOGRAPHY_OSRANDOM_str_reasons);
|
||||
}
|
||||
}
|
||||
|
||||
static void ERR_Cryptography_OSRandom_error(int function, int reason,
|
||||
char *file, int line)
|
||||
{
|
||||
ERR_PUT_error(Cryptography_OSRandom_lib_error_code, function, reason,
|
||||
file, line);
|
||||
}
|
||||
|
||||
/* Returns 1 if successfully added, 2 if engine has previously been added,
|
||||
and 0 for error. */
|
||||
int Cryptography_add_osrandom_engine(void) {
|
||||
ENGINE *e;
|
||||
|
||||
ERR_load_Cryptography_OSRandom_strings();
|
||||
|
||||
e = ENGINE_by_id(Cryptography_osrandom_engine_id);
|
||||
if (e != NULL) {
|
||||
ENGINE_free(e);
|
||||
return 2;
|
||||
} else {
|
||||
ERR_clear_error();
|
||||
}
|
||||
|
||||
e = ENGINE_new();
|
||||
if (e == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (!ENGINE_set_id(e, Cryptography_osrandom_engine_id) ||
|
||||
!ENGINE_set_name(e, Cryptography_osrandom_engine_name) ||
|
||||
!ENGINE_set_RAND(e, &osrandom_rand) ||
|
||||
!ENGINE_set_init_function(e, osrandom_init) ||
|
||||
!ENGINE_set_finish_function(e, osrandom_finish) ||
|
||||
!ENGINE_set_cmd_defns(e, osrandom_cmd_defns) ||
|
||||
!ENGINE_set_ctrl_function(e, osrandom_ctrl)) {
|
||||
ENGINE_free(e);
|
||||
return 0;
|
||||
}
|
||||
if (!ENGINE_add(e)) {
|
||||
ENGINE_free(e);
|
||||
return 0;
|
||||
}
|
||||
if (!ENGINE_free(e)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
/* If OpenSSL has no ENGINE support then we don't want
|
||||
* to compile the osrandom engine, but we do need some
|
||||
* placeholders */
|
||||
static const char *Cryptography_osrandom_engine_id = "no-engine-support";
|
||||
static const char *Cryptography_osrandom_engine_name = "osrandom_engine disabled";
|
||||
|
||||
int Cryptography_add_osrandom_engine(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
#if CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE
|
||||
/* OpenSSL has ENGINE support so include all of this. */
|
||||
#ifdef _WIN32
|
||||
#include <Wincrypt.h>
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
/* for defined(BSD) */
|
||||
#ifndef __MVS__
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#ifdef BSD
|
||||
/* for SYS_getentropy */
|
||||
#include <sys/syscall.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <sys/random.h>
|
||||
/* To support weak linking we need to declare this as a weak import even if
|
||||
* it's not present in sys/random (e.g. macOS < 10.12). */
|
||||
extern int getentropy(void *buffer, size_t size) __attribute((weak_import));
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
/* for SYS_getrandom */
|
||||
#include <sys/syscall.h>
|
||||
#ifndef GRND_NONBLOCK
|
||||
#define GRND_NONBLOCK 0x0001
|
||||
#endif /* GRND_NONBLOCK */
|
||||
|
||||
#ifndef SYS_getrandom
|
||||
/* We only bother to define the constants for platforms where we ship
|
||||
* wheels, since that's the predominant way you get a situation where
|
||||
* you don't have SYS_getrandom at compile time but do have the syscall
|
||||
* at runtime */
|
||||
#if defined(__x86_64__)
|
||||
#define SYS_getrandom 318
|
||||
#elif defined(__i386__)
|
||||
#define SYS_getrandom 355
|
||||
#elif defined(__aarch64__)
|
||||
#define SYS_getrandom 278
|
||||
#endif
|
||||
#endif
|
||||
#endif /* __linux__ */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#define CRYPTOGRAPHY_OSRANDOM_ENGINE_CRYPTGENRANDOM 1
|
||||
#define CRYPTOGRAPHY_OSRANDOM_ENGINE_GETENTROPY 2
|
||||
#define CRYPTOGRAPHY_OSRANDOM_ENGINE_GETRANDOM 3
|
||||
#define CRYPTOGRAPHY_OSRANDOM_ENGINE_DEV_URANDOM 4
|
||||
|
||||
#ifndef CRYPTOGRAPHY_OSRANDOM_ENGINE
|
||||
#if defined(_WIN32)
|
||||
/* Windows */
|
||||
#define CRYPTOGRAPHY_OSRANDOM_ENGINE CRYPTOGRAPHY_OSRANDOM_ENGINE_CRYPTGENRANDOM
|
||||
#elif defined(BSD) && defined(SYS_getentropy)
|
||||
/* OpenBSD 5.6+ & macOS with SYS_getentropy defined, although < 10.12 will fallback
|
||||
* to urandom */
|
||||
#define CRYPTOGRAPHY_OSRANDOM_ENGINE CRYPTOGRAPHY_OSRANDOM_ENGINE_GETENTROPY
|
||||
#elif defined(__linux__) && defined(SYS_getrandom)
|
||||
/* Linux 3.17+ */
|
||||
#define CRYPTOGRAPHY_OSRANDOM_ENGINE CRYPTOGRAPHY_OSRANDOM_ENGINE_GETRANDOM
|
||||
#else
|
||||
/* Keep this as last entry, fall back to /dev/urandom */
|
||||
#define CRYPTOGRAPHY_OSRANDOM_ENGINE CRYPTOGRAPHY_OSRANDOM_ENGINE_DEV_URANDOM
|
||||
#endif
|
||||
#endif /* CRYPTOGRAPHY_OSRANDOM_ENGINE */
|
||||
|
||||
/* Fallbacks need /dev/urandom helper functions. */
|
||||
#if CRYPTOGRAPHY_OSRANDOM_ENGINE == CRYPTOGRAPHY_OSRANDOM_ENGINE_GETRANDOM || \
|
||||
CRYPTOGRAPHY_OSRANDOM_ENGINE == CRYPTOGRAPHY_OSRANDOM_ENGINE_DEV_URANDOM
|
||||
#define CRYPTOGRAPHY_OSRANDOM_NEEDS_DEV_URANDOM 1
|
||||
#endif
|
||||
|
||||
enum {
|
||||
CRYPTOGRAPHY_OSRANDOM_GETRANDOM_INIT_FAILED = -2,
|
||||
CRYPTOGRAPHY_OSRANDOM_GETRANDOM_NOT_INIT,
|
||||
CRYPTOGRAPHY_OSRANDOM_GETRANDOM_FALLBACK,
|
||||
CRYPTOGRAPHY_OSRANDOM_GETRANDOM_WORKS
|
||||
};
|
||||
|
||||
enum {
|
||||
CRYPTOGRAPHY_OSRANDOM_GETENTROPY_NOT_INIT,
|
||||
CRYPTOGRAPHY_OSRANDOM_GETENTROPY_FALLBACK,
|
||||
CRYPTOGRAPHY_OSRANDOM_GETENTROPY_WORKS
|
||||
};
|
||||
|
||||
/* engine ctrl */
|
||||
#define CRYPTOGRAPHY_OSRANDOM_GET_IMPLEMENTATION ENGINE_CMD_BASE
|
||||
|
||||
/* error reporting */
|
||||
static void ERR_load_Cryptography_OSRandom_strings(void);
|
||||
static void ERR_Cryptography_OSRandom_error(int function, int reason,
|
||||
char *file, int line);
|
||||
|
||||
#define CRYPTOGRAPHY_OSRANDOM_F_INIT 100
|
||||
#define CRYPTOGRAPHY_OSRANDOM_F_RAND_BYTES 101
|
||||
#define CRYPTOGRAPHY_OSRANDOM_F_FINISH 102
|
||||
#define CRYPTOGRAPHY_OSRANDOM_F_DEV_URANDOM_FD 300
|
||||
#define CRYPTOGRAPHY_OSRANDOM_F_DEV_URANDOM_READ 301
|
||||
|
||||
#define CRYPTOGRAPHY_OSRANDOM_R_CRYPTACQUIRECONTEXT 100
|
||||
#define CRYPTOGRAPHY_OSRANDOM_R_CRYPTGENRANDOM 101
|
||||
#define CRYPTOGRAPHY_OSRANDOM_R_CRYPTRELEASECONTEXT 102
|
||||
|
||||
#define CRYPTOGRAPHY_OSRANDOM_R_GETENTROPY_FAILED 200
|
||||
|
||||
#define CRYPTOGRAPHY_OSRANDOM_R_DEV_URANDOM_OPEN_FAILED 300
|
||||
#define CRYPTOGRAPHY_OSRANDOM_R_DEV_URANDOM_READ_FAILED 301
|
||||
|
||||
#define CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_INIT_FAILED 400
|
||||
#define CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_INIT_FAILED_UNEXPECTED 402
|
||||
#define CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_FAILED 403
|
||||
#define CRYPTOGRAPHY_OSRANDOM_R_GETRANDOM_NOT_INIT 404
|
||||
#endif
|
||||
|
|
@ -7,7 +7,6 @@ import collections
|
|||
import contextlib
|
||||
import itertools
|
||||
import typing
|
||||
import warnings
|
||||
from contextlib import contextmanager
|
||||
|
||||
from cryptography import utils, x509
|
||||
|
|
@ -185,13 +184,6 @@ class Backend:
|
|||
typing.Callable,
|
||||
] = {}
|
||||
self._register_default_ciphers()
|
||||
if self._fips_enabled and self._lib.CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE:
|
||||
warnings.warn(
|
||||
"OpenSSL FIPS mode is enabled. Can't enable DRBG fork safety.",
|
||||
UserWarning,
|
||||
)
|
||||
else:
|
||||
self.activate_osrandom_engine()
|
||||
self._dh_types = [self._lib.EVP_PKEY_DH]
|
||||
if self._lib.Cryptography_HAS_EVP_PKEY_DHX:
|
||||
self._dh_types.append(self._lib.EVP_PKEY_DHX)
|
||||
|
|
@ -230,60 +222,6 @@ class Backend:
|
|||
assert self._is_fips_enabled()
|
||||
self._fips_enabled = self._is_fips_enabled()
|
||||
|
||||
def activate_builtin_random(self) -> None:
|
||||
if self._lib.CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE:
|
||||
# Obtain a new structural reference.
|
||||
e = self._lib.ENGINE_get_default_RAND()
|
||||
if e != self._ffi.NULL:
|
||||
self._lib.ENGINE_unregister_RAND(e)
|
||||
# Reset the RNG to use the built-in.
|
||||
res = self._lib.RAND_set_rand_method(self._ffi.NULL)
|
||||
self.openssl_assert(res == 1)
|
||||
# decrement the structural reference from get_default_RAND
|
||||
res = self._lib.ENGINE_finish(e)
|
||||
self.openssl_assert(res == 1)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def _get_osurandom_engine(self):
|
||||
# Fetches an engine by id and returns it. This creates a structural
|
||||
# reference.
|
||||
e = self._lib.ENGINE_by_id(self._lib.Cryptography_osrandom_engine_id)
|
||||
self.openssl_assert(e != self._ffi.NULL)
|
||||
# Initialize the engine for use. This adds a functional reference.
|
||||
res = self._lib.ENGINE_init(e)
|
||||
self.openssl_assert(res == 1)
|
||||
|
||||
try:
|
||||
yield e
|
||||
finally:
|
||||
# Decrement the structural ref incremented by ENGINE_by_id.
|
||||
res = self._lib.ENGINE_free(e)
|
||||
self.openssl_assert(res == 1)
|
||||
# Decrement the functional ref incremented by ENGINE_init.
|
||||
res = self._lib.ENGINE_finish(e)
|
||||
self.openssl_assert(res == 1)
|
||||
|
||||
def activate_osrandom_engine(self) -> None:
|
||||
if self._lib.CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE:
|
||||
# Unregister and free the current engine.
|
||||
self.activate_builtin_random()
|
||||
with self._get_osurandom_engine() as e:
|
||||
# Set the engine as the default RAND provider.
|
||||
res = self._lib.ENGINE_set_default_RAND(e)
|
||||
self.openssl_assert(res == 1)
|
||||
# Reset the RNG to use the engine
|
||||
res = self._lib.RAND_set_rand_method(self._ffi.NULL)
|
||||
self.openssl_assert(res == 1)
|
||||
|
||||
def osrandom_engine_implementation(self) -> str:
|
||||
buf = self._ffi.new("char[]", 64)
|
||||
with self._get_osurandom_engine() as e:
|
||||
res = self._lib.ENGINE_ctrl_cmd(
|
||||
e, b"get_implementation", len(buf), buf, self._ffi.NULL, 0
|
||||
)
|
||||
self.openssl_assert(res > 0)
|
||||
return self._ffi.string(buf).decode("ascii")
|
||||
|
||||
def openssl_version_text(self) -> str:
|
||||
"""
|
||||
Friendly string name of the loaded OpenSSL library. This is not
|
||||
|
|
@ -1968,7 +1906,7 @@ class Backend:
|
|||
if self._fips_enabled:
|
||||
return False
|
||||
return (
|
||||
not self._lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_111B
|
||||
not self._lib.CRYPTOGRAPHY_IS_LIBRESSL
|
||||
and not self._lib.CRYPTOGRAPHY_IS_BORINGSSL
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ class _CipherContext:
|
|||
lib = self._backend._lib
|
||||
if res == 0 and (
|
||||
(
|
||||
lib.CRYPTOGRAPHY_OPENSSL_111D_OR_GREATER
|
||||
not lib.CRYPTOGRAPHY_IS_LIBRESSL
|
||||
and errors[0]._lib_reason_match(
|
||||
lib.ERR_LIB_EVP, lib.EVP_R_XTS_DUPLICATED_KEYS
|
||||
)
|
||||
|
|
|
|||
|
|
@ -162,7 +162,6 @@ def cryptography_has_engine() -> typing.List[str]:
|
|||
"ENGINE_ctrl_cmd",
|
||||
"ENGINE_free",
|
||||
"ENGINE_get_name",
|
||||
"Cryptography_add_osrandom_engine",
|
||||
"ENGINE_ctrl_cmd_string",
|
||||
"ENGINE_load_builtin_engines",
|
||||
"ENGINE_load_private_key",
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import typing
|
|||
import warnings
|
||||
|
||||
import cryptography
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import InternalError
|
||||
from cryptography.hazmat.bindings._rust import _openssl, openssl
|
||||
from cryptography.hazmat.bindings.openssl._conditional import CONDITIONAL_NAMES
|
||||
|
|
@ -98,18 +97,6 @@ class Binding:
|
|||
res = self.lib.EVP_default_properties_enable_fips(self.ffi.NULL, 1)
|
||||
_openssl_assert(self.lib, res == 1)
|
||||
|
||||
@classmethod
|
||||
def _register_osrandom_engine(cls) -> None:
|
||||
# Clear any errors extant in the queue before we start. In many
|
||||
# scenarios other things may be interacting with OpenSSL in the same
|
||||
# process space and it has proven untenable to assume that they will
|
||||
# reliably clear the error queue. Once we clear it here we will
|
||||
# error on any subsequent unexpected item in the stack.
|
||||
cls.lib.ERR_clear_error()
|
||||
if cls.lib.CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE:
|
||||
result = cls.lib.Cryptography_add_osrandom_engine()
|
||||
_openssl_assert(cls.lib, result in (1, 2))
|
||||
|
||||
@classmethod
|
||||
def _ensure_ffi_initialized(cls) -> None:
|
||||
with cls._init_lock:
|
||||
|
|
@ -118,7 +105,6 @@ class Binding:
|
|||
_openssl.lib, CONDITIONAL_NAMES
|
||||
)
|
||||
cls._lib_loaded = True
|
||||
cls._register_osrandom_engine()
|
||||
# As of OpenSSL 3.0.0 we must register a legacy cipher provider
|
||||
# to get RC2 (needed for junk asymmetric private key
|
||||
# serialization), RC4, Blowfish, IDEA, SEED, etc. These things
|
||||
|
|
@ -189,20 +175,3 @@ if (
|
|||
UserWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
|
||||
def _verify_openssl_version(lib):
|
||||
if (
|
||||
not lib.CRYPTOGRAPHY_OPENSSL_111D_OR_GREATER
|
||||
and not lib.CRYPTOGRAPHY_IS_LIBRESSL
|
||||
and not lib.CRYPTOGRAPHY_IS_BORINGSSL
|
||||
):
|
||||
warnings.warn(
|
||||
"Support for OpenSSL less than version 1.1.1d is deprecated and "
|
||||
"the next release of cryptography will drop support. Please "
|
||||
"upgrade your OpenSSL to version 1.1.1d or newer.",
|
||||
utils.DeprecatedIn40,
|
||||
)
|
||||
|
||||
|
||||
_verify_openssl_version(Binding.lib)
|
||||
|
|
|
|||
|
|
@ -5,9 +5,6 @@
|
|||
|
||||
import itertools
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
import pytest
|
||||
|
||||
|
|
@ -179,158 +176,6 @@ class TestOpenSSL:
|
|||
assert backend._bn_to_int(bn) == 0
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not backend._lib.CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE,
|
||||
reason="Requires OpenSSL with ENGINE support and OpenSSL < 1.1.1d",
|
||||
)
|
||||
@pytest.mark.skip_fips(reason="osrandom engine disabled for FIPS")
|
||||
class TestOpenSSLRandomEngine:
|
||||
def setup_method(self):
|
||||
# The default RAND engine is global and shared between
|
||||
# tests. We make sure that the default engine is osrandom
|
||||
# before we start each test and restore the global state to
|
||||
# that engine in teardown.
|
||||
current_default = backend._lib.ENGINE_get_default_RAND()
|
||||
name = backend._lib.ENGINE_get_name(current_default)
|
||||
assert name == backend._lib.Cryptography_osrandom_engine_name
|
||||
|
||||
def teardown_method(self):
|
||||
# we need to reset state to being default. backend is a shared global
|
||||
# for all these tests.
|
||||
backend.activate_osrandom_engine()
|
||||
current_default = backend._lib.ENGINE_get_default_RAND()
|
||||
name = backend._lib.ENGINE_get_name(current_default)
|
||||
assert name == backend._lib.Cryptography_osrandom_engine_name
|
||||
|
||||
@pytest.mark.skipif(
|
||||
sys.executable is None, reason="No Python interpreter available."
|
||||
)
|
||||
def test_osrandom_engine_is_default(self, tmpdir):
|
||||
engine_printer = textwrap.dedent(
|
||||
"""
|
||||
import sys
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
e = backend._lib.ENGINE_get_default_RAND()
|
||||
name = backend._lib.ENGINE_get_name(e)
|
||||
sys.stdout.write(backend._ffi.string(name).decode('ascii'))
|
||||
res = backend._lib.ENGINE_free(e)
|
||||
assert res == 1
|
||||
"""
|
||||
)
|
||||
engine_name = tmpdir.join("engine_name")
|
||||
|
||||
# If we're running tests via ``python setup.py test`` in a clean
|
||||
# environment then all of our dependencies are going to be installed
|
||||
# into either the current directory or the .eggs directory. However the
|
||||
# subprocess won't know to activate these dependencies, so we'll get it
|
||||
# to do so by passing our entire sys.path into the subprocess via the
|
||||
# PYTHONPATH environment variable.
|
||||
env = os.environ.copy()
|
||||
env["PYTHONPATH"] = os.pathsep.join(sys.path)
|
||||
|
||||
with engine_name.open("w") as out:
|
||||
subprocess.check_call(
|
||||
[sys.executable, "-c", engine_printer],
|
||||
env=env,
|
||||
stdout=out,
|
||||
stderr=subprocess.PIPE,
|
||||
)
|
||||
|
||||
osrandom_engine_name = backend._ffi.string(
|
||||
backend._lib.Cryptography_osrandom_engine_name
|
||||
)
|
||||
|
||||
assert engine_name.read().encode("ascii") == osrandom_engine_name
|
||||
|
||||
def test_osrandom_sanity_check(self):
|
||||
# This test serves as a check against catastrophic failure.
|
||||
buf = backend._ffi.new("unsigned char[]", 500)
|
||||
res = backend._lib.RAND_bytes(buf, 500)
|
||||
assert res == 1
|
||||
assert backend._ffi.buffer(buf)[:] != "\x00" * 500
|
||||
|
||||
def test_activate_osrandom_no_default(self):
|
||||
backend.activate_builtin_random()
|
||||
e = backend._lib.ENGINE_get_default_RAND()
|
||||
assert e == backend._ffi.NULL
|
||||
backend.activate_osrandom_engine()
|
||||
e = backend._lib.ENGINE_get_default_RAND()
|
||||
name = backend._lib.ENGINE_get_name(e)
|
||||
assert name == backend._lib.Cryptography_osrandom_engine_name
|
||||
res = backend._lib.ENGINE_free(e)
|
||||
assert res == 1
|
||||
|
||||
def test_activate_builtin_random(self):
|
||||
e = backend._lib.ENGINE_get_default_RAND()
|
||||
assert e != backend._ffi.NULL
|
||||
name = backend._lib.ENGINE_get_name(e)
|
||||
assert name == backend._lib.Cryptography_osrandom_engine_name
|
||||
res = backend._lib.ENGINE_free(e)
|
||||
assert res == 1
|
||||
backend.activate_builtin_random()
|
||||
e = backend._lib.ENGINE_get_default_RAND()
|
||||
assert e == backend._ffi.NULL
|
||||
|
||||
def test_activate_builtin_random_already_active(self):
|
||||
backend.activate_builtin_random()
|
||||
e = backend._lib.ENGINE_get_default_RAND()
|
||||
assert e == backend._ffi.NULL
|
||||
backend.activate_builtin_random()
|
||||
e = backend._lib.ENGINE_get_default_RAND()
|
||||
assert e == backend._ffi.NULL
|
||||
|
||||
def test_osrandom_engine_implementation(self):
|
||||
name = backend.osrandom_engine_implementation()
|
||||
assert name in [
|
||||
"/dev/urandom",
|
||||
"CryptGenRandom",
|
||||
"getentropy",
|
||||
"getrandom",
|
||||
]
|
||||
if sys.platform.startswith("linux"):
|
||||
assert name in ["getrandom", "/dev/urandom"]
|
||||
if sys.platform == "darwin":
|
||||
assert name in ["getentropy"]
|
||||
if sys.platform == "win32":
|
||||
assert name == "CryptGenRandom"
|
||||
|
||||
def test_activate_osrandom_already_default(self):
|
||||
e = backend._lib.ENGINE_get_default_RAND()
|
||||
name = backend._lib.ENGINE_get_name(e)
|
||||
assert name == backend._lib.Cryptography_osrandom_engine_name
|
||||
res = backend._lib.ENGINE_free(e)
|
||||
assert res == 1
|
||||
backend.activate_osrandom_engine()
|
||||
e = backend._lib.ENGINE_get_default_RAND()
|
||||
name = backend._lib.ENGINE_get_name(e)
|
||||
assert name == backend._lib.Cryptography_osrandom_engine_name
|
||||
res = backend._lib.ENGINE_free(e)
|
||||
assert res == 1
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
backend._lib.CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE,
|
||||
reason="Requires OpenSSL without ENGINE support or OpenSSL >=1.1.1d",
|
||||
)
|
||||
class TestOpenSSLNoEngine:
|
||||
def test_no_engine_support(self):
|
||||
assert (
|
||||
backend._ffi.string(backend._lib.Cryptography_osrandom_engine_id)
|
||||
== b"no-engine-support"
|
||||
)
|
||||
assert (
|
||||
backend._ffi.string(backend._lib.Cryptography_osrandom_engine_name)
|
||||
== b"osrandom_engine disabled"
|
||||
)
|
||||
|
||||
def test_activate_builtin_random_does_nothing(self):
|
||||
backend.activate_builtin_random()
|
||||
|
||||
def test_activate_osrandom_does_nothing(self):
|
||||
backend.activate_osrandom_engine()
|
||||
|
||||
|
||||
class TestOpenSSLRSA:
|
||||
def test_generate_rsa_parameters_supported(self):
|
||||
assert backend.generate_rsa_parameters_supported(1, 1024) is False
|
||||
|
|
|
|||
|
|
@ -21,11 +21,6 @@ class TestOpenSSL:
|
|||
assert binding.lib
|
||||
assert binding.ffi
|
||||
|
||||
def test_add_engine_more_than_once(self):
|
||||
b = Binding()
|
||||
b._register_osrandom_engine()
|
||||
assert b.lib.ERR_get_error() == 0
|
||||
|
||||
def test_ssl_ctx_options(self):
|
||||
# Test that we're properly handling 32-bit unsigned on all platforms.
|
||||
b = Binding()
|
||||
|
|
@ -85,18 +80,6 @@ class TestOpenSSL:
|
|||
if not b.lib.CRYPTOGRAPHY_IS_BORINGSSL:
|
||||
assert b"data not multiple of block length" in error.reason_text
|
||||
|
||||
def test_check_startup_errors_are_allowed(self):
|
||||
b = Binding()
|
||||
b.lib.ERR_put_error(
|
||||
b.lib.ERR_LIB_EVP,
|
||||
b.lib.EVP_F_EVP_ENCRYPTFINAL_EX,
|
||||
b.lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH,
|
||||
b"",
|
||||
-1,
|
||||
)
|
||||
b._register_osrandom_engine()
|
||||
assert rust_openssl.capture_error_stack() == []
|
||||
|
||||
def test_version_mismatch(self):
|
||||
with pytest.raises(ImportError):
|
||||
_verify_package_version("nottherightversion")
|
||||
|
|
|
|||
|
|
@ -61,9 +61,7 @@ class TestAESModeXTS:
|
|||
enc.update(b"0" * 15)
|
||||
|
||||
@pytest.mark.supported(
|
||||
only_if=lambda backend: (
|
||||
backend._lib.CRYPTOGRAPHY_OPENSSL_111D_OR_GREATER
|
||||
),
|
||||
only_if=lambda backend: (not backend._lib.CRYPTOGRAPHY_IS_LIBRESSL),
|
||||
skip_message="duplicate key encryption error added in OpenSSL 1.1.1d",
|
||||
)
|
||||
def test_xts_no_duplicate_keys_encryption(self, backend):
|
||||
|
|
|
|||
Loading…
Reference in a new issue