Switch to an explicit curve object.
Happily, this eliminates just about all of the error cases.
diff --git a/OpenSSL/test/test_crypto.py b/OpenSSL/test/test_crypto.py
index a3685a9..b288985 100644
--- a/OpenSSL/test/test_crypto.py
+++ b/OpenSSL/test/test_crypto.py
@@ -25,9 +25,10 @@
from OpenSSL.crypto import PKCS12, PKCS12Type, load_pkcs12
from OpenSSL.crypto import CRL, Revoked, load_crl
from OpenSSL.crypto import NetscapeSPKI, NetscapeSPKIType
-from OpenSSL.crypto import sign, verify
+from OpenSSL.crypto import (
+ sign, verify, get_elliptic_curve, get_elliptic_curves)
from OpenSSL.test.util import TestCase, b
-from OpenSSL._util import native
+from OpenSSL._util import native, lib
def normalize_certificate_pem(pem):
return dump_certificate(FILETYPE_PEM, load_certificate(FILETYPE_PEM, pem))
@@ -3058,5 +3059,81 @@
verify(good_cert, sig, content, "sha1")
+
+class EllipticCurveTests(TestCase):
+ """
+ Tests for :py:class:`_EllipticCurve`, :py:obj:`get_elliptic_curve`, and
+ :py:obj:`get_elliptic_curves`.
+ """
+ def test_set(self):
+ """
+ :py:obj:`get_elliptic_curves` returns a :py:obj:`set`.
+ """
+ self.assertIsInstance(get_elliptic_curves(), set)
+
+
+ def test_some_curves(self):
+ """
+ If :py:mod:`cryptography` has elliptic curve support then the set
+ returned by :py:obj:`get_elliptic_curves` has some elliptic curves in
+ it.
+
+ There could be an OpenSSL that violates this assumption. If so, this
+ test will fail and we'll find out.
+ """
+ curves = get_elliptic_curves()
+ if lib.Cryptography_HAS_EC:
+ self.assertTrue(curves)
+ else:
+ self.assertFalse(curves)
+
+
+ def test_a_curve(self):
+ """
+ :py:obj:`get_elliptic_curve` can be used to retrieve a particular
+ supported curve.
+ """
+ curves = get_elliptic_curves()
+ if curves:
+ curve = next(iter(curves))
+ self.assertEqual(curve.name, get_elliptic_curve(curve.name).name)
+ else:
+ self.assertRaises(ValueError, get_elliptic_curve, u"prime256v1")
+
+
+ def test_not_a_curve(self):
+ """
+ :py:obj:`get_elliptic_curve` raises :py:class:`ValueError` if called
+ with a name which does not identify a supported curve.
+ """
+ self.assertRaises(
+ ValueError, get_elliptic_curve, u"this curve was just invented")
+
+
+ def test_repr(self):
+ """
+ The string representation of a curve object includes simply states the
+ object is a curve and what its name is.
+ """
+ curves = get_elliptic_curves()
+ if curves:
+ curve = next(iter(curves))
+ self.assertEqual("<Curve %r>" % (curve.name,), repr(curve))
+
+
+ def test_to_EC_KEY(self):
+ """
+ The curve object can export a version of itself as an EC_KEY* via the
+ private :py:meth:`_EllipticCurve._to_EC_KEY`.
+ """
+ curves = get_elliptic_curves()
+ if curves:
+ curve = next(iter(curves))
+ # It's not easy to assert anything about this object. However, see
+ # leakcheck/crypto.py for a test that demonstrates it at least does
+ # not leak memory.
+ curve._to_EC_KEY()
+
+
if __name__ == '__main__':
main()
diff --git a/OpenSSL/test/test_ssl.py b/OpenSSL/test/test_ssl.py
index fdeff9d..6231143 100644
--- a/OpenSSL/test/test_ssl.py
+++ b/OpenSSL/test/test_ssl.py
@@ -20,6 +20,7 @@
from OpenSSL.crypto import PKey, X509, X509Extension, X509Store
from OpenSSL.crypto import dump_privatekey, load_privatekey
from OpenSSL.crypto import dump_certificate, load_certificate
+from OpenSSL.crypto import get_elliptic_curves
from OpenSSL.SSL import _lib
from OpenSSL.SSL import OPENSSL_VERSION_NUMBER, SSLEAY_VERSION, SSLEAY_CFLAGS
@@ -36,9 +37,6 @@
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 (
- _Cryptography_HAS_EC, ELLIPTIC_CURVE_DESCRIPTIONS,
- ECNotAvailable, UnknownObject, UnsupportedEllipticCurve)
from OpenSSL.SSL import (
Error, SysCallError, WantReadError, WantWriteError, ZeroReturnError)
@@ -1179,101 +1177,13 @@
def test_set_tmp_ecdh_curve(self):
"""
:py:obj:`Context.set_tmp_ecdh_curve` sets the elliptic curve for
- Diffie-Hellman to the specified named curve.
+ Diffie-Hellman to the specified curve.
"""
context = Context(TLSv1_METHOD)
- for curve in ELLIPTIC_CURVE_DESCRIPTIONS.keys():
- context.set_tmp_ecdh_curve(curve) # Must not throw.
-
-
- def test_set_tmp_ecdh_curve_not_available(self):
- """
- :py:obj:`Context.set_tmp_ecdh_curve` raises :py:obj:`ECNotAvailable` if
- elliptic curve support is not available from the underlying OpenSSL
- version at all.
- """
- has_ec = _lib.Cryptography_HAS_EC
- try:
- _lib.Cryptography_HAS_EC = False
-
- context = Context(TLSv1_METHOD)
- self.assertRaises(
- ECNotAvailable,
- context.set_tmp_ecdh_curve, next(iter(ELLIPTIC_CURVE_DESCRIPTIONS)))
- finally:
- _lib.Cryptography_HAS_EC = has_ec
-
-
- def test_set_tmp_ecdh_curve_bad_curve_name(self):
- """
- :py:obj:`Context.set_tmp_ecdh_curve` raises :py:obj:`UnknownObject` if
- passed a curve_name that OpenSSL does not recognize and EC is
- available.
- """
- context = Context(TLSv1_METHOD)
- try:
- context.set_tmp_ecdh_curve('not_an_elliptic_curve')
- except ECNotAvailable:
- self.assertFalse(_Cryptography_HAS_EC)
- except UnknownObject:
- self.assertTrue(_Cryptography_HAS_EC)
- else:
- self.fail(
- "set_tmp_ecdh_curve did not fail when called with "
- "non-existent curve name")
-
-
- def test_set_tmp_ecdh_curve_bad_nid(self):
- """
- :py:obj:`Context._set_tmp_ecdh_curve_by_nid`, an implementation detail
- of :py:obj:`Context.set_tmp_ecdh_curve`, raises
- :py:obj:`UnsupportedEllipticCurve` raises if passed a NID that does not
- identify a supported curve.
- """
- context = Context(TLSv1_METHOD)
- try:
- context._set_tmp_ecdh_curve_by_nid(
- u("curve"), _lib.OBJ_sn2nid(b"sha256"))
- except UnsupportedEllipticCurve:
- pass
- else:
- self.fail(
- "_set_tmp_ecdh_curve_by_nid did not raise "
- "UnsupportedEllipticCurve for a NID that does not "
- "identify a supported curve.")
-
-
- def test_set_tmp_ecdh_curve_not_a_curve(self):
- """
- :py:obj:`Context.set_tmp_ecdh_curve` raises
- :py:obj:`UnsupportedEllipticCurve` if passed a curve_name that OpenSSL
- cannot instantiate as an elliptic curve. It raises
- :py:obj:`ECNotAvailable` if EC is not available at all.
- """
- context = Context(TLSv1_METHOD)
- try:
- context.set_tmp_ecdh_curve('sha256')
- except ECNotAvailable:
- self.assertFalse(_Cryptography_HAS_EC)
- except UnknownObject:
- self.assertTrue(_Cryptography_HAS_EC)
- else:
- self.fail(
- "set_tmp_ecdh_curve did not fail when called with "
- "a name that is not an elliptic curve")
-
-
- def test_has_curve_descriptions(self):
- """
- If the underlying cryptography bindings claim to have elliptic
- curve support, there should be at least one curve.
-
- (In theory there could be an OpenSSL that violates this
- assumption. If so, this test will fail and we'll find out.)
-
- """
- if _Cryptography_HAS_EC:
- self.assertNotEqual(len(ELLIPTIC_CURVE_DESCRIPTIONS), 0)
+ for curve in get_elliptic_curves():
+ # The only easily "assertable" thing is that it does not raise an
+ # exception.
+ context.set_tmp_ecdh_curve(curve)
def test_set_cipher_list_bytes(self):