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
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix :mod:`ssl` code to be compatible with OpenSSL 1.1.x builds that use
``no-deprecated`` and ``--api=1.1.0``.
56 changes: 45 additions & 11 deletions Modules/_ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,24 @@ static void _PySSLFixErrno(void) {
# define PY_OPENSSL_1_1_API 1
#endif

/* OpenSSL API compat */
#ifdef OPENSSL_API_COMPAT
#if OPENSSL_API_COMPAT >= 0x10100000L

/* OpenSSL API 1.1.0+ does not include version methods */
#ifndef OPENSSL_NO_TLS1_METHOD
#define OPENSSL_NO_TLS1_METHOD 1
#endif
#ifndef OPENSSL_NO_TLS1_1_METHOD
#define OPENSSL_NO_TLS1_1_METHOD 1
#endif
#ifndef OPENSSL_NO_TLS1_2_METHOD
#define OPENSSL_NO_TLS1_2_METHOD 1
#endif

#endif /* >= 1.1.0 compcat */
#endif /* OPENSSL_API_COMPAT */

/* LibreSSL 2.7.0 provides necessary OpenSSL 1.1.0 APIs */
#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x2070000fL
# define PY_OPENSSL_1_1_API 1
Expand Down Expand Up @@ -201,6 +219,12 @@ static void _PySSLFixErrno(void) {
#define TLS_method SSLv23_method
#define TLS_client_method SSLv23_client_method
#define TLS_server_method SSLv23_server_method
#define ASN1_STRING_get0_data ASN1_STRING_data
#define X509_get0_notBefore X509_get_notBefore
#define X509_get0_notAfter X509_get_notAfter
#define OpenSSL_version_num SSLeay
#define OpenSSL_version SSLeay_version
#define OPENSSL_VERSION SSLEAY_VERSION

static int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne)
{
Expand Down Expand Up @@ -885,7 +909,7 @@ _ssl_configure_hostname(PySSLSocket *self, const char* server_hostname)
goto error;
}
} else {
if (!X509_VERIFY_PARAM_set1_ip(param, ASN1_STRING_data(ip),
if (!X509_VERIFY_PARAM_set1_ip(param, ASN1_STRING_get0_data(ip),
ASN1_STRING_length(ip))) {
_setSSLError(NULL, 0, __FILE__, __LINE__);
goto error;
Expand Down Expand Up @@ -1361,7 +1385,7 @@ _get_peer_alt_names (X509 *certificate) {
goto fail;
}
PyTuple_SET_ITEM(t, 0, v);
v = PyUnicode_FromStringAndSize((char *)ASN1_STRING_data(as),
v = PyUnicode_FromStringAndSize((char *)ASN1_STRING_get0_data(as),
ASN1_STRING_length(as));
if (v == NULL) {
Py_DECREF(t);
Expand Down Expand Up @@ -1657,7 +1681,7 @@ _decode_certificate(X509 *certificate) {
ASN1_INTEGER *serialNumber;
char buf[2048];
int len, result;
ASN1_TIME *notBefore, *notAfter;
const ASN1_TIME *notBefore, *notAfter;
PyObject *pnotBefore, *pnotAfter;

retval = PyDict_New();
Expand Down Expand Up @@ -1719,7 +1743,7 @@ _decode_certificate(X509 *certificate) {
Py_DECREF(sn_obj);

(void) BIO_reset(biobuf);
notBefore = X509_get_notBefore(certificate);
notBefore = X509_get0_notBefore(certificate);
ASN1_TIME_print(biobuf, notBefore);
len = BIO_gets(biobuf, buf, sizeof(buf)-1);
if (len < 0) {
Expand All @@ -1736,7 +1760,7 @@ _decode_certificate(X509 *certificate) {
Py_DECREF(pnotBefore);

(void) BIO_reset(biobuf);
notAfter = X509_get_notAfter(certificate);
notAfter = X509_get0_notAfter(certificate);
ASN1_TIME_print(biobuf, notAfter);
len = BIO_gets(biobuf, buf, sizeof(buf)-1);
if (len < 0) {
Expand Down Expand Up @@ -3079,17 +3103,23 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
ctx = SSL_CTX_new(SSLv3_method());
break;
#endif
#if defined(TLS1_VERSION) && !defined(OPENSSL_NO_TLS1)
#if (defined(TLS1_VERSION) && \
!defined(OPENSSL_NO_TLS1) && \
!defined(OPENSSL_NO_TLS1_METHOD))
case PY_SSL_VERSION_TLS1:
ctx = SSL_CTX_new(TLSv1_method());
break;
#endif
#if defined(TLS1_1_VERSION) && !defined(OPENSSL_NO_TLS1_1)
#if (defined(TLS1_1_VERSION) && \
!defined(OPENSSL_NO_TLS1_1) && \
!defined(OPENSSL_NO_TLS1_1_METHOD))
case PY_SSL_VERSION_TLS1_1:
ctx = SSL_CTX_new(TLSv1_1_method());
break;
#endif
#if defined(TLS1_2_VERSION) && !defined(OPENSSL_NO_TLS1_2)
#if (defined(TLS1_2_VERSION) && \
!defined(OPENSSL_NO_TLS1_2) && \
!defined(OPENSSL_NO_TLS1_2_METHOD))
case PY_SSL_VERSION_TLS1_2:
ctx = SSL_CTX_new(TLSv1_2_method());
break;
Expand Down Expand Up @@ -3207,7 +3237,7 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
conservative and assume it wasn't fixed until release. We do this check
at runtime to avoid problems from the dynamic linker.
See #25672 for more on this. */
libver = SSLeay();
libver = OpenSSL_version_num();
if (!(libver >= 0x10001000UL && libver < 0x1000108fUL) &&
!(libver >= 0x10000000UL && libver < 0x100000dfUL)) {
SSL_CTX_set_mode(self->ctx, SSL_MODE_RELEASE_BUFFERS);
Expand Down Expand Up @@ -5286,7 +5316,11 @@ PySSL_RAND(int len, int pseudo)
if (bytes == NULL)
return NULL;
if (pseudo) {
#ifdef PY_OPENSSL_1_1_API
ok = RAND_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len);
#else
ok = RAND_pseudo_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len);
#endif
if (ok == 0 || ok == 1)
return Py_BuildValue("NO", bytes, ok == 1 ? Py_True : Py_False);
}
Expand Down Expand Up @@ -6373,7 +6407,7 @@ PyInit__ssl(void)
/* SSLeay() gives us the version of the library linked against,
which could be different from the headers version.
*/
libver = SSLeay();
libver = OpenSSL_version_num();
r = PyLong_FromUnsignedLong(libver);
if (r == NULL)
return NULL;
Expand All @@ -6383,7 +6417,7 @@ PyInit__ssl(void)
r = Py_BuildValue("IIIII", major, minor, fix, patch, status);
if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION_INFO", r))
return NULL;
r = PyUnicode_FromString(SSLeay_version(SSLEAY_VERSION));
r = PyUnicode_FromString(OpenSSL_version(OPENSSL_VERSION));
if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION", r))
return NULL;

Expand Down
1 change: 1 addition & 0 deletions Tools/ssl/multissltests.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ def _build_src(self):
"shared", "--debug",
"--prefix={}".format(self.install_dir)
]
# cmd.extend(["no-deprecated", "--api=1.1.0"])
env = os.environ.copy()
# set rpath
env["LD_RUN_PATH"] = self.lib_dir
Expand Down