Skip to content

Commit 974f00b

Browse files
miss-islingtonstratakis
authored andcommitted
00361: openssl-3-compatibility
Backported from Python 3.8 Based on https://github.com/stratakis/cpython/tree/fedora-3.6_openssl3_compat Some fixes
1 parent 331f3bb commit 974f00b

17 files changed

+15289
-170
lines changed

Doc/library/hashlib.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,10 @@ More condensed:
109109

110110
Using :func:`new` with an algorithm provided by OpenSSL:
111111

112-
>>> h = hashlib.new('ripemd160')
112+
>>> h = hashlib.new('sha512_256')
113113
>>> h.update(b"Nobody inspects the spammish repetition")
114114
>>> h.hexdigest()
115-
'cc4a5ce1b3df48aec5d22d1f16b894a0b894eccc'
115+
'19197dc4d03829df858011c6c87600f994a858103bbc19005f20987aa19a97e2'
116116

117117
Hashlib provides the following constant attributes:
118118

Doc/library/ssl.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,14 @@ Constants
844844

845845
.. versionadded:: 3.6
846846

847+
.. data:: OP_IGNORE_UNEXPECTED_EOF
848+
849+
Ignore unexpected shutdown of TLS connections.
850+
851+
This option is only available with OpenSSL 3.0.0 and later.
852+
853+
.. versionadded:: 3..6.15-27
854+
847855
.. data:: HAS_ALPN
848856

849857
Whether the OpenSSL library has built-in support for the *Application-Layer
@@ -1143,6 +1151,9 @@ SSL sockets also have the following additional methods and attributes:
11431151
The returned dictionary includes additional X509v3 extension items
11441152
such as ``crlDistributionPoints``, ``caIssuers`` and ``OCSP`` URIs.
11451153

1154+
.. versionchanged:: 3.6.15-27
1155+
IPv6 address strings no longer have a trailing new line.
1156+
11461157
.. method:: SSLSocket.cipher()
11471158

11481159
Returns a three-value tuple containing the name of the cipher being used, the

Lib/test/test_ssl.py

Lines changed: 89 additions & 60 deletions
Large diffs are not rendered by default.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Make Python compatible with OpenSSL 3.0.0. :func:`ssl.SSLSocket.getpeercert`
2+
no longer returns IPv6 addresses with a trailing new line.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
The header files for :mod:`ssl` error codes are now OpenSSL
2+
version-specific. Exceptions will now show correct reason and library
3+
codes. The ``make_ssl_data.py`` script has been rewritten to use OpenSSL's
4+
text file with error codes.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
OpenSSL 3.0.0: Don't call the password callback function a second time when
2+
first call has signaled an error condition.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add :data:`ssl.OP_IGNORE_UNEXPECTED_EOF` constants (OpenSSL 3.0.0)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
OpenSSL 3.0.0: :meth:`~ssl.SSLContext.load_verify_locations` now returns a
2+
consistent error message when cadata contains no valid certificate.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
OpenSSL 3.0.0: Disable testing of legacy protocols TLS 1.0 and 1.1. Tests
2+
are failing with TLSV1_ALERT_INTERNAL_ERROR.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix test case for OpenSSL 3.0.1 version. OpenSSL 3.0 uses ``0xMNN00PP0L``.

Modules/_hashopenssl.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
364364
return -1;
365365
}
366366

367-
digest = EVP_get_digestbyname(nameStr);
367+
digest = EVP_MD_fetch(NULL, nameStr, NULL);
368368
if (!digest) {
369369
PyErr_SetString(PyExc_ValueError, "unknown hash function");
370370
if (data_obj)
@@ -529,7 +529,7 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
529529
if (data_obj)
530530
GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view);
531531

532-
digest = EVP_get_digestbyname(name);
532+
digest = EVP_MD_fetch(NULL, name, NULL);
533533

534534
ret_obj = EVPnew(name_obj, digest, NULL, (unsigned char*)view.buf, view.len);
535535

@@ -654,7 +654,7 @@ pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict)
654654
return NULL;
655655
}
656656

657-
digest = EVP_get_digestbyname(name);
657+
digest = EVP_MD_fetch(NULL, name, NULL);
658658
if (digest == NULL) {
659659
PyErr_SetString(PyExc_ValueError, "unsupported hash type");
660660
goto end;
@@ -941,8 +941,8 @@ generate_hash_name_list(void)
941941
\
942942
if (CONST_new_ ## NAME ## _ctx_p == NULL) { \
943943
EVP_MD_CTX *ctx_p = EVP_MD_CTX_new(); \
944-
if (!EVP_get_digestbyname(#NAME) || \
945-
!EVP_DigestInit(ctx_p, EVP_get_digestbyname(#NAME))) { \
944+
if (!EVP_MD_fetch(NULL, #NAME, NULL) || \
945+
!EVP_DigestInit(ctx_p, EVP_MD_fetch(NULL, #NAME, NULL))) { \
946946
_setException(PyExc_ValueError); \
947947
EVP_MD_CTX_free(ctx_p); \
948948
return NULL; \

Modules/_ssl.c

Lines changed: 85 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,13 @@ struct py_ssl_library_code {
103103
};
104104

105105
/* Include generated data (error codes) */
106+
#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
107+
#include "_ssl_data_300.h"
108+
#elif (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER)
109+
#include "_ssl_data_111.h"
110+
#else
106111
#include "_ssl_data.h"
112+
#endif
107113

108114
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
109115
# define OPENSSL_VERSION_1_1 1
@@ -1204,14 +1210,61 @@ _get_peer_alt_names (X509 *certificate) {
12041210
PyTuple_SET_ITEM(t, 1, v);
12051211
break;
12061212

1213+
case GEN_IPADD:
1214+
/* OpenSSL < 3.0.0 adds a trailing \n to IPv6. 3.0.0 removed
1215+
* the trailing newline. Remove it in all versions
1216+
*/
1217+
t = PyTuple_New(2);
1218+
if (t == NULL)
1219+
goto fail;
1220+
1221+
v = PyUnicode_FromString("IP Address");
1222+
if (v == NULL) {
1223+
Py_DECREF(t);
1224+
goto fail;
1225+
}
1226+
PyTuple_SET_ITEM(t, 0, v);
1227+
1228+
if (name->d.ip->length == 4) {
1229+
unsigned char *p = name->d.ip->data;
1230+
v = PyUnicode_FromFormat(
1231+
"%d.%d.%d.%d",
1232+
p[0], p[1], p[2], p[3]
1233+
);
1234+
} else if (name->d.ip->length == 16) {
1235+
/* PyUnicode_FromFormat() does not support %X */
1236+
unsigned char *p = name->d.ip->data;
1237+
len = sprintf(
1238+
buf,
1239+
"%X:%X:%X:%X:%X:%X:%X:%X",
1240+
p[0] << 8 | p[1],
1241+
p[2] << 8 | p[3],
1242+
p[4] << 8 | p[5],
1243+
p[6] << 8 | p[7],
1244+
p[8] << 8 | p[9],
1245+
p[10] << 8 | p[11],
1246+
p[12] << 8 | p[13],
1247+
p[14] << 8 | p[15]
1248+
);
1249+
v = PyUnicode_FromStringAndSize(buf, len);
1250+
} else {
1251+
v = PyUnicode_FromString("<invalid>");
1252+
}
1253+
1254+
if (v == NULL) {
1255+
Py_DECREF(t);
1256+
goto fail;
1257+
}
1258+
PyTuple_SET_ITEM(t, 1, v);
1259+
break;
1260+
12071261
default:
12081262
/* for everything else, we use the OpenSSL print form */
12091263
switch (gntype) {
12101264
/* check for new general name type */
12111265
case GEN_OTHERNAME:
12121266
case GEN_X400:
12131267
case GEN_EDIPARTY:
1214-
case GEN_IPADD:
12151268
case GEN_RID:
12161269
break;
12171270
default:
@@ -2880,6 +2933,10 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
28802933
#endif
28812934
#ifdef SSL_OP_SINGLE_ECDH_USE
28822935
options |= SSL_OP_SINGLE_ECDH_USE;
2936+
#endif
2937+
#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
2938+
/* Make OpenSSL 3.0.0 behave like 1.1.1 */
2939+
options |= SSL_OP_IGNORE_UNEXPECTED_EOF;
28832940
#endif
28842941
SSL_CTX_set_options(self->ctx, options);
28852942

@@ -3441,6 +3498,13 @@ _password_callback(char *buf, int size, int rwflag, void *userdata)
34413498

34423499
PySSL_END_ALLOW_THREADS_S(pw_info->thread_state);
34433500

3501+
if (pw_info->error) {
3502+
/* already failed previously. OpenSSL 3.0.0-alpha14 invokes the
3503+
* callback multiple times which can lead to fatal Python error in
3504+
* exception check. */
3505+
goto error;
3506+
}
3507+
34443508
if (pw_info->callable) {
34453509
fn_ret = PyObject_CallFunctionObjArgs(pw_info->callable, NULL);
34463510
if (!fn_ret) {
@@ -3584,7 +3648,7 @@ _add_ca_certs(PySSLContext *self, void *data, Py_ssize_t len,
35843648
{
35853649
BIO *biobuf = NULL;
35863650
X509_STORE *store;
3587-
int retval = 0, err, loaded = 0;
3651+
int retval = -1, err, loaded = 0;
35883652

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

@@ -3638,23 +3702,32 @@ _add_ca_certs(PySSLContext *self, void *data, Py_ssize_t len,
36383702
}
36393703

36403704
err = ERR_peek_last_error();
3641-
if ((filetype == SSL_FILETYPE_ASN1) &&
3642-
(loaded > 0) &&
3643-
(ERR_GET_LIB(err) == ERR_LIB_ASN1) &&
3644-
(ERR_GET_REASON(err) == ASN1_R_HEADER_TOO_LONG)) {
3705+
if (loaded == 0) {
3706+
const char *msg = NULL;
3707+
if (filetype == SSL_FILETYPE_PEM) {
3708+
msg = "no start line: cadata does not contain a certificate";
3709+
} else {
3710+
msg = "not enough data: cadata does not contain a certificate";
3711+
}
3712+
_setSSLError(msg, 0, __FILE__, __LINE__);
3713+
retval = -1;
3714+
} else if ((filetype == SSL_FILETYPE_ASN1) &&
3715+
(ERR_GET_LIB(err) == ERR_LIB_ASN1) &&
3716+
(ERR_GET_REASON(err) == ASN1_R_HEADER_TOO_LONG)) {
36453717
/* EOF ASN1 file, not an error */
36463718
ERR_clear_error();
36473719
retval = 0;
36483720
} else if ((filetype == SSL_FILETYPE_PEM) &&
3649-
(loaded > 0) &&
36503721
(ERR_GET_LIB(err) == ERR_LIB_PEM) &&
36513722
(ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
36523723
/* EOF PEM file, not an error */
36533724
ERR_clear_error();
36543725
retval = 0;
3655-
} else {
3726+
} else if (err != 0) {
36563727
_setSSLError(NULL, 0, __FILE__, __LINE__);
36573728
retval = -1;
3729+
} else {
3730+
retval = 0;
36583731
}
36593732

36603733
BIO_free(biobuf);
@@ -5637,6 +5710,10 @@ PyInit__ssl(void)
56375710
PyModule_AddIntConstant(m, "OP_ENABLE_MIDDLEBOX_COMPAT",
56385711
SSL_OP_ENABLE_MIDDLEBOX_COMPAT);
56395712
#endif
5713+
#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
5714+
PyModule_AddIntConstant(m, "OP_IGNORE_UNEXPECTED_EOF",
5715+
SSL_OP_IGNORE_UNEXPECTED_EOF);
5716+
#endif
56405717

56415718
#if HAVE_SNI
56425719
r = Py_True;

0 commit comments

Comments
 (0)