You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
8.1 KiB

  1. From 991f0176e188227647bf4c993d8da81cf794b3ae Mon Sep 17 00:00:00 2001
  2. From: Christian Heimes <christian@python.org>
  3. Date: Sun, 25 Feb 2018 20:03:07 +0100
  4. Subject: [PATCH] bpo-30008: SSL module: emulate tls methods
  5. OpenSSL 1.1 compatility: emulate version specific TLS methods with
  6. SSL_CTX_set_min/max_proto_version().
  7. ---
  8. .../2018-02-25-20-05-51.bpo-30008.6Bmyhr.rst | 4 +
  9. Modules/_ssl.c | 134 ++++++++++++++----
  10. 2 files changed, 108 insertions(+), 30 deletions(-)
  11. create mode 100644 Misc/NEWS.d/next/Library/2018-02-25-20-05-51.bpo-30008.6Bmyhr.rst
  12. diff --git a/Misc/NEWS.d/next/Library/2018-02-25-20-05-51.bpo-30008.6Bmyhr.rst b/Misc/NEWS.d/next/Library/2018-02-25-20-05-51.bpo-30008.6Bmyhr.rst
  13. new file mode 100644
  14. index 000000000000..e0a08464a1e1
  15. --- /dev/null
  16. +++ b/Misc/NEWS.d/next/Library/2018-02-25-20-05-51.bpo-30008.6Bmyhr.rst
  17. @@ -0,0 +1,4 @@
  18. +The ssl module no longer uses function that are deprecated since OpenSSL
  19. +1.1.0. The version specific TLS methods are emulated with TLS_method() plus
  20. +SSL_CTX_set_min/max_proto_version(). Pseudo random numbers are generated
  21. +with RAND_bytes().
  22. diff --git a/Modules/_ssl.c b/Modules/_ssl.c
  23. index f50823e6947a..827026e3bf5c 100644
  24. --- a/Modules/_ssl.c
  25. +++ b/Modules/_ssl.c
  26. @@ -45,14 +45,6 @@ static PySocketModule_APIObject PySocketModule;
  27. #include <sys/poll.h>
  28. #endif
  29. -/* Don't warn about deprecated functions */
  30. -#ifdef __GNUC__
  31. -#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  32. -#endif
  33. -#ifdef __clang__
  34. -#pragma clang diagnostic ignored "-Wdeprecated-declarations"
  35. -#endif
  36. -
  37. /* Include OpenSSL header files */
  38. #include "openssl/rsa.h"
  39. #include "openssl/crypto.h"
  40. @@ -205,6 +197,7 @@ static void _PySSLFixErrno(void) {
  41. #ifndef PY_OPENSSL_1_1_API
  42. /* OpenSSL 1.1 API shims for OpenSSL < 1.1.0 and LibreSSL < 2.7.0 */
  43. +#define ASN1_STRING_get0_data ASN1_STRING_data
  44. #define TLS_method SSLv23_method
  45. #define TLS_client_method SSLv23_client_method
  46. #define TLS_server_method SSLv23_server_method
  47. @@ -896,7 +889,7 @@ _ssl_configure_hostname(PySSLSocket *self, const char* server_hostname)
  48. goto error;
  49. }
  50. } else {
  51. - if (!X509_VERIFY_PARAM_set1_ip(param, ASN1_STRING_data(ip),
  52. + if (!X509_VERIFY_PARAM_set1_ip(param, ASN1_STRING_get0_data(ip),
  53. ASN1_STRING_length(ip))) {
  54. _setSSLError(NULL, 0, __FILE__, __LINE__);
  55. goto error;
  56. @@ -1372,8 +1365,9 @@ _get_peer_alt_names (X509 *certificate) {
  57. goto fail;
  58. }
  59. PyTuple_SET_ITEM(t, 0, v);
  60. - v = PyUnicode_FromStringAndSize((char *)ASN1_STRING_data(as),
  61. - ASN1_STRING_length(as));
  62. + v = PyUnicode_FromStringAndSize(
  63. + (char *)ASN1_STRING_get0_data(as),
  64. + ASN1_STRING_length(as));
  65. if (v == NULL) {
  66. Py_DECREF(t);
  67. goto fail;
  68. @@ -3031,44 +3025,124 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
  69. long options;
  70. SSL_CTX *ctx = NULL;
  71. X509_VERIFY_PARAM *params;
  72. - int result;
  73. + int result = 0;
  74. #if defined(SSL_MODE_RELEASE_BUFFERS)
  75. unsigned long libver;
  76. #endif
  77. PySSL_BEGIN_ALLOW_THREADS
  78. - if (proto_version == PY_SSL_VERSION_TLS1)
  79. + switch (proto_version) {
  80. +#if OPENSSL_VERSION_NUMBER <= 0x10100000L
  81. + /* OpenSSL < 1.1.0 or not LibreSSL
  82. + * Use old-style methods for OpenSSL 1.0.2
  83. + */
  84. +#if defined(SSL2_VERSION) && !defined(OPENSSL_NO_SSL2)
  85. + case PY_SSL_VERSION_SSL2:
  86. + ctx = SSL_CTX_new(SSLv2_method());
  87. + break;
  88. +#endif
  89. +#if defined(SSL3_VERSION) && !defined(OPENSSL_NO_SSL3)
  90. + case PY_SSL_VERSION_SSL3:
  91. + ctx = SSL_CTX_new(SSLv3_method());
  92. + break;
  93. +#endif
  94. +#if defined(TLS1_VERSION) && !defined(OPENSSL_NO_TLS1)
  95. + case PY_SSL_VERSION_TLS1:
  96. ctx = SSL_CTX_new(TLSv1_method());
  97. -#if HAVE_TLSv1_2
  98. - else if (proto_version == PY_SSL_VERSION_TLS1_1)
  99. + break;
  100. +#endif
  101. +#if defined(TLS1_1_VERSION) && !defined(OPENSSL_NO_TLS1_1)
  102. + case PY_SSL_VERSION_TLS1_1:
  103. ctx = SSL_CTX_new(TLSv1_1_method());
  104. - else if (proto_version == PY_SSL_VERSION_TLS1_2)
  105. + break;
  106. +#endif
  107. +#if defined(TLS1_2_VERSION) && !defined(OPENSSL_NO_TLS1_2)
  108. + case PY_SSL_VERSION_TLS1_2:
  109. ctx = SSL_CTX_new(TLSv1_2_method());
  110. + break;
  111. #endif
  112. -#ifndef OPENSSL_NO_SSL3
  113. - else if (proto_version == PY_SSL_VERSION_SSL3)
  114. - ctx = SSL_CTX_new(SSLv3_method());
  115. +#else
  116. + /* OpenSSL >= 1.1 or LibreSSL
  117. + * create context with TLS_method for all protocols
  118. + * no SSLv2_method in OpenSSL 1.1.
  119. + */
  120. +#if defined(SSL3_VERSION) && !defined(OPENSSL_NO_SSL3)
  121. + case PY_SSL_VERSION_SSL3:
  122. + ctx = SSL_CTX_new(TLS_method());
  123. + if (ctx != NULL) {
  124. + /* OpenSSL 1.1.0 sets SSL_OP_NO_SSLv3 for TLS_method by default */
  125. + SSL_CTX_clear_options(ctx, SSL_OP_NO_SSLv3);
  126. + if (!SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION))
  127. + result = -2;
  128. + if (!SSL_CTX_set_max_proto_version(ctx, SSL3_VERSION))
  129. + result = -2;
  130. + }
  131. + break;
  132. #endif
  133. -#ifndef OPENSSL_NO_SSL2
  134. - else if (proto_version == PY_SSL_VERSION_SSL2)
  135. - ctx = SSL_CTX_new(SSLv2_method());
  136. +#if defined(TLS1_VERSION) && !defined(OPENSSL_NO_TLS1)
  137. + case PY_SSL_VERSION_TLS1:
  138. + ctx = SSL_CTX_new(TLS_method());
  139. + if (ctx != NULL) {
  140. + SSL_CTX_clear_options(ctx, SSL_OP_NO_TLSv1);
  141. + if (!SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION))
  142. + result = -2;
  143. + if (!SSL_CTX_set_max_proto_version(ctx, TLS1_VERSION))
  144. + result = -2;
  145. + }
  146. + break;
  147. +#endif
  148. +#if defined(TLS1_1_VERSION) && !defined(OPENSSL_NO_TLS1_1)
  149. + case PY_SSL_VERSION_TLS1_1:
  150. + ctx = SSL_CTX_new(TLS_method());
  151. + if (ctx != NULL) {
  152. + SSL_CTX_clear_options(ctx, SSL_OP_NO_TLSv1_1);
  153. + if (!SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION))
  154. + result = -2;
  155. + if (!SSL_CTX_set_max_proto_version(ctx, TLS1_1_VERSION))
  156. + result = -2;
  157. + }
  158. + break;
  159. +#endif
  160. +#if defined(TLS1_2_VERSION) && !defined(OPENSSL_NO_TLS1_2)
  161. + case PY_SSL_VERSION_TLS1_2:
  162. + ctx = SSL_CTX_new(TLS_method());
  163. + if (ctx != NULL) {
  164. + SSL_CTX_clear_options(ctx, SSL_OP_NO_TLSv1_2);
  165. + if (!SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION))
  166. + result = -2;
  167. + if (!SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION))
  168. + result = -2;
  169. + }
  170. + break;
  171. #endif
  172. - else if (proto_version == PY_SSL_VERSION_TLS) /* SSLv23 */
  173. +#endif /* OpenSSL >= 1.1 */
  174. + case PY_SSL_VERSION_TLS:
  175. + /* SSLv23 */
  176. ctx = SSL_CTX_new(TLS_method());
  177. - else if (proto_version == PY_SSL_VERSION_TLS_CLIENT)
  178. + break;
  179. + case PY_SSL_VERSION_TLS_CLIENT:
  180. ctx = SSL_CTX_new(TLS_client_method());
  181. - else if (proto_version == PY_SSL_VERSION_TLS_SERVER)
  182. + break;
  183. + case PY_SSL_VERSION_TLS_SERVER:
  184. ctx = SSL_CTX_new(TLS_server_method());
  185. - else
  186. - proto_version = -1;
  187. + break;
  188. + default:
  189. + result = -1;
  190. + break;
  191. + }
  192. PySSL_END_ALLOW_THREADS
  193. - if (proto_version == -1) {
  194. + if (result == -1) {
  195. PyErr_SetString(PyExc_ValueError,
  196. "invalid protocol version");
  197. return NULL;
  198. }
  199. - if (ctx == NULL) {
  200. + else if (result == -2) {
  201. + PyErr_SetString(PyExc_ValueError,
  202. + "protocol configuration error");
  203. + return NULL;
  204. + }
  205. + else if (ctx == NULL) {
  206. _setSSLError(NULL, 0, __FILE__, __LINE__);
  207. return NULL;
  208. }
  209. @@ -5241,7 +5315,7 @@ PySSL_RAND(int len, int pseudo)
  210. if (bytes == NULL)
  211. return NULL;
  212. if (pseudo) {
  213. - ok = RAND_pseudo_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len);
  214. + ok = (_PyOS_URandom((unsigned char*)PyBytes_AS_STRING(bytes), len) == 0 ? 1 : 0);
  215. if (ok == 0 || ok == 1)
  216. return Py_BuildValue("NO", bytes, ok == 1 ? Py_True : Py_False);
  217. }