Skip to content

Commit 5242773

Browse files
authored
Merge pull request #298 from tlsfuzzer/curve-by-name
Selecting curve by name
2 parents 522f480 + 66a5150 commit 5242773

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

src/ecdsa/curves.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"NIST521p",
2424
"curves",
2525
"find_curve",
26+
"curve_by_name",
2627
"SECP256k1",
2728
"BRAINPOOLP160r1",
2829
"BRAINPOOLP192r1",
@@ -469,10 +470,44 @@ def from_pem(cls, string, valid_encodings=None):
469470

470471

471472
def find_curve(oid_curve):
473+
"""Select a curve based on its OID
474+
475+
:param tuple[int,...] oid_curve: ASN.1 Object Identifier of the
476+
curve to return, like ``(1, 2, 840, 10045, 3, 1, 7)`` for ``NIST256p``.
477+
478+
:raises UnknownCurveError: When the oid doesn't match any of the supported
479+
curves
480+
481+
:rtype: ~ecdsa.curves.Curve
482+
"""
472483
for c in curves:
473484
if c.oid == oid_curve:
474485
return c
475486
raise UnknownCurveError(
476487
"I don't know about the curve with oid %s."
477488
"I only know about these: %s" % (oid_curve, [c.name for c in curves])
478489
)
490+
491+
492+
def curve_by_name(name):
493+
"""Select a curve based on its name.
494+
495+
Returns a :py:class:`~ecdsa.curves.Curve` object with a ``name`` name.
496+
Note that ``name`` is case-sensitve.
497+
498+
:param str name: Name of the curve to return, like ``NIST256p`` or
499+
``prime256v1``
500+
501+
:raises UnknownCurveError: When the name doesn't match any of the supported
502+
curves
503+
504+
:rtype: ~ecdsa.curves.Curve
505+
"""
506+
for c in curves:
507+
if name == c.name or (c.openssl_name and name == c.openssl_name):
508+
return c
509+
raise UnknownCurveError(
510+
"Curve with name {0!r} unknown, only curves supported: {1}".format(
511+
name, [c.name for c in curves]
512+
)
513+
)

src/ecdsa/test_curves.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,14 @@
55

66
import base64
77
import pytest
8-
from .curves import Curve, NIST256p, curves, UnknownCurveError, PRIME_FIELD_OID
8+
from .curves import (
9+
Curve,
10+
NIST256p,
11+
curves,
12+
UnknownCurveError,
13+
PRIME_FIELD_OID,
14+
curve_by_name,
15+
)
916
from .ellipticcurve import CurveFp, PointJacobi, CurveEdTw
1017
from . import der
1118
from .util import number_to_string
@@ -288,6 +295,36 @@ def test_decode_malformed_garbage_after_prime(self):
288295
self.assertIn("Prime-p element", str(e.exception))
289296

290297

298+
class TestCurveSearching(unittest.TestCase):
299+
def test_correct_name(self):
300+
c = curve_by_name("NIST256p")
301+
self.assertIs(c, NIST256p)
302+
303+
def test_openssl_name(self):
304+
c = curve_by_name("prime256v1")
305+
self.assertIs(c, NIST256p)
306+
307+
def test_unknown_curve(self):
308+
with self.assertRaises(UnknownCurveError) as e:
309+
curve_by_name("foo bar")
310+
311+
self.assertIn(
312+
"name 'foo bar' unknown, only curves supported: "
313+
"['NIST192p', 'NIST224p'",
314+
str(e.exception),
315+
)
316+
317+
def test_with_None_as_parameter(self):
318+
with self.assertRaises(UnknownCurveError) as e:
319+
curve_by_name(None)
320+
321+
self.assertIn(
322+
"name None unknown, only curves supported: "
323+
"['NIST192p', 'NIST224p'",
324+
str(e.exception),
325+
)
326+
327+
291328
@pytest.mark.parametrize("curve", curves, ids=[i.name for i in curves])
292329
def test_curve_params_encode_decode_named(curve):
293330
ret = Curve.from_der(curve.to_der("named_curve"))

0 commit comments

Comments
 (0)