summaryrefslogtreecommitdiffstats
path: root/Modules/_ssl.c
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2023-07-17 15:55:30 (GMT)
committerGitHub <noreply@github.com>2023-07-17 15:55:30 (GMT)
commitad95c7253a70e559e7d3f25d53f4772f28bb8b44 (patch)
treef64578e483489c7c2ea93b3e4bf9f1cd3e285742 /Modules/_ssl.c
parent036bb7365607ab7e5cf901f1ac4256f9ae1be82c (diff)
downloadcpython-ad95c7253a70e559e7d3f25d53f4772f28bb8b44.zip
cpython-ad95c7253a70e559e7d3f25d53f4772f28bb8b44.tar.gz
cpython-ad95c7253a70e559e7d3f25d53f4772f28bb8b44.tar.bz2
gh-106687: _ssl: use uint64_t for SSL options (#106700)
SSL_CTX_get_options() uses uint64_t for options: https://www.openssl.org/docs/man3.1/man3/SSL_CTX_get_options.html Fix this compiler warning on Windows with MSC: conversion from 'uint64_t' to 'long', possible loss of data
Diffstat (limited to 'Modules/_ssl.c')
-rw-r--r--Modules/_ssl.c80
1 files changed, 54 insertions, 26 deletions
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index 571de33..0cf4d3e 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -3025,7 +3025,7 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
/*[clinic end generated code: output=2cf0d7a0741b6bd1 input=8d58a805b95fc534]*/
{
PySSLContext *self;
- long options;
+ uint64_t options;
const SSL_METHOD *method = NULL;
SSL_CTX *ctx = NULL;
X509_VERIFY_PARAM *params;
@@ -3618,20 +3618,32 @@ PyDoc_STRVAR(PySSLContext_security_level_doc, "The current security level");
static PyObject *
get_options(PySSLContext *self, void *c)
{
- return PyLong_FromLong(SSL_CTX_get_options(self->ctx));
+ uint64_t options = SSL_CTX_get_options(self->ctx);
+ Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(options));
+ return PyLong_FromUnsignedLongLong(options);
}
static int
set_options(PySSLContext *self, PyObject *arg, void *c)
{
- long new_opts, opts, set, clear;
- long opt_no = (
+ PyObject *new_opts_obj;
+ unsigned long long new_opts_arg;
+ uint64_t new_opts, opts, clear, set;
+ uint64_t opt_no = (
SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 |
SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_3
);
- if (!PyArg_Parse(arg, "l", &new_opts))
+ if (!PyArg_Parse(arg, "O!", &PyLong_Type, &new_opts_obj)) {
return -1;
+ }
+ new_opts_arg = PyLong_AsUnsignedLongLong(new_opts_obj);
+ if (new_opts_arg == (unsigned long long)-1 && PyErr_Occurred()) {
+ return -1;
+ }
+ Py_BUILD_ASSERT(sizeof(new_opts) >= sizeof(new_opts_arg));
+ new_opts = (uint64_t)new_opts_arg;
+
opts = SSL_CTX_get_options(self->ctx);
clear = opts & ~new_opts;
set = ~opts & new_opts;
@@ -3645,8 +3657,9 @@ set_options(PySSLContext *self, PyObject *arg, void *c)
if (clear) {
SSL_CTX_clear_options(self->ctx, clear);
}
- if (set)
+ if (set) {
SSL_CTX_set_options(self->ctx, set);
+ }
return 0;
}
@@ -5754,10 +5767,24 @@ sslmodule_init_socketapi(PyObject *module)
return 0;
}
+
static int
-sslmodule_init_constants(PyObject *m)
+sslmodule_add_option(PyObject *m, const char *name, uint64_t value)
{
+ Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(value));
+ PyObject *obj = PyLong_FromUnsignedLongLong(value);
+ if (obj == NULL) {
+ return -1;
+ }
+ int res = PyModule_AddObjectRef(m, name, obj);
+ Py_DECREF(obj);
+ return res;
+}
+
+static int
+sslmodule_init_constants(PyObject *m)
+{
PyModule_AddStringConstant(m, "_DEFAULT_CIPHERS",
PY_SSL_DEFAULT_CIPHER_STRING);
@@ -5877,46 +5904,47 @@ sslmodule_init_constants(PyObject *m)
PyModule_AddIntConstant(m, "PROTOCOL_TLSv1_2",
PY_SSL_VERSION_TLS1_2);
+#define ADD_OPTION(NAME, VALUE) if (sslmodule_add_option(m, NAME, (VALUE)) < 0) return -1
+
/* protocol options */
- PyModule_AddIntConstant(m, "OP_ALL",
- SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
- PyModule_AddIntConstant(m, "OP_NO_SSLv2", SSL_OP_NO_SSLv2);
- PyModule_AddIntConstant(m, "OP_NO_SSLv3", SSL_OP_NO_SSLv3);
- PyModule_AddIntConstant(m, "OP_NO_TLSv1", SSL_OP_NO_TLSv1);
- PyModule_AddIntConstant(m, "OP_NO_TLSv1_1", SSL_OP_NO_TLSv1_1);
- PyModule_AddIntConstant(m, "OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2);
+ ADD_OPTION("OP_ALL", SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
+ ADD_OPTION("OP_NO_SSLv2", SSL_OP_NO_SSLv2);
+ ADD_OPTION("OP_NO_SSLv3", SSL_OP_NO_SSLv3);
+ ADD_OPTION("OP_NO_TLSv1", SSL_OP_NO_TLSv1);
+ ADD_OPTION("OP_NO_TLSv1_1", SSL_OP_NO_TLSv1_1);
+ ADD_OPTION("OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2);
#ifdef SSL_OP_NO_TLSv1_3
- PyModule_AddIntConstant(m, "OP_NO_TLSv1_3", SSL_OP_NO_TLSv1_3);
+ ADD_OPTION("OP_NO_TLSv1_3", SSL_OP_NO_TLSv1_3);
#else
- PyModule_AddIntConstant(m, "OP_NO_TLSv1_3", 0);
+ ADD_OPTION("OP_NO_TLSv1_3", 0);
#endif
- PyModule_AddIntConstant(m, "OP_CIPHER_SERVER_PREFERENCE",
+ ADD_OPTION("OP_CIPHER_SERVER_PREFERENCE",
SSL_OP_CIPHER_SERVER_PREFERENCE);
- PyModule_AddIntConstant(m, "OP_SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE);
- PyModule_AddIntConstant(m, "OP_NO_TICKET", SSL_OP_NO_TICKET);
- PyModule_AddIntConstant(m, "OP_LEGACY_SERVER_CONNECT",
+ ADD_OPTION("OP_SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE);
+ ADD_OPTION("OP_NO_TICKET", SSL_OP_NO_TICKET);
+ ADD_OPTION("OP_LEGACY_SERVER_CONNECT",
SSL_OP_LEGACY_SERVER_CONNECT);
#ifdef SSL_OP_SINGLE_ECDH_USE
- PyModule_AddIntConstant(m, "OP_SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE);
+ ADD_OPTION("OP_SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE);
#endif
#ifdef SSL_OP_NO_COMPRESSION
- PyModule_AddIntConstant(m, "OP_NO_COMPRESSION",
+ ADD_OPTION("OP_NO_COMPRESSION",
SSL_OP_NO_COMPRESSION);
#endif
#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT
- PyModule_AddIntConstant(m, "OP_ENABLE_MIDDLEBOX_COMPAT",
+ ADD_OPTION("OP_ENABLE_MIDDLEBOX_COMPAT",
SSL_OP_ENABLE_MIDDLEBOX_COMPAT);
#endif
#ifdef SSL_OP_NO_RENEGOTIATION
- PyModule_AddIntConstant(m, "OP_NO_RENEGOTIATION",
+ ADD_OPTION("OP_NO_RENEGOTIATION",
SSL_OP_NO_RENEGOTIATION);
#endif
#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
- PyModule_AddIntConstant(m, "OP_IGNORE_UNEXPECTED_EOF",
+ ADD_OPTION("OP_IGNORE_UNEXPECTED_EOF",
SSL_OP_IGNORE_UNEXPECTED_EOF);
#endif
#ifdef SSL_OP_ENABLE_KTLS
- PyModule_AddIntConstant(m, "OP_ENABLE_KTLS", SSL_OP_ENABLE_KTLS);
+ ADD_OPTION("OP_ENABLE_KTLS", SSL_OP_ENABLE_KTLS);
#endif
#ifdef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT