diff -r c29301b1503f Lib/ssl.py --- a/Lib/ssl.py Fri Mar 21 21:49:38 2014 -0400 +++ b/Lib/ssl.py Sat Mar 22 01:01:47 2014 -0400 @@ -517,6 +517,13 @@ raise ValueError("check_hostname requires server_hostname, " "but it's not supported by your OpenSSL " "library") + + if server_side and not self._context._has_set_ecdh_curve: + if HAS_ECDH: + # This is a sever side socket and no ECDH curve has been + # specified + self._context.set_ecdh_curve() + self.server_side = server_side self.server_hostname = server_hostname self.do_handshake_on_connect = do_handshake_on_connect diff -r c29301b1503f Lib/test/test_ssl.py --- a/Lib/test/test_ssl.py Fri Mar 21 21:49:38 2014 -0400 +++ b/Lib/test/test_ssl.py Sat Mar 22 01:01:47 2014 -0400 @@ -922,7 +922,6 @@ ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) ctx.set_ecdh_curve("prime256v1") ctx.set_ecdh_curve(b"prime256v1") - self.assertRaises(TypeError, ctx.set_ecdh_curve) self.assertRaises(TypeError, ctx.set_ecdh_curve, None) self.assertRaises(ValueError, ctx.set_ecdh_curve, "foo") self.assertRaises(ValueError, ctx.set_ecdh_curve, b"foo") diff -r c29301b1503f Modules/_ssl.c --- a/Modules/_ssl.c Fri Mar 21 21:49:38 2014 -0400 +++ b/Modules/_ssl.c Sat Mar 22 01:01:47 2014 -0400 @@ -213,6 +213,9 @@ PyObject *set_hostname; #endif int check_hostname; +#ifndef OPENSSL_NO_ECDH + int _has_set_ecdh_curve; +#endif } PySSLContext; typedef struct { @@ -2052,6 +2055,10 @@ #endif /* Don't check host name by default */ self->check_hostname = 0; +#ifndef OPENSSL_NO_ECDH + /* We haven't set a ecdh curve yet */ + self->_has_set_ecdh_curve = 0; +#endif /* Defaults */ SSL_CTX_set_verify(self->ctx, SSL_VERIFY_NONE, NULL); options = SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; @@ -2337,6 +2344,14 @@ return 0; } +#ifndef OPENSSL_NO_ECDH +static PyObject * +get_has_set_ecdh_curve(PySSLContext *self, void *c) +{ + return PyBool_FromLong(self->_has_set_ecdh_curve); +} +#endif + typedef struct { PyThreadState *thread_state; @@ -2855,22 +2870,33 @@ #ifndef OPENSSL_NO_ECDH static PyObject * -set_ecdh_curve(PySSLContext *self, PyObject *name) +set_ecdh_curve(PySSLContext *self, PyObject *args) { + PyObject *name = NULL; PyObject *name_bytes; int nid; EC_KEY *key; - if (!PyUnicode_FSConverter(name, &name_bytes)) - return NULL; - assert(PyBytes_Check(name_bytes)); - nid = OBJ_sn2nid(PyBytes_AS_STRING(name_bytes)); - Py_DECREF(name_bytes); - if (nid == 0) { - PyErr_Format(PyExc_ValueError, - "unknown elliptic curve name %R", name); + if (!PyArg_ParseTuple(args, "|O:name", &name)) { return NULL; } + + if (name == NULL) { + nid = NID_X9_62_prime256v1; + } + else { + if (!PyUnicode_FSConverter(name, &name_bytes)) + return NULL; + assert(PyBytes_Check(name_bytes)); + nid = OBJ_sn2nid(PyBytes_AS_STRING(name_bytes)); + Py_DECREF(name_bytes); + if (nid == 0) { + PyErr_Format(PyExc_ValueError, + "unknown elliptic curve name %R", name); + return NULL; + } + } + key = EC_KEY_new_by_curve_name(nid); if (key == NULL) { _setSSLError(NULL, 0, __FILE__, __LINE__); @@ -2878,6 +2904,10 @@ } SSL_CTX_set_tmp_ecdh(self->ctx, key); EC_KEY_free(key); + + /* Mark that we've set a ecdh curve */ + self->_has_set_ecdh_curve = 1; + Py_RETURN_NONE; } #endif @@ -3131,6 +3161,9 @@ (setter) set_check_hostname, NULL}, {"options", (getter) get_options, (setter) set_options, NULL}, +#ifndef OPENSSL_NO_ECDH + {"_has_set_ecdh_curve", (getter) get_has_set_ecdh_curve, NULL, NULL}, +#endif #ifdef HAVE_OPENSSL_VERIFY_PARAM {"verify_flags", (getter) get_verify_flags, (setter) set_verify_flags, NULL}, @@ -3159,7 +3192,7 @@ METH_NOARGS, NULL}, #ifndef OPENSSL_NO_ECDH {"set_ecdh_curve", (PyCFunction) set_ecdh_curve, - METH_O, NULL}, + METH_VARARGS, NULL}, #endif {"set_servername_callback", (PyCFunction) set_servername_callback, METH_VARARGS, PySSL_set_servername_callback_doc},