summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@amacapital.net>2014-03-13 17:22:25 -0700
committerAndy Lutomirski <luto@amacapital.net>2014-03-13 17:40:33 -0700
commitf05a273f1bd6a083cb922cc3c5565ad01cbc05e0 (patch)
tree41dcb073ffdc3bc83c511ece228bc440a0238005
parent76a6133518e5671cc6380304fdc06aae66542d7c (diff)
downloadpyopenssl-f05a273f1bd6a083cb922cc3c5565ad01cbc05e0.tar.gz
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.
-rw-r--r--OpenSSL/SSL.py20
-rw-r--r--OpenSSL/test/test_ssl.py27
-rw-r--r--doc/api/ssl.rst34
3 files changed, 50 insertions, 31 deletions
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 @@ if _Cryptography_HAS_EC:
_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 @@ class Context(object):
_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 @@ from OpenSSL.SSL import (
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 @@ class ContextTests(TestCase, _LoopbackMixin):
# 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 @@ Context, Connection.
.. 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 @@ Context objects have the following methods:
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)
+
+ Select a curve to use for ECDHE key exchange.
- Configure this connection to people to use Elliptical Curve Diffie-Hellman
- key exchanges.
+ The valid values of *curve_name* are the keys in
+ :py:data:`ELLIPTIC_CURVE_DESCRIPTIONS`.
- ``curve_name`` should be one of the named curve constants, such as
- :py:data:`NID_X9_62_prime256v1`.
+ 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)