cpython: 8b729d65cfd2 (original) (raw)
Mercurial > cpython
changeset 74084:8b729d65cfd2
Issue #13627: Add support for SSL Elliptic Curve-based Diffie-Hellman key exchange, through the SSLContext.set_ecdh_curve() method and the ssl.OP_SINGLE_ECDH_USE option. [#13627]
Antoine Pitrou solipsis@pitrou.net | |
---|---|
date | Mon, 19 Dec 2011 17:16:51 +0100 |
parents | a3d5f522065f |
children | a882aa30a713 |
files | Doc/library/ssl.rst Lib/ssl.py Lib/test/ssl_servers.py Lib/test/test_ssl.py Misc/NEWS Modules/_ssl.c |
diffstat | 6 files changed, 76 insertions(+), 1 deletions(-)[+] [-] Doc/library/ssl.rst 26 Lib/ssl.py 2 Lib/test/ssl_servers.py 5 Lib/test/test_ssl.py 10 Misc/NEWS 4 Modules/_ssl.c 30 |
line wrap: on
line diff
--- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -428,6 +428,14 @@ Constants .. versionadded:: 3.3 +.. data:: OP_SINGLE_ECDH_USE +
- Prevents re-use of the same ECDH key for several SSL sessions. This
- improves forward secrecy but requires more computational resources.
- This option only applies to server sockets. +
- .. versionadded:: 3.3 +
.. data:: HAS_SNI
Whether the OpenSSL library has built-in support for the *Server Name
@@ -672,6 +680,24 @@ to speed up repeated connections from th
when connected, the :meth:SSLSocket.cipher
method of SSL sockets will
give the currently selected cipher.
+.. method:: SSLContext.set_ecdh_curve(curve_name)
+
- Set the curve name for Elliptic Curve-based Diffie-Hellman (abbreviated
- ECDH) key exchange. Using Diffie-Hellman key exchange improves forward
- secrecy at the expense of computational resources (both on the server and
- on the client). The curve_name parameter should be a string describing
- a well-known elliptic curve, for example
prime256v1
for a widely - supported curve. +
- This setting doesn't apply to client sockets. You can also use the
- :data:
OP_SINGLE_ECDH_USE
option to further improve security. + - .. versionadded:: 3.3 +
- .. seealso::
`SSL/TLS & Perfect Forward Secrecy <http://vincent.bernat.im/en/blog/2011-ssl-perfect-forward-secrecy.html>`_[](#l1.37)
Vincent Bernat.[](#l1.38)
+ .. method:: SSLContext.wrap_socket(sock, server_side=False, [](#l1.40) do_handshake_on_connect=True, suppress_ragged_eofs=True, [](#l1.41) server_hostname=None)
--- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -68,7 +68,7 @@ from _ssl import ( from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED from _ssl import ( OP_ALL, OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_TLSv1,
- OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_ECDH_USE, ) from _ssl import RAND_status, RAND_egd, RAND_add, RAND_bytes, RAND_pseudo_bytes from _ssl import (
--- a/Lib/test/ssl_servers.py +++ b/Lib/test/ssl_servers.py @@ -176,6 +176,9 @@ if name == "main": action='store_false', help='be less verbose') parser.add_argument('-s', '--stats', dest='use_stats_handler', default=False, action='store_true', help='always return stats page')
- parser.add_argument('--curve-name', dest='curve_name', type=str,
action='store',[](#l3.8)
args = parser.parse_args() support.verbose = args.verbose @@ -186,6 +189,8 @@ if name == "main": handler_class.root = os.getcwd() context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context.load_cert_chain(CERTFILE)help='curve name for EC-based Diffie-Hellman')[](#l3.9)
- if args.curve_name:
context.set_ecdh_curve(args.curve_name)[](#l3.18)
server = HTTPSServer(("", args.port), handler_class, context) if args.verbose:
--- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -99,6 +99,7 @@ class BasicSocketTests(unittest.TestCase ssl.CERT_OPTIONAL ssl.CERT_REQUIRED ssl.OP_CIPHER_SERVER_PREFERENCE
ssl.OP_SINGLE_ECDH_USE[](#l4.7) self.assertIn(ssl.HAS_SNI, {True, False})[](#l4.8)
def test_random(self): @@ -558,6 +559,15 @@ class ContextTests(unittest.TestCase): ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) ctx.set_default_verify_paths()
- def test_set_ecdh_curve(self):
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)[](#l4.16)
ctx.set_ecdh_curve("prime256v1")[](#l4.17)
ctx.set_ecdh_curve(b"prime256v1")[](#l4.18)
self.assertRaises(TypeError, ctx.set_ecdh_curve)[](#l4.19)
self.assertRaises(TypeError, ctx.set_ecdh_curve, None)[](#l4.20)
self.assertRaises(ValueError, ctx.set_ecdh_curve, "foo")[](#l4.21)
self.assertRaises(ValueError, ctx.set_ecdh_curve, b"foo")[](#l4.22)
+ class NetworkedTests(unittest.TestCase):
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -419,6 +419,10 @@ Core and Builtins Library ------- +- Issue #13627: Add support for SSL Elliptic Curve-based Diffie-Hellman
- key exchange, through the SSLContext.set_ecdh_curve() method and the
- ssl.OP_SINGLE_ECDH_USE option. +
- Issue #13635: Add ssl.OP_CIPHER_SERVER_PREFERENCE, so that SSL servers choose the cipher based on their own preferences, rather than on the client's.
--- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1986,6 +1986,33 @@ set_default_verify_paths(PySSLContext *s Py_RETURN_NONE; } +static PyObject * +set_ecdh_curve(PySSLContext *self, PyObject *name) +{
- if (!PyUnicode_FSConverter(name, &name_bytes))
return NULL;[](#l6.15)
- assert(PyBytes_Check(name_bytes));
- nid = OBJ_sn2nid(PyBytes_AS_STRING(name_bytes));
- Py_DECREF(name_bytes);
- if (nid == 0) {
PyErr_Format(PyExc_ValueError,[](#l6.20)
"unknown elliptic curve name %R", name);[](#l6.21)
return NULL;[](#l6.22)
- }
- key = EC_KEY_new_by_curve_name(nid);
- if (key == NULL) {
_setSSLError(NULL, 0, __FILE__, __LINE__);[](#l6.26)
return NULL;[](#l6.27)
- }
- SSL_CTX_set_tmp_ecdh(self->ctx, key);
- EC_KEY_free(key);
- Py_RETURN_NONE;
+} + static PyGetSetDef context_getsetlist[] = { {"options", (getter) get_options, (setter) set_options, NULL}, @@ -2007,6 +2034,8 @@ static struct PyMethodDef context_method METH_NOARGS, NULL}, {"set_default_verify_paths", (PyCFunction) set_default_verify_paths, METH_NOARGS, NULL},
- {"set_ecdh_curve", (PyCFunction) set_ecdh_curve,
{NULL, NULL} /* sentinel */ }; @@ -2452,6 +2481,7 @@ PyInit__ssl(void) PyModule_AddIntConstant(m, "OP_NO_TLSv1", SSL_OP_NO_TLSv1); PyModule_AddIntConstant(m, "OP_CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE);METH_O, NULL},[](#l6.42)
- PyModule_AddIntConstant(m, "OP_SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE);