Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
slapos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
104
Merge Requests
104
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
nexedi
slapos
Commits
949a61b4
Commit
949a61b4
authored
Dec 11, 2023
by
Kazuhiko Shiozaki
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
component/python-cryptography: backport OpenSSL 3.0 support.
parent
24a22308
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
339 additions
and
1 deletion
+339
-1
component/python-cryptography/buildout.cfg
component/python-cryptography/buildout.cfg
+2
-0
component/python-cryptography/cryptography-3.3.2-openssl-3.0.patch
.../python-cryptography/cryptography-3.3.2-openssl-3.0.patch
+336
-0
stack/slapos.cfg
stack/slapos.cfg
+1
-1
No files found.
component/python-cryptography/buildout.cfg
View file @
949a61b4
...
...
@@ -12,6 +12,8 @@ recipe = zc.recipe.egg:custom
egg = cryptography
environment = python-cryptography-env
setup-eggs = ${python-cffi:egg}
cryptography-patches = ${:_profile_base_location_}/cryptography-3.3.2-openssl-3.0.patch#aa055c3cfab6110fd616f2de049e1388
cryptography-patch-options = -p0
library-dirs =
${openssl:location}/lib/
rpath =
...
...
component/python-cryptography/cryptography-3.3.2-openssl-3.0.patch
0 → 100644
View file @
949a61b4
Minimal changes to support OpenSSL 3.0 based on the following commits :
* f08a7de651f9e6475c8c0a67d2a61ed8b669ddf6 [WIP] 3.0.0 support (#5250)
*
50ec692749b7e2e62685b443f5e629627b03987e remove unneeded binding (#6150)
*
77fb53c75e47f50e09b1b3be3a4d10c7e4e34dc2 3.0.0 deprecated func and it isn't useful to us in general (#6148)
diff --git src/_cffi_src/build_openssl.py src/_cffi_src/build_openssl.py
index 4380c3396..928f5fe4f 100644
--- src/_cffi_src/build_openssl.py
+++ src/_cffi_src/build_openssl.py
@@ -105,6 +105,7 @@
ffi = build_ffi_for_binding(
"osrandom_engine",
"pem",
"pkcs12",
+ "provider",
"rand",
"rsa",
"ssl",
diff --git src/_cffi_src/openssl/cryptography.py src/_cffi_src/openssl/cryptography.py
index f24bee5a4..920a86dea 100644
--- src/_cffi_src/openssl/cryptography.py
+++ src/_cffi_src/openssl/cryptography.py
@@ -35,6 +35,8 @@
INCLUDES = """
#define CRYPTOGRAPHY_OPENSSL_110F_OR_GREATER \
(OPENSSL_VERSION_NUMBER >= 0x1010006f && !CRYPTOGRAPHY_IS_LIBRESSL)
+#define CRYPTOGRAPHY_OPENSSL_300_OR_GREATER \
+ (OPENSSL_VERSION_NUMBER >= 0x30000000 && !CRYPTOGRAPHY_IS_LIBRESSL)
#define CRYPTOGRAPHY_OPENSSL_LESS_THAN_110J \
(OPENSSL_VERSION_NUMBER < 0x101000af || CRYPTOGRAPHY_IS_LIBRESSL)
@@ -54,6 +56,7 @@
INCLUDES = """
TYPES = """
static const int CRYPTOGRAPHY_OPENSSL_110F_OR_GREATER;
+static const int CRYPTOGRAPHY_OPENSSL_300_OR_GREATER;
static const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_111;
static const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_111B;
diff --git src/_cffi_src/openssl/err.py src/_cffi_src/openssl/err.py
index 0dd741467..c2486953d 100644
--- src/_cffi_src/openssl/err.py
+++ src/_cffi_src/openssl/err.py
@@ -19,6 +19,7 @@
static const int EVP_R_UNKNOWN_PBE_ALGORITHM;
static const int ERR_LIB_EVP;
static const int ERR_LIB_PEM;
+static const int ERR_LIB_PROV;
static const int ERR_LIB_ASN1;
static const int ERR_LIB_PKCS12;
@@ -40,10 +41,14 @@
void ERR_clear_error(void);
void ERR_put_error(int, int, int, const char *, int);
int ERR_GET_LIB(unsigned long);
-int ERR_GET_FUNC(unsigned long);
int ERR_GET_REASON(unsigned long);
"""
CUSTOMIZATIONS = """
+/* This define is tied to provider support and is conditionally
+ removed if Cryptography_HAS_PROVIDERS is false */
+#ifndef ERR_LIB_PROV
+#define ERR_LIB_PROV 0
+#endif
"""
diff --git src/_cffi_src/openssl/fips.py src/_cffi_src/openssl/fips.py
index c92bca494..38bfa231f 100644
--- src/_cffi_src/openssl/fips.py
+++ src/_cffi_src/openssl/fips.py
@@ -18,7 +18,7 @@
int FIPS_mode(void);
"""
CUSTOMIZATIONS = """
-#if CRYPTOGRAPHY_IS_LIBRESSL
+#if CRYPTOGRAPHY_IS_LIBRESSL || CRYPTOGRAPHY_OPENSSL_300_OR_GREATER
static const long Cryptography_HAS_FIPS = 0;
int (*FIPS_mode_set)(int) = NULL;
int (*FIPS_mode)(void) = NULL;
diff --git src/_cffi_src/openssl/provider.py src/_cffi_src/openssl/provider.py
new file mode 100644
index 000000000..d7d659ea5
--- /dev/null
+++ src/_cffi_src/openssl/provider.py
@@ -0,0 +1,40 @@
+# 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.
+
+
+INCLUDES = """
+#if CRYPTOGRAPHY_OPENSSL_300_OR_GREATER
+#include <openssl/provider.h>
+#include <openssl/proverr.h>
+#endif
+"""
+
+TYPES = """
+static const long Cryptography_HAS_PROVIDERS;
+
+typedef ... OSSL_PROVIDER;
+typedef ... OSSL_LIB_CTX;
+
+static const long PROV_R_BAD_DECRYPT;
+static const long PROV_R_WRONG_FINAL_BLOCK_LENGTH;
+"""
+
+FUNCTIONS = """
+OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *, const char *);
+int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov);
+"""
+
+CUSTOMIZATIONS = """
+#if CRYPTOGRAPHY_OPENSSL_300_OR_GREATER
+static const long Cryptography_HAS_PROVIDERS = 1;
+#else
+static const long Cryptography_HAS_PROVIDERS = 0;
+typedef void OSSL_PROVIDER;
+typedef void OSSL_LIB_CTX;
+static const long PROV_R_BAD_DECRYPT = 0;
+static const long PROV_R_WRONG_FINAL_BLOCK_LENGTH = 0;
+OSSL_PROVIDER *(*OSSL_PROVIDER_load)(OSSL_LIB_CTX *, const char *) = NULL;
+int (*OSSL_PROVIDER_unload)(OSSL_PROVIDER *) = NULL;
+#endif
+"""
diff --git src/cryptography/hazmat/backends/openssl/backend.py src/cryptography/hazmat/backends/openssl/backend.py
index 45d4a1a1e..1b48355da 100644
--- src/cryptography/hazmat/backends/openssl/backend.py
+++ src/cryptography/hazmat/backends/openssl/backend.py
@@ -1307,6 +1307,11 @@
class Backend(object):
def _evp_pkey_from_der_traditional_key(self, bio_data, password):
key = self._lib.d2i_PrivateKey_bio(bio_data.bio, self._ffi.NULL)
if key != self._ffi.NULL:
+ # In OpenSSL 3.0.0-alpha15 there exist scenarios where the key will
+ # successfully load but errors are still put on the stack. Tracked
+ # as https://github.com/openssl/openssl/issues/14996
+ self._consume_errors()
+
key = self._ffi.gc(key, self._lib.EVP_PKEY_free)
if password is not None:
raise TypeError(
@@ -1474,6 +1479,11 @@
class Backend(object):
else:
self._handle_key_loading_error()
+ # In OpenSSL 3.0.0-alpha15 there exist scenarios where the key will
+ # successfully load but errors are still put on the stack. Tracked
+ # as https://github.com/openssl/openssl/issues/14996
+ self._consume_errors()
+
evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free)
if password is not None and userdata.called == 0:
@@ -1496,11 +1506,22 @@
class Backend(object):
"incorrect format or it may be encrypted with an unsupported "
"algorithm."
)
- elif errors[0]._lib_reason_match(
- self._lib.ERR_LIB_EVP, self._lib.EVP_R_BAD_DECRYPT
- ) or errors[0]._lib_reason_match(
- self._lib.ERR_LIB_PKCS12,
- self._lib.PKCS12_R_PKCS12_CIPHERFINAL_ERROR,
+
+ elif (
+ errors[0]._lib_reason_match(
+ self._lib.ERR_LIB_EVP, self._lib.EVP_R_BAD_DECRYPT
+ )
+ or errors[0]._lib_reason_match(
+ self._lib.ERR_LIB_PKCS12,
+ self._lib.PKCS12_R_PKCS12_CIPHERFINAL_ERROR,
+ )
+ or (
+ self._lib.Cryptography_HAS_PROVIDERS
+ and errors[0]._lib_reason_match(
+ self._lib.ERR_LIB_PROV,
+ self._lib.PROV_R_BAD_DECRYPT,
+ )
+ )
):
raise ValueError("Bad decrypt. Incorrect password?")
@@ -2546,7 +2567,15 @@
class Backend(object):
if sk_x509_ptr[0] != self._ffi.NULL:
sk_x509 = self._ffi.gc(sk_x509_ptr[0], self._lib.sk_X509_free)
num = self._lib.sk_X509_num(sk_x509_ptr[0])
- for i in range(num):
+
+ # In OpenSSL < 3.0.0 PKCS12 parsing reverses the order of the
+ # certificates.
+ if self._lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER:
+ indices = range(num)
+ else:
+ indices = reversed(range(num))
+
+ for i in indices:
x509 = self._lib.sk_X509_value(sk_x509, i)
self.openssl_assert(x509 != self._ffi.NULL)
x509 = self._ffi.gc(x509, self._lib.X509_free)
diff --git src/cryptography/hazmat/backends/openssl/ciphers.py src/cryptography/hazmat/backends/openssl/ciphers.py
index ad5dad3f7..f4c869a40 100644
--- src/cryptography/hazmat/backends/openssl/ciphers.py
+++ src/cryptography/hazmat/backends/openssl/ciphers.py
@@ -146,7 +146,14 @@
class _CipherContext(object):
res = self._backend._lib.EVP_CipherUpdate(
self._ctx, outbuf, outlen, inbuf, inlen
)
- self._backend.openssl_assert(res != 0)
+ if res == 0 and isinstance(self._mode, modes.XTS):
+ self._backend._consume_errors()
+ raise ValueError(
+ "In XTS mode you must supply at least a full block in the "
+ "first update call. For AES this is 16 bytes."
+ )
+ else:
+ self._backend.openssl_assert(res != 0)
data_processed += inlen
total_out += outlen[0]
@@ -175,6 +182,13 @@
class _CipherContext(object):
errors[0]._lib_reason_match(
self._backend._lib.ERR_LIB_EVP,
self._backend._lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH,
+ )
+ or (
+ self._backend._lib.Cryptography_HAS_PROVIDERS
+ and errors[0]._lib_reason_match(
+ self._backend._lib.ERR_LIB_PROV,
+ self._backend._lib.PROV_R_WRONG_FINAL_BLOCK_LENGTH,
+ )
),
errors=errors,
)
diff --git src/cryptography/hazmat/bindings/openssl/_conditional.py src/cryptography/hazmat/bindings/openssl/_conditional.py
index ca50fed13..fdcead1a5 100644
--- src/cryptography/hazmat/bindings/openssl/_conditional.py
+++ src/cryptography/hazmat/bindings/openssl/_conditional.py
@@ -271,6 +271,16 @@
def cryptography_has_get_proto_version():
]
+def cryptography_has_providers():
+ return [
+ "OSSL_PROVIDER_load",
+ "OSSL_PROVIDER_unload",
+ "ERR_LIB_PROV",
+ "PROV_R_WRONG_FINAL_BLOCK_LENGTH",
+ "PROV_R_BAD_DECRYPT",
+ ]
+
+
# This is a mapping of
# {condition: function-returning-names-dependent-on-that-condition} so we can
# loop over them and delete unsupported names at runtime. It will be removed
@@ -319,4 +329,5 @@
CONDITIONAL_NAMES = {
"Cryptography_HAS_VERIFIED_CHAIN": cryptography_has_verified_chain,
"Cryptography_HAS_SRTP": cryptography_has_srtp,
"Cryptography_HAS_GET_PROTO_VERSION": cryptography_has_get_proto_version,
+ "Cryptography_HAS_PROVIDERS": cryptography_has_providers,
}
diff --git src/cryptography/hazmat/bindings/openssl/binding.py src/cryptography/hazmat/bindings/openssl/binding.py
index 7a84a340e..c0b0d8238 100644
--- src/cryptography/hazmat/bindings/openssl/binding.py
+++ src/cryptography/hazmat/bindings/openssl/binding.py
@@ -15,15 +15,14 @@
from cryptography.hazmat.bindings._openssl import ffi, lib
from cryptography.hazmat.bindings.openssl._conditional import CONDITIONAL_NAMES
_OpenSSLErrorWithText = collections.namedtuple(
- "_OpenSSLErrorWithText", ["code", "lib", "func", "reason", "reason_text"]
+ "_OpenSSLErrorWithText", ["code", "lib", "reason", "reason_text"]
)
class _OpenSSLError(object):
- def __init__(self, code, lib, func, reason):
+ def __init__(self, code, lib, reason):
self._code = code
self._lib = lib
- self._func = func
self._reason = reason
def _lib_reason_match(self, lib, reason):
@@ -31,7 +30,6 @@
class _OpenSSLError(object):
code = utils.read_only_property("_code")
lib = utils.read_only_property("_lib")
- func = utils.read_only_property("_func")
reason = utils.read_only_property("_reason")
@@ -43,10 +41,9 @@
def _consume_errors(lib):
break
err_lib = lib.ERR_GET_LIB(code)
- err_func = lib.ERR_GET_FUNC(code)
err_reason = lib.ERR_GET_REASON(code)
- errors.append(_OpenSSLError(code, err_lib, err_func, err_reason))
+ errors.append(_OpenSSLError(code, err_lib, err_reason))
return errors
@@ -60,7 +57,7 @@
def _errors_with_text(errors):
errors_with_text.append(
_OpenSSLErrorWithText(
- err.code, err.lib, err.func, err.reason, err_text_reason
+ err.code, err.lib, err.reason, err_text_reason
)
)
@@ -140,6 +137,24 @@
class Binding(object):
# adds all ciphers/digests for EVP
cls.lib.OpenSSL_add_all_algorithms()
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
+ # are ugly legacy, but we aren't going to get rid of them
+ # any time soon.
+ if cls.lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER:
+ cls._legacy_provider = cls.lib.OSSL_PROVIDER_load(
+ cls.ffi.NULL, b"legacy"
+ )
+ _openssl_assert(
+ cls.lib, cls._legacy_provider != cls.ffi.NULL
+ )
+ cls._default_provider = cls.lib.OSSL_PROVIDER_load(
+ cls.ffi.NULL, b"default"
+ )
+ _openssl_assert(
+ cls.lib, cls._default_provider != cls.ffi.NULL
+ )
@classmethod
def init_static_locks(cls):
stack/slapos.cfg
View file @
949a61b4
...
...
@@ -176,7 +176,7 @@ collective.recipe.template = 2.0
configparser = 4.0.2:whl
contextlib2 = 0.6.0.post1
croniter = 0.3.25
cryptography = 3.3.2
cryptography = 3.3.2
+SlapOSPatched001
dataclasses = 0.8
dateparser = 0.7.6
decorator = 4.3.0
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment