summaryrefslogtreecommitdiff
path: root/lang/python34/files/patch-issue30622
blob: 9ee185fc26ed352ec78e946e8b7068e64d3a972c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
From b2d096bd2a5ff86e53c25d00ee5fa097b36bf1d8 Mon Sep 17 00:00:00 2001
From: Melvyn Sopacua <melvyn-sopacua@users.noreply.github.com>
Date: Mon, 4 Sep 2017 23:35:15 +0200
Subject: [PATCH] bpo-30622: Change NPN detection: (#2079)

* Change NPN detection:

Version breakdown, support disabled (pre-patch/post-patch):
- pre-1.0.1: OPENSSL_NPN_NEGOTIATED will not be defined -> False/False
- 1.0.1 and 1.0.2: OPENSSL_NPN_NEGOTIATED will not be defined ->
False/False
- 1.1.0+: OPENSSL_NPN_NEGOTIATED will be defined and
OPENSSL_NO_NEXTPROTONEG will be defined -> True/False

Version breakdown support enabled (pre-patch/post-patch):
- pre-1.0.1: OPENSSL_NPN_NEGOTIATED will not be defined -> False/False
- 1.0.1 and 1.0.2: OPENSSL_NPN_NEGOTIATED will be defined and
OPENSSL_NO_NEXTPROTONEG will not be defined -> True/True
- 1.1.0+: OPENSSL_NPN_NEGOTIATED will be defined and
OPENSSL_NO_NEXTPROTONEG will not be defined -> True/True

* Refine NPN guard:

- If NPN is disabled, but ALPN is available we need our callback
- Make clinic's ssl behave the same way

This created a working ssl module for me, with NPN disabled and ALPN
enabled for OpenSSL 1.1.0f.

Concerns to address:
The initial commit for NPN support into OpenSSL [1], had the
OPENSSL_NPN_* variables defined inside the OPENSSL_NO_NEXTPROTONEG
guard. The question is if that ever made it into a release.
This would need an ugly hack, something like:

	#if defined(OPENSSL_NO_NEXTPROTONEG) && \
		!defined(OPENSSL_NPN_NEGOTIATED)
	#	define OPENSSL_NPN_UNSUPPORTED 0
	#	define OPENSSL_NPN_NEGOTIATED 1
	#	define OPENSSL_NPN_NO_OVERLAP 2
	#endif

[1] https://github.com/openssl/openssl/commit/68b33cc5c7

--- Modules/_ssl.c.orig	2018-02-04 23:40:38 UTC
+++ Modules/_ssl.c
@@ -207,7 +207,7 @@ static unsigned int _ssl_locks_count = 0
 typedef struct {
     PyObject_HEAD
     SSL_CTX *ctx;
-#ifdef OPENSSL_NPN_NEGOTIATED
+#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
     char *npn_protocols;
     int npn_protocols_len;
 #endif
@@ -1403,7 +1403,7 @@ static PyObject *PySSL_cipher (PySSLSock
     return NULL;
 }
 
-#ifdef OPENSSL_NPN_NEGOTIATED
+#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
 static PyObject *PySSL_selected_npn_protocol(PySSLSocket *self) {
     const unsigned char *out;
     unsigned int outlen;
@@ -1920,7 +1920,7 @@ static PyMethodDef PySSLMethods[] = {
     {"peer_certificate", (PyCFunction)PySSL_peercert, METH_VARARGS,
      PySSL_peercert_doc},
     {"cipher", (PyCFunction)PySSL_cipher, METH_NOARGS},
-#ifdef OPENSSL_NPN_NEGOTIATED
+#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
     {"selected_npn_protocol", (PyCFunction)PySSL_selected_npn_protocol, METH_NOARGS},
 #endif
     {"compression", (PyCFunction)PySSL_compression, METH_NOARGS},
@@ -2027,7 +2027,7 @@ context_new(PyTypeObject *type, PyObject
         return NULL;
     }
     self->ctx = ctx;
-#ifdef OPENSSL_NPN_NEGOTIATED
+#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
     self->npn_protocols = NULL;
 #endif
 #ifndef OPENSSL_NO_TLSEXT
@@ -2099,7 +2099,7 @@ context_dealloc(PySSLContext *self)
 {
     context_clear(self);
     SSL_CTX_free(self->ctx);
-#ifdef OPENSSL_NPN_NEGOTIATED
+#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
     PyMem_Free(self->npn_protocols);
 #endif
     Py_TYPE(self)->tp_free(self);
@@ -2126,7 +2126,7 @@ set_ciphers(PySSLContext *self, PyObject
     Py_RETURN_NONE;
 }
 
-#ifdef OPENSSL_NPN_NEGOTIATED
+#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
 /* this callback gets passed to SSL_CTX_set_next_protos_advertise_cb */
 static int
 _advertiseNPN_cb(SSL *s,
@@ -2175,7 +2175,7 @@ _selectNPN_cb(SSL *s,
 static PyObject *
 _set_npn_protocols(PySSLContext *self, PyObject *args)
 {
-#ifdef OPENSSL_NPN_NEGOTIATED
+#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
     Py_buffer protos;
 
     if (!PyArg_ParseTuple(args, "y*:set_npn_protocols", &protos))
@@ -4130,7 +4130,7 @@ PyInit__ssl(void)
     Py_INCREF(r);
     PyModule_AddObject(m, "HAS_ECDH", r);
 
-#ifdef OPENSSL_NPN_NEGOTIATED
+#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
     r = Py_True;
 #else
     r = Py_False;