Identify elliptic curves by short name, not NID

Using NIDs is awkward and requires updating pyOpenSSL every time a new
curve is added.  This approach avoids needing to update pyOpenSSL
each time a new curve is added, and it results in more readable code
and a more readable dict ELLIPTIC_CURVE_DESCRIPTIONS.
diff --git a/OpenSSL/SSL.py b/OpenSSL/SSL.py
index 602a98c..f6d62d4 100644
--- a/OpenSSL/SSL.py
+++ b/OpenSSL/SSL.py
@@ -271,7 +271,8 @@
     _num_curves = _lib.EC_get_builtin_curves(_ffi.NULL, 0)
     _curves = _ffi.new('EC_builtin_curve[]', _num_curves)
     if _lib.EC_get_builtin_curves(_curves, _num_curves) == _num_curves:
-        ELLIPTIC_CURVE_DESCRIPTIONS = dict((c.nid, _ffi.string(c.comment))
+        ELLIPTIC_CURVE_DESCRIPTIONS = dict((_ffi.string(_lib.OBJ_nid2sn(c.nid)),
+                                            _ffi.string(c.comment))
                                            for c in _curves)
     del _num_curves
     del _curves
@@ -749,16 +750,25 @@
         _lib.SSL_CTX_set_tmp_dh(self._context, dh)
 
 
-    def set_tmp_ecdh_by_curve_name(self, curve_name):
+    def set_tmp_ecdh_curve(self, curve_name):
         """
         Select a curve to use for ECDHE key exchange.
 
-        :param curve_name: One of the named curve constants.
-        :type curve_name: int
+        The valid values of *curve_name* are the keys in
+        :py:data:OpenSSL.SSL.ELLIPTIC_CURVE_DESCRIPTIONS.
+
+        Raises a ``ValueError`` if the linked OpenSSL was not compiled with
+        elliptical curve support, or the specified curve is not available.
+
+        :param curve_name: The 'short name' of a curve, e.g. 'prime256v1'
+        :type curve_name: str
         :return: None
         """
         if _lib.Cryptography_HAS_EC:
-            ecdh = _lib.EC_KEY_new_by_curve_name(curve_name)
+            nid = _lib.OBJ_sn2nid(curve_name)
+            if nid == _lib.NID_undef:
+                raise ValueError("No such OpenSSL object '%s'" % curve_name)
+            ecdh = _lib.EC_KEY_new_by_curve_name(nid)
             if ecdh == _ffi.NULL:
                 raise ValueError(
                     "OpenSSL could not load the requested elliptic curve"
diff --git a/OpenSSL/test/test_ssl.py b/OpenSSL/test/test_ssl.py
index 2686d12..0fc8f29 100644
--- a/OpenSSL/test/test_ssl.py
+++ b/OpenSSL/test/test_ssl.py
@@ -35,7 +35,8 @@
     SESS_CACHE_OFF, SESS_CACHE_CLIENT, SESS_CACHE_SERVER, SESS_CACHE_BOTH,
     SESS_CACHE_NO_AUTO_CLEAR, SESS_CACHE_NO_INTERNAL_LOOKUP,
     SESS_CACHE_NO_INTERNAL_STORE, SESS_CACHE_NO_INTERNAL)
-from OpenSSL.SSL import NID_X9_62_prime256v1, _Cryptography_HAS_EC
+from OpenSSL.SSL import (
+    _Cryptography_HAS_EC, ELLIPTIC_CURVE_DESCRIPTIONS)
 
 from OpenSSL.SSL import (
     Error, SysCallError, WantReadError, WantWriteError, ZeroReturnError)
@@ -1173,15 +1174,21 @@
         # XXX What should I assert here? -exarkun
 
 
-    if _Cryptography_HAS_EC:
-        def test_set_tmp_ecdh_by_curve_name(self):
-            """
-            :py:obj:`Context.set_tmp_ecdh_by_curve_name` sets the Eliptical
-            Curve for Diffie-Hellman by the named curve.
-            """
-            context = Context(TLSv1_METHOD)
-            context.set_tmp_ecdh_by_curve_name(NID_X9_62_prime256v1)
-            # XXX What should I assert here? -alex
+    def test_set_tmp_ecdh_curve(self):
+        """
+        :py:obj:`Context.set_tmp_ecdh_curve` sets the Eliptical
+        Curve for Diffie-Hellman by the named curve.
+        """
+        context = Context(TLSv1_METHOD)
+        for curve in ELLIPTIC_CURVE_DESCRIPTIONS.keys():
+            context.set_tmp_ecdh_curve(curve)  # Must not throw.
+
+        if _Cryptography_HAS_EC:
+            # If EC is compiled in, there must be at least one curve
+            # Tn theory there could be an OpenSSL that violates this
+            # assumption.  If so, this test will fail and we'll find
+            # out.
+            self.assertTrue(ELLIPTIC_CURVE_DESCRIPTIONS)
 
 
     def test_set_cipher_list_bytes(self):
diff --git a/doc/api/ssl.rst b/doc/api/ssl.rst
index 76fb0ad..f169cbc 100644
--- a/doc/api/ssl.rst
+++ b/doc/api/ssl.rst
@@ -116,16 +116,15 @@
      .. versionadded:: 0.14
 
 
-.. py:data:: NID_X9_62_prime192v1
-             NID_X9_62_prime192v2
-             NID_X9_62_prime192v3
-             NID_X9_62_prime239v1
-             NID_X9_62_prime239v2
-             NID_X9_62_prime239v3
-             NID_X9_62_prime256v1
+.. py:data:: ELLIPTIC_CURVE_DESCRIPTIONS
 
-    Constants used with :py:meth:`Context.set_tmp_ecdh_by_curve_name` to
-    specify which elliptical curve should be used.
+    A dictionary mapping short names of elliptic curves to textual
+    descriptions.  This dictionary contains exactly the set of curves
+    supported by the OpenSSL build in use.
+
+    The keys are the curve names that can be passed into
+    Constants used with :py:meth:`Context.set_tmp_ecdh_curve` to
+    specify which elliptical curve should be used for ECDHE key exchange.
 
 
 .. py:data:: OPENSSL_VERSION_NUMBER
@@ -334,16 +333,19 @@
 
     Load parameters for Ephemeral Diffie-Hellman from *dhfile*.
 
-.. py:method:: Context.set_tmp_ecdh_by_curve_name(curve_name)
+.. py:method:: Context.set_tmp_ecdh_curve(curve_name)
 
-    Configure this connection to people to use Elliptical Curve Diffie-Hellman
-    key exchanges.
+   Select a curve to use for ECDHE key exchange.
 
-    ``curve_name`` should be one of the named curve constants, such as
-    :py:data:`NID_X9_62_prime256v1`.
+   The valid values of *curve_name* are the keys in
+   :py:data:`ELLIPTIC_CURVE_DESCRIPTIONS`.
 
-    Raises a ``ValueError`` if the linked OpenSSL was not compiled with
-    elliptical curve support, or the specified curve is not available.
+   Raises a ``ValueError`` if the linked OpenSSL was not compiled with
+   elliptical curve support, or the specified curve is not available.
+
+   :param curve_name: The 'short name' of a curve, e.g. 'prime256v1'
+   :type curve_name: str
+   :return: None
 
 .. py:method:: Context.set_app_data(data)