Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 01d9c23

Browse files
miss-islingtontiran
andcommitted
[3.7] bpo-30622: Improve NPN support detection (GH-5859) (#5860)
The ssl module now detects missing NPN support in LibreSSL. Co-Authored-By: Bernard Spil <[email protected]> Signed-off-by: Christian Heimes <[email protected]> (cherry picked from commit 6cdb795) Co-authored-by: Christian Heimes <[email protected]>
1 parent 8fa8478 commit 01d9c23

File tree

4 files changed

+42
-11
lines changed

4 files changed

+42
-11
lines changed

Doc/library/ssl.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2434,6 +2434,23 @@ successful call of :func:`~ssl.RAND_add`, :func:`~ssl.RAND_bytes` or
24342434
:func:`~ssl.RAND_pseudo_bytes` is sufficient.
24352435

24362436

2437+
.. ssl-libressl:
2438+
2439+
LibreSSL support
2440+
----------------
2441+
2442+
LibreSSL is a fork of OpenSSL 1.0.1. The ssl module has limited support for
2443+
LibreSSL. Some features are not available when the ssl module is compiled
2444+
with LibreSSL.
2445+
2446+
* LibreSSL >= 2.6.1 no longer supports NPN. The methods
2447+
:meth:`SSLContext.set_npn_protocols` and
2448+
:meth:`SSLSocket.selected_npn_protocol` are not available.
2449+
* :meth:`SSLContext.set_default_verify_paths` ignores the env vars
2450+
:envvar:`SSL_CERT_FILE` and :envvar:`SSL_CERT_PATH` although
2451+
:func:`get_default_verify_paths` still reports them.
2452+
2453+
24372454
.. seealso::
24382455

24392456
Class :class:`socket.socket`
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The ssl module now detects missing NPN support in LibreSSL.

Modules/_ssl.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,19 @@ static void _PySSLFixErrno(void) {
160160
# define HAVE_ALPN
161161
#endif
162162

163+
/* We cannot rely on OPENSSL_NO_NEXTPROTONEG because LibreSSL 2.6.1 dropped
164+
* NPN support but did not set OPENSSL_NO_NEXTPROTONEG for compatibility
165+
* reasons. The check for TLSEXT_TYPE_next_proto_neg works with
166+
* OpenSSL 1.0.1+ and LibreSSL.
167+
*/
168+
#ifdef OPENSSL_NO_NEXTPROTONEG
169+
# define HAVE_NPN 0
170+
#elif defined(TLSEXT_TYPE_next_proto_neg)
171+
# define HAVE_NPN 1
172+
#else
173+
# define HAVE_NPN 0
174+
# endif
175+
163176
#ifndef INVALID_SOCKET /* MS defines this */
164177
#define INVALID_SOCKET (-1)
165178
#endif
@@ -328,7 +341,7 @@ static unsigned int _ssl_locks_count = 0;
328341
typedef struct {
329342
PyObject_HEAD
330343
SSL_CTX *ctx;
331-
#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
344+
#ifdef HAVE_NPN
332345
unsigned char *npn_protocols;
333346
int npn_protocols_len;
334347
#endif
@@ -1909,7 +1922,7 @@ _ssl__SSLSocket_version_impl(PySSLSocket *self)
19091922
return PyUnicode_FromString(version);
19101923
}
19111924

1912-
#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
1925+
#ifdef HAVE_NPN
19131926
/*[clinic input]
19141927
_ssl._SSLSocket.selected_npn_protocol
19151928
[clinic start generated code]*/
@@ -2874,7 +2887,7 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
28742887
self->ctx = ctx;
28752888
self->hostflags = X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS;
28762889
self->protocol = proto_version;
2877-
#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
2890+
#ifdef HAVE_NPN
28782891
self->npn_protocols = NULL;
28792892
#endif
28802893
#ifdef HAVE_ALPN
@@ -3013,7 +3026,7 @@ context_dealloc(PySSLContext *self)
30133026
PyObject_GC_UnTrack(self);
30143027
context_clear(self);
30153028
SSL_CTX_free(self->ctx);
3016-
#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
3029+
#ifdef HAVE_NPN
30173030
PyMem_FREE(self->npn_protocols);
30183031
#endif
30193032
#ifdef HAVE_ALPN
@@ -3091,7 +3104,7 @@ _ssl__SSLContext_get_ciphers_impl(PySSLContext *self)
30913104
#endif
30923105

30933106

3094-
#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG) || defined(HAVE_ALPN)
3107+
#if defined(HAVE_NPN) || defined(HAVE_ALPN)
30953108
static int
30963109
do_protocol_selection(int alpn, unsigned char **out, unsigned char *outlen,
30973110
const unsigned char *server_protocols, unsigned int server_protocols_len,
@@ -3117,7 +3130,7 @@ do_protocol_selection(int alpn, unsigned char **out, unsigned char *outlen,
31173130
}
31183131
#endif
31193132

3120-
#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
3133+
#ifdef HAVE_NPN
31213134
/* this callback gets passed to SSL_CTX_set_next_protos_advertise_cb */
31223135
static int
31233136
_advertiseNPN_cb(SSL *s,
@@ -3160,7 +3173,7 @@ _ssl__SSLContext__set_npn_protocols_impl(PySSLContext *self,
31603173
Py_buffer *protos)
31613174
/*[clinic end generated code: output=72b002c3324390c6 input=319fcb66abf95bd7]*/
31623175
{
3163-
#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
3176+
#ifdef HAVE_NPN
31643177
PyMem_Free(self->npn_protocols);
31653178
self->npn_protocols = PyMem_Malloc(protos->len);
31663179
if (self->npn_protocols == NULL)
@@ -5705,7 +5718,7 @@ PyInit__ssl(void)
57055718
Py_INCREF(r);
57065719
PyModule_AddObject(m, "HAS_ECDH", r);
57075720

5708-
#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
5721+
#ifdef HAVE_NPN
57095722
r = Py_True;
57105723
#else
57115724
r = Py_False;

Modules/clinic/_ssl.c.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ _ssl__SSLSocket_version(PySSLSocket *self, PyObject *Py_UNUSED(ignored))
132132
return _ssl__SSLSocket_version_impl(self);
133133
}
134134

135-
#if (defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG))
135+
#if defined(HAVE_NPN)
136136

137137
PyDoc_STRVAR(_ssl__SSLSocket_selected_npn_protocol__doc__,
138138
"selected_npn_protocol($self, /)\n"
@@ -151,7 +151,7 @@ _ssl__SSLSocket_selected_npn_protocol(PySSLSocket *self, PyObject *Py_UNUSED(ign
151151
return _ssl__SSLSocket_selected_npn_protocol_impl(self);
152152
}
153153

154-
#endif /* (defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)) */
154+
#endif /* defined(HAVE_NPN) */
155155

156156
#if defined(HAVE_ALPN)
157157

@@ -1175,4 +1175,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje
11751175
#ifndef _SSL_ENUM_CRLS_METHODDEF
11761176
#define _SSL_ENUM_CRLS_METHODDEF
11771177
#endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */
1178-
/*[clinic end generated code: output=d987411caeb106e7 input=a9049054013a1b77]*/
1178+
/*[clinic end generated code: output=a00fef6a470cfc2c input=a9049054013a1b77]*/

0 commit comments

Comments
 (0)