From 2d5acf3dccc6d340fff8f2429a82b2a535109dfe Mon Sep 17 00:00:00 2001 From: Hubert Kario Date: Fri, 10 Jun 2022 11:44:09 +0200 Subject: add support for finding Curves by name --- src/ecdsa/curves.py | 25 +++++++++++++++++++++++++ src/ecdsa/test_curves.py | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/ecdsa/curves.py b/src/ecdsa/curves.py index ee2849f..191cfab 100644 --- a/src/ecdsa/curves.py +++ b/src/ecdsa/curves.py @@ -23,6 +23,7 @@ __all__ = [ "NIST521p", "curves", "find_curve", + "curve_by_name", "SECP256k1", "BRAINPOOLP160r1", "BRAINPOOLP192r1", @@ -476,3 +477,27 @@ def find_curve(oid_curve): "I don't know about the curve with oid %s." "I only know about these: %s" % (oid_curve, [c.name for c in curves]) ) + + +def curve_by_name(name): + """Select a curve based on its name. + + Returns a :py:class:`~ecdsa.curves.Curve` object with a ``name`` name. + Note that ``name`` is case-sensitve. + + :param str name: Name of the curve to return, like ``NIST256p`` or + ``prime256v1`` + + :raises UnknownCurveError: When the name doesn't match any of the supported + curves + + :rtype: ~ecdsa.curves.Curve + """ + for c in curves: + if name == c.name or (c.openssl_name and name == c.openssl_name): + return c + raise UnknownCurveError( + "Curve with name {0!r} unknown, only curves supported: {1}".format( + name, [c.name for c in curves] + ) + ) diff --git a/src/ecdsa/test_curves.py b/src/ecdsa/test_curves.py index 8b5282b..93b6c9b 100644 --- a/src/ecdsa/test_curves.py +++ b/src/ecdsa/test_curves.py @@ -5,7 +5,14 @@ except ImportError: import base64 import pytest -from .curves import Curve, NIST256p, curves, UnknownCurveError, PRIME_FIELD_OID +from .curves import ( + Curve, + NIST256p, + curves, + UnknownCurveError, + PRIME_FIELD_OID, + curve_by_name, +) from .ellipticcurve import CurveFp, PointJacobi, CurveEdTw from . import der from .util import number_to_string @@ -288,6 +295,36 @@ class TestParameterEncoding(unittest.TestCase): self.assertIn("Prime-p element", str(e.exception)) +class TestCurveSearching(unittest.TestCase): + def test_correct_name(self): + c = curve_by_name("NIST256p") + self.assertIs(c, NIST256p) + + def test_openssl_name(self): + c = curve_by_name("prime256v1") + self.assertIs(c, NIST256p) + + def test_unknown_curve(self): + with self.assertRaises(UnknownCurveError) as e: + curve_by_name("foo bar") + + self.assertIn( + "name 'foo bar' unknown, only curves supported: " + "['NIST192p', 'NIST224p'", + str(e.exception), + ) + + def test_with_None_as_parameter(self): + with self.assertRaises(UnknownCurveError) as e: + curve_by_name(None) + + self.assertIn( + "name None unknown, only curves supported: " + "['NIST192p', 'NIST224p'", + str(e.exception), + ) + + @pytest.mark.parametrize("curve", curves, ids=[i.name for i in curves]) def test_curve_params_encode_decode_named(curve): ret = Curve.from_der(curve.to_der("named_curve")) -- cgit v1.2.1 From 66a5150d7488c5a50b5ae692294629838d0e3ae6 Mon Sep 17 00:00:00 2001 From: Hubert Kario Date: Fri, 10 Jun 2022 11:49:23 +0200 Subject: document find_curve() --- src/ecdsa/curves.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/ecdsa/curves.py b/src/ecdsa/curves.py index 191cfab..1119ee5 100644 --- a/src/ecdsa/curves.py +++ b/src/ecdsa/curves.py @@ -470,6 +470,16 @@ curves = [ def find_curve(oid_curve): + """Select a curve based on its OID + + :param tuple[int,...] oid_curve: ASN.1 Object Identifier of the + curve to return, like ``(1, 2, 840, 10045, 3, 1, 7)`` for ``NIST256p``. + + :raises UnknownCurveError: When the oid doesn't match any of the supported + curves + + :rtype: ~ecdsa.curves.Curve + """ for c in curves: if c.oid == oid_curve: return c -- cgit v1.2.1