8000 support for PEM format for EC parameters · tlsfuzzer/python-ecdsa@5ddcd9b · GitHub
[go: up one dir, main page]

Skip to content

Commit 5ddcd9b

Browse files
committed
support for PEM format for EC parameters
1 parent 078882e commit 5ddcd9b

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

src/ecdsa/curves.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import division
22

3+
from six import PY2
34
from . import der, ecdsa, ellipticcurve
45
from .util import orderlen, number_to_string, string_to_number
56
from ._compat import normalise_bytes
@@ -79,6 +80,9 @@ def to_der(self, encoding=None, point_encoding="uncompressed"):
7980
:param str point_encoding: the point encoding of the generator when
8081
explicit curve encoding is used. Ignored for ``named_curve``
8182
format.
83+
84+
:return: DER encoded ECParameters structure
85+
:rtype: bytes
8286
"""
8387
if encoding is None:
8488
if self.oid:
@@ -117,6 +121,24 @@ def to_der(self, encoding=None, point_encoding="uncompressed"):
117121

118122
return der.encode_sequence(*seq_elements)
119123

124+
def to_pem(self, encoding=None, point_encoding="uncompressed"):
125+
"""
126+
Serialise the curve parameters to the :term:`PEM` format.
127+
128+
:param str encoding: the format to save the curve parameters in.
129+
Default is ``named_curve``, with fallback being the ``explicit``
130+
if the OID is not set for the curve.
131+
:param str point_encoding: the point encoding of the generator when
132+
explicit curve encoding is used. Ignored for ``named_curve``
133+
format.
134+
135+
:return: PEM encoded ECParameters structure
136+
:rtype: str
137+
"""
138+
return der.topem(
139+
self.to_der(encoding, point_encoding), "EC PARAMETERS"
140+
)
141+
120142
@staticmethod
121143
def from_der(data):
122144
"""Decode the curve parameters from DER file.
@@ -190,6 +212,21 @@ def from_der(data):
190212
return i
191213
return tmp_curve
192214

215+
@classmethod
216+
def from_pem(cls, string):
217+
"""Decode the curve parameters from PEM file.
218+
219+
:param str string: the text string to decode the parameters from
220+
"""
221+
if not PY2 and isinstance(string, str): # pragma: no branch
222+
string = string.encode()
223+
224+
ec_param_index = string.find(b"-----BEGIN EC PARAMETERS-----")
225+
if ec_param_index == -1:
226+
raise der.UnexpectedDER("EC PARAMETERS PEM header not found")
227+
228+
return cls.from_der(der.unpem(string[ec_param_index:]))
229+
193230

194231
# the SEC curves
195232
SECP112r1 = Curve(

src/ecdsa/test_curves.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,45 @@ def setUpClass(cls):
2424
"AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQE="
2525
)
2626

27+
def test_from_pem(self):
28+
pem_params = (
29+
"-----BEGIN EC PARAMETERS-----\n"
30+
"MIHgAgEBMCwGByqGSM49AQECIQD/////AAAAAQAAAAAAAAAAAAAAAP/////////\n"
31+
"//////zBEBCD/////AAAAAQAAAAAAAAAAAAAAAP///////////////AQgWsY12K\n"
32+
"o6k+ez671VdpiGvGUdBrDMU7D2O848PifSYEsEQQRrF9Hy4SxCR/i85uVjpEDyd\n"
33+
"wN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1\n"
34+
"AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQE=\n"
35+
"-----END EC PARAMETERS-----\n"
36+
)
37+
curve = Curve.from_pem(pem_params)
38+
39+
self.assertIs(curve, NIST256p)
40+
41+
def test_from_pem_with_wrong_header(self):
42+
pem_params = (
43+
"-----BEGIN PARAMETERS-----\n"
44+
"MIHgAgEBMCwGByqGSM49AQECIQD/////AAAAAQAAAAAAAAAAAAAAAP/////////\n"
45+
"//////zBEBCD/////AAAAAQAAAAAAAAAAAAAAAP///////////////AQgWsY12K\n"
46+
"o6k+ez671VdpiGvGUdBrDMU7D2O848PifSYEsEQQRrF9Hy4SxCR/i85uVjpEDyd\n"
47+
"wN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1\n"
48+
"AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQE=\n"
49+
"-----END PARAMETERS-----\n"
50+
)
51+
with self.assertRaises(der.UnexpectedDER) as e:
52+
Curve.from_pem(pem_params)
53+
54+
self.assertIn("PARAMETERS PEM header", str(e.exception))
55+
56+
def test_to_pem(self):
57+
pem_params = (
58+
b"-----BEGIN EC PARAMETERS-----\n"
59+
b"BggqhkjOPQMBBw==\n"
60+
b"-----END EC PARAMETERS-----\n"
61+
)
62+
encoding = NIST256p.to_pem()
63+
64+
self.assertEqual(pem_params, encoding)
65+
2766
def test_compare_with_different_object(self):
2867
self.assertNotEqual(NIST256p, 256)
2968

0 commit comments

Comments
 (0)
0