Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion recipe/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{% set ver2 = '.'.join(version.split('.')[0:2]) %}
{% set ver2nd = ''.join(version.split('.')[0:2]) %}
{% set ver3nd = ''.join(version.split('.')[0:3]) %}
{% set build_number = "0" %}
{% set build_number = "1" %}
{% set channel_targets = ('abc', 'def') %}

# this makes the linter happy
Expand Down Expand Up @@ -88,6 +88,10 @@ source:
- patches/0026-Use-OpenSSL-3-instead-of-1_1.patch
{% endif %}
- patches/0027-Unvendor-expat.patch
# https://github.com/python/cpython/pull/100373 (OpenSSL 3.5.7 Windows cert-store fix)
- patches/0028-Fix-ssl-DER-EOF-detection-for-openssl-3.5.7.patch
# https://github.com/python/cpython/pull/29791
- patches/0029-Fix-ctypes-fielddesc-init-for-external-libffi.patch

build:
number: {{ build_number }}
Expand Down Expand Up @@ -235,6 +239,7 @@ outputs:
- tests/cython/*
- tests/prefix-replacement/*
- run_test.py
- test-cert.pem
commands:
- echo on # [win]
- set # [win]
Expand Down
523 changes: 262 additions & 261 deletions recipe/patches/0015-Doing-d1trimfile.patch

Large diffs are not rendered by default.

7 changes: 3 additions & 4 deletions recipe/patches/0021-Unvendor-libffi.patch
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ index 975c4a0d35..97fb5966bf 100644
- <Delete Files="@(_LIBFFIDLL->'$(OutDir)%(Filename)%(Extension)')" TreatErrorsAsWarnings="true" />
- </Target>
</Project>
\ No newline at end of file
--
2.32.1 (Apple Git-133)

\ No newline at end of file
--
2.32.1 (Apple Git-133)
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
From 863a0a7badf3919c4a710df67e98dbf5db0a2690 Mon Sep 17 00:00:00 2001
From: David Benjamin <davidben@google.com>
Date: Tue, 20 Dec 2022 10:36:19 -0500
Subject: [PATCH 28/28] Fix ssl DER EOF detection for openssl 3.5.7

In PEM, we need to parse until error and then suppress
PEM_R_NO_START_LINE, because PEM allows arbitrary leading and trailing
data. DER, however, does not. Parsing until error and suppressing
ASN1_R_HEADER_TOO_LONG doesn't quite work because that error also
covers some cases that should be rejected.

Instead, check BIO_eof early and stop the loop that way.

Backported for OpenSSL 3.5.7 compatibility on Windows (openssl 3.5.7
returns ASN1_R_NOT_ENOUGH_DATA at DER EOF instead of ASN1_R_HEADER_TOO_LONG).
---
Lib/test/test_ssl.py | 2 ++
Modules/_ssl.c | 10 ++++++----
2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index d4eb2d2e81..f251dff95c 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -1522,6 +1522,8 @@ class ContextTests(unittest.TestCase):
"not enough data: cadata does not contain a certificate"
):
ctx.load_verify_locations(cadata=b"broken")
+ with self.assertRaises(ssl.SSLError):
+ ctx.load_verify_locations(cadata=cacert_der + b"A")

@unittest.skipIf(Py_DEBUG_WIN32, "Avoid mixing debug/release CRT on Windows")
def test_load_dh_params(self):
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index 8f03a846ae..c740decd66 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -3951,7 +3951,7 @@ _add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len,
{
BIO *biobuf = NULL;
X509_STORE *store;
- int retval = -1, err, loaded = 0;
+ int retval = -1, err, loaded = 0, was_bio_eof = 0;

assert(filetype == SSL_FILETYPE_ASN1 || filetype == SSL_FILETYPE_PEM);

@@ -3979,6 +3979,10 @@ _add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len,
int r;

if (filetype == SSL_FILETYPE_ASN1) {
+ if (BIO_eof(biobuf)) {
+ was_bio_eof = 1;
+ break;
+ }
cert = d2i_X509_bio(biobuf, NULL);
} else {
cert = PEM_read_bio_X509(biobuf, NULL,
@@ -4014,9 +4018,7 @@ _add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len,
}
_setSSLError(get_state_ctx(self), msg, 0, __FILE__, __LINE__);
retval = -1;
- } else if ((filetype == SSL_FILETYPE_ASN1) &&
- (ERR_GET_LIB(err) == ERR_LIB_ASN1) &&
- (ERR_GET_REASON(err) == ASN1_R_HEADER_TOO_LONG)) {
+ } else if ((filetype == SSL_FILETYPE_ASN1) && was_bio_eof) {
/* EOF ASN1 file, not an error */
ERR_clear_error();
retval = 0;
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Christian Heimes <christian@python.org>
Date: Sat, 27 Nov 2021 21:41:18 +0100
Subject: [PATCH 29/29] Fix ctypes fielddesc init for external libffi

Backport https://github.com/python/cpython/pull/29791 (bpo-45898) for
Windows builds that link against an external libffi DLL instead of the
vendored copy. Delay fielddesc initialization and remove duplicate
ffi_type definitions from cfield.c. (FFI_BUILDING is replaced with
USING_MALLOC_CLOSURE_DOT_C=1 in 0015-Doing-d1trimfile.patch.)
---
diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c
index 534ec94..240b73c 100644
--- a/Modules/_ctypes/cfield.c
+++ b/Modules/_ctypes/cfield.c
@@ -1473,55 +1473,40 @@ P_get(void *ptr, Py_ssize_t size)
}

static struct fielddesc formattable[] = {
- { 's', s_set, s_get, &ffi_type_pointer},
- { 'b', b_set, b_get, &ffi_type_schar},
- { 'B', B_set, B_get, &ffi_type_uchar},
- { 'c', c_set, c_get, &ffi_type_schar},
- { 'd', d_set, d_get, &ffi_type_double, d_set_sw, d_get_sw},
- { 'g', g_set, g_get, &ffi_type_longdouble},
- { 'f', f_set, f_get, &ffi_type_float, f_set_sw, f_get_sw},
- { 'h', h_set, h_get, &ffi_type_sshort, h_set_sw, h_get_sw},
- { 'H', H_set, H_get, &ffi_type_ushort, H_set_sw, H_get_sw},
- { 'i', i_set, i_get, &ffi_type_sint, i_set_sw, i_get_sw},
- { 'I', I_set, I_get, &ffi_type_uint, I_set_sw, I_get_sw},
-/* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */
-/* As soon as we can get rid of the type codes, this is no longer a problem */
-#if SIZEOF_LONG == 4
- { 'l', l_set, l_get, &ffi_type_sint32, l_set_sw, l_get_sw},
- { 'L', L_set, L_get, &ffi_type_uint32, L_set_sw, L_get_sw},
-#elif SIZEOF_LONG == 8
- { 'l', l_set, l_get, &ffi_type_sint64, l_set_sw, l_get_sw},
- { 'L', L_set, L_get, &ffi_type_uint64, L_set_sw, L_get_sw},
-#else
-# error
-#endif
-#if SIZEOF_LONG_LONG == 8
- { 'q', q_set, q_get, &ffi_type_sint64, q_set_sw, q_get_sw},
- { 'Q', Q_set, Q_get, &ffi_type_uint64, Q_set_sw, Q_get_sw},
-#else
-# error
-#endif
- { 'P', P_set, P_get, &ffi_type_pointer},
- { 'z', z_set, z_get, &ffi_type_pointer},
- { 'u', u_set, u_get, NULL}, /* ffi_type set later */
- { 'U', U_set, U_get, &ffi_type_pointer},
- { 'Z', Z_set, Z_get, &ffi_type_pointer},
+ { 's', s_set, s_get, NULL},
+ { 'b', b_set, b_get, NULL},
+ { 'B', B_set, B_get, NULL},
+ { 'c', c_set, c_get, NULL},
+ { 'd', d_set, d_get, NULL, d_set_sw, d_get_sw},
+ { 'g', g_set, g_get, NULL},
+ { 'f', f_set, f_get, NULL, f_set_sw, f_get_sw},
+ { 'h', h_set, h_get, NULL, h_set_sw, h_get_sw},
+ { 'H', H_set, H_get, NULL, H_set_sw, H_get_sw},
+ { 'i', i_set, i_get, NULL, i_set_sw, i_get_sw},
+ { 'I', I_set, I_get, NULL, I_set_sw, I_get_sw},
+ { 'l', l_set, l_get, NULL, l_set_sw, l_get_sw},
+ { 'L', L_set, L_get, NULL, L_set_sw, L_get_sw},
+ { 'q', q_set, q_get, NULL, q_set_sw, q_get_sw},
+ { 'Q', Q_set, Q_get, NULL, Q_set_sw, Q_get_sw},
+ { 'P', P_set, P_get, NULL},
+ { 'z', z_set, z_get, NULL},
+ { 'u', u_set, u_get, NULL},
+ { 'U', U_set, U_get, NULL},
+ { 'Z', Z_set, Z_get, NULL},
#ifdef MS_WIN32
- { 'X', BSTR_set, BSTR_get, &ffi_type_pointer},
+ { 'X', BSTR_set, BSTR_get, NULL},
#endif
- { 'v', vBOOL_set, vBOOL_get, &ffi_type_sshort},
-#if SIZEOF__BOOL == 1
- { '?', bool_set, bool_get, &ffi_type_uchar}, /* Also fallback for no native _Bool support */
-#elif SIZEOF__BOOL == SIZEOF_SHORT
- { '?', bool_set, bool_get, &ffi_type_ushort},
-#elif SIZEOF__BOOL == SIZEOF_INT
- { '?', bool_set, bool_get, &ffi_type_uint, I_set_sw, I_get_sw},
+ { 'v', vBOOL_set, vBOOL_get, NULL},
+#if SIZEOF__BOOL == SIZEOF_INT
+ { '?', bool_set, bool_get, NULL, I_set_sw, I_get_sw},
#elif SIZEOF__BOOL == SIZEOF_LONG
- { '?', bool_set, bool_get, &ffi_type_ulong, L_set_sw, L_get_sw},
+ { '?', bool_set, bool_get, NULL, L_set_sw, L_get_sw},
#elif SIZEOF__BOOL == SIZEOF_LONG_LONG
- { '?', bool_set, bool_get, &ffi_type_ulong, Q_set_sw, Q_get_sw},
+ { '?', bool_set, bool_get, NULL, Q_set_sw, Q_get_sw},
+#else
+ { '?', bool_set, bool_get, NULL},
#endif /* SIZEOF__BOOL */
- { 'O', O_set, O_get, &ffi_type_pointer},
+ { 'O', O_set, O_get, NULL},
{ 0, NULL, NULL, NULL},
};

@@ -1530,6 +1515,79 @@ static struct fielddesc formattable[] = {
Use '?' as code for BOOL.
*/

+/* Delayed initialization. Windows cannot statically reference dynamically
+ loaded addresses from DLLs. */
+void
+_ctypes_init_fielddesc(void)
+{
+ struct fielddesc *fd = formattable;
+ for (; fd->code; ++fd) {
+ switch (fd->code) {
+ case 's': fd->pffi_type = &ffi_type_pointer; break;
+ case 'b': fd->pffi_type = &ffi_type_schar; break;
+ case 'B': fd->pffi_type = &ffi_type_uchar; break;
+ case 'c': fd->pffi_type = &ffi_type_schar; break;
+ case 'd': fd->pffi_type = &ffi_type_double; break;
+ case 'g': fd->pffi_type = &ffi_type_longdouble; break;
+ case 'f': fd->pffi_type = &ffi_type_float; break;
+ case 'h': fd->pffi_type = &ffi_type_sshort; break;
+ case 'H': fd->pffi_type = &ffi_type_ushort; break;
+ case 'i': fd->pffi_type = &ffi_type_sint; break;
+ case 'I': fd->pffi_type = &ffi_type_uint; break;
+ /* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */
+ /* As soon as we can get rid of the type codes, this is no longer a problem */
+ #if SIZEOF_LONG == 4
+ case 'l': fd->pffi_type = &ffi_type_sint32; break;
+ case 'L': fd->pffi_type = &ffi_type_uint32; break;
+ #elif SIZEOF_LONG == 8
+ case 'l': fd->pffi_type = &ffi_type_sint64; break;
+ case 'L': fd->pffi_type = &ffi_type_uint64; break;
+ #else
+ #error
+ #endif
+ #if SIZEOF_LONG_LONG == 8
+ case 'q': fd->pffi_type = &ffi_type_sint64; break;
+ case 'Q': fd->pffi_type = &ffi_type_uint64; break;
+ #else
+ #error
+ #endif
+ case 'P': fd->pffi_type = &ffi_type_pointer; break;
+ case 'z': fd->pffi_type = &ffi_type_pointer; break;
+ case 'u':
+ if (sizeof(wchar_t) == sizeof(short))
+ fd->pffi_type = &ffi_type_sshort;
+ else if (sizeof(wchar_t) == sizeof(int))
+ fd->pffi_type = &ffi_type_sint;
+ else if (sizeof(wchar_t) == sizeof(long))
+ fd->pffi_type = &ffi_type_slong;
+ else
+ Py_UNREACHABLE();
+ break;
+ case 'U': fd->pffi_type = &ffi_type_pointer; break;
+ case 'Z': fd->pffi_type = &ffi_type_pointer; break;
+ #ifdef MS_WIN32
+ case 'X': fd->pffi_type = &ffi_type_pointer; break;
+ #endif
+ case 'v': fd->pffi_type = &ffi_type_sshort; break;
+ #if SIZEOF__BOOL == 1
+ case '?': fd->pffi_type = &ffi_type_uchar; break; /* Also fallback for no native _Bool support */
+ #elif SIZEOF__BOOL == SIZEOF_SHORT
+ case '?': fd->pffi_type = &ffi_type_ushort; break;
+ #elif SIZEOF__BOOL == SIZEOF_INT
+ case '?': fd->pffi_type = &ffi_type_uint; break;
+ #elif SIZEOF__BOOL == SIZEOF_LONG
+ case '?': fd->pffi_type = &ffi_type_ulong; break;
+ #elif SIZEOF__BOOL == SIZEOF_LONG_LONG
+ case '?': fd->pffi_type = &ffi_type_ulong; break;
+ #endif /* SIZEOF__BOOL */
+ case 'O': fd->pffi_type = &ffi_type_pointer; break;
+ default:
+ Py_UNREACHABLE();
+ }
+ }
+
+}
+
struct fielddesc *
_ctypes_get_fielddesc(const char *fmt)
{
@@ -1538,12 +1596,7 @@ _ctypes_get_fielddesc(const char *fmt)

if (!initialized) {
initialized = 1;
- if (sizeof(wchar_t) == sizeof(short))
- _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sshort;
- else if (sizeof(wchar_t) == sizeof(int))
- _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sint;
- else if (sizeof(wchar_t) == sizeof(long))
- _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_slong;
+ _ctypes_init_fielddesc();
}

for (; table->code; ++table) {
@@ -1553,77 +1606,4 @@ _ctypes_get_fielddesc(const char *fmt)
return NULL;
}

-typedef struct { char c; char x; } s_char;
-typedef struct { char c; short x; } s_short;
-typedef struct { char c; int x; } s_int;
-typedef struct { char c; long x; } s_long;
-typedef struct { char c; float x; } s_float;
-typedef struct { char c; double x; } s_double;
-typedef struct { char c; long double x; } s_long_double;
-typedef struct { char c; char *x; } s_char_p;
-typedef struct { char c; void *x; } s_void_p;
-
-/*
-#define CHAR_ALIGN (sizeof(s_char) - sizeof(char))
-#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
-#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
-*/
-#define INT_ALIGN (sizeof(s_int) - sizeof(int))
-#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
-#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
-#define LONGDOUBLE_ALIGN (sizeof(s_long_double) - sizeof(long double))
-
-/* #define CHAR_P_ALIGN (sizeof(s_char_p) - sizeof(char*)) */
-#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void*))
-
-/*
-#ifdef HAVE_USABLE_WCHAR_T
-typedef struct { char c; wchar_t x; } s_wchar;
-typedef struct { char c; wchar_t *x; } s_wchar_p;
-
-#define WCHAR_ALIGN (sizeof(s_wchar) - sizeof(wchar_t))
-#define WCHAR_P_ALIGN (sizeof(s_wchar_p) - sizeof(wchar_t*))
-#endif
-*/
-
-typedef struct { char c; long long x; } s_long_long;
-#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long))
-
-/* from ffi.h:
-typedef struct _ffi_type
-{
- size_t size;
- unsigned short alignment;
- unsigned short type;
- struct _ffi_type **elements;
-} ffi_type;
-*/
-
-/* align and size are bogus for void, but they must not be zero */
-ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID };
-
-ffi_type ffi_type_uint8 = { 1, 1, FFI_TYPE_UINT8 };
-ffi_type ffi_type_sint8 = { 1, 1, FFI_TYPE_SINT8 };
-
-ffi_type ffi_type_uint16 = { 2, 2, FFI_TYPE_UINT16 };
-ffi_type ffi_type_sint16 = { 2, 2, FFI_TYPE_SINT16 };
-
-ffi_type ffi_type_uint32 = { 4, INT_ALIGN, FFI_TYPE_UINT32 };
-ffi_type ffi_type_sint32 = { 4, INT_ALIGN, FFI_TYPE_SINT32 };
-
-ffi_type ffi_type_uint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_UINT64 };
-ffi_type ffi_type_sint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_SINT64 };
-
-ffi_type ffi_type_float = { sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT };
-ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE };
-
-#ifdef ffi_type_longdouble
-#undef ffi_type_longdouble
-#endif
- /* This is already defined on OSX */
-ffi_type ffi_type_longdouble = { sizeof(long double), LONGDOUBLE_ALIGN,
- FFI_TYPE_LONGDOUBLE };
-
-ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER };
-
/*---------------- EOF ----------------*/
6 changes: 6 additions & 0 deletions recipe/run_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,9 @@
print('OPENSSL_VERSION:', ssl.OPENSSL_VERSION)
CONDA_OPENSSL_VERSION = os.getenv("openssl")
assert CONDA_OPENSSL_VERSION in ssl.OPENSSL_VERSION
# xref https://github.com/conda-forge/openssl-feedstock/issues/237
from pathlib import Path
pem = Path(__file__).with_name("test-cert.pem").read_text()
der = ssl.PEM_cert_to_DER_cert(pem)
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.load_verify_locations(cadata=der)
Loading