@@ -130,6 +130,19 @@ struct py_ssl_library_code {
130130# define HAVE_ALPN
131131#endif
132132
133+ /* We cannot rely on OPENSSL_NO_NEXTPROTONEG because LibreSSL 2.6.1 dropped
134+ * NPN support but did not set OPENSSL_NO_NEXTPROTONEG for compatibility
135+ * reasons. The check for TLSEXT_TYPE_next_proto_neg works with
136+ * OpenSSL 1.0.1+ and LibreSSL.
137+ */
138+ #ifdef OPENSSL_NO_NEXTPROTONEG
139+ # define HAVE_NPN 0
140+ #elif defined(TLSEXT_TYPE_next_proto_neg )
141+ # define HAVE_NPN 1
142+ #else
143+ # define HAVE_NPN 0
144+ # endif
145+
133146#ifndef INVALID_SOCKET /* MS defines this */
134147#define INVALID_SOCKET (-1)
135148#endif
@@ -284,7 +297,7 @@ static unsigned int _ssl_locks_count = 0;
284297typedef struct {
285298 PyObject_HEAD
286299 SSL_CTX * ctx ;
287- #if defined( OPENSSL_NPN_NEGOTIATED ) && !defined( OPENSSL_NO_NEXTPROTONEG )
300+ #ifdef HAVE_NPN
288301 unsigned char * npn_protocols ;
289302 int npn_protocols_len ;
290303#endif
@@ -1776,7 +1789,7 @@ _ssl__SSLSocket_version_impl(PySSLSocket *self)
17761789 return PyUnicode_FromString (version );
17771790}
17781791
1779- #if defined( OPENSSL_NPN_NEGOTIATED ) && !defined( OPENSSL_NO_NEXTPROTONEG )
1792+ #ifdef HAVE_NPN
17801793/*[clinic input]
17811794_ssl._SSLSocket.selected_npn_protocol
17821795[clinic start generated code]*/
@@ -2729,7 +2742,7 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
27292742 return NULL ;
27302743 }
27312744 self -> ctx = ctx ;
2732- #if defined( OPENSSL_NPN_NEGOTIATED ) && !defined( OPENSSL_NO_NEXTPROTONEG )
2745+ #ifdef HAVE_NPN
27332746 self -> npn_protocols = NULL ;
27342747#endif
27352748#ifdef HAVE_ALPN
@@ -2864,7 +2877,7 @@ context_dealloc(PySSLContext *self)
28642877 PyObject_GC_UnTrack (self );
28652878 context_clear (self );
28662879 SSL_CTX_free (self -> ctx );
2867- #if defined( OPENSSL_NPN_NEGOTIATED ) && !defined( OPENSSL_NO_NEXTPROTONEG )
2880+ #ifdef HAVE_NPN
28682881 PyMem_FREE (self -> npn_protocols );
28692882#endif
28702883#ifdef HAVE_ALPN
@@ -2942,7 +2955,7 @@ _ssl__SSLContext_get_ciphers_impl(PySSLContext *self)
29422955#endif
29432956
29442957
2945- #if defined(OPENSSL_NPN_NEGOTIATED ) && !defined( OPENSSL_NO_NEXTPROTONEG ) || defined(HAVE_ALPN )
2958+ #if defined(HAVE_NPN ) || defined(HAVE_ALPN )
29462959static int
29472960do_protocol_selection (int alpn , unsigned char * * out , unsigned char * outlen ,
29482961 const unsigned char * server_protocols , unsigned int server_protocols_len ,
@@ -2968,7 +2981,7 @@ do_protocol_selection(int alpn, unsigned char **out, unsigned char *outlen,
29682981}
29692982#endif
29702983
2971- #if defined( OPENSSL_NPN_NEGOTIATED ) && !defined( OPENSSL_NO_NEXTPROTONEG )
2984+ #ifdef HAVE_NPN
29722985/* this callback gets passed to SSL_CTX_set_next_protos_advertise_cb */
29732986static int
29742987_advertiseNPN_cb (SSL * s ,
@@ -3011,7 +3024,7 @@ _ssl__SSLContext__set_npn_protocols_impl(PySSLContext *self,
30113024 Py_buffer * protos )
30123025/*[clinic end generated code: output=72b002c3324390c6 input=319fcb66abf95bd7]*/
30133026{
3014- #if defined( OPENSSL_NPN_NEGOTIATED ) && !defined( OPENSSL_NO_NEXTPROTONEG )
3027+ #ifdef HAVE_NPN
30153028 PyMem_Free (self -> npn_protocols );
30163029 self -> npn_protocols = PyMem_Malloc (protos -> len );
30173030 if (self -> npn_protocols == NULL )
@@ -5481,7 +5494,7 @@ PyInit__ssl(void)
54815494 Py_INCREF (r );
54825495 PyModule_AddObject (m , "HAS_ECDH" , r );
54835496
5484- #if defined( OPENSSL_NPN_NEGOTIATED ) && !defined( OPENSSL_NO_NEXTPROTONEG )
5497+ #ifdef HAVE_NPN
54855498 r = Py_True ;
54865499#else
54875500 r = Py_False ;
0 commit comments