Skip to content

Commit d1670c7

Browse files
committed
code reuse for ASN.1 formatting
reuse the new to_string and from_string to support saving and reading the public key in PEM and DER files with both compressed and uncompressed point encoding
1 parent fc91378 commit d1670c7

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

src/ecdsa/keys.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,20 @@ def from_der(klass, string):
121121
if empty != b(""):
122122
raise der.UnexpectedDER("trailing junk after DER pubkey objects: %s" %
123123
binascii.hexlify(empty))
124-
assert oid_pk == oid_ecPublicKey, (oid_pk, oid_ecPublicKey)
124+
if not oid_pk == oid_ecPublicKey:
125+
raise der.UnexpectedDER("Unexpected object identifier in DER "
126+
"encoding: {0!r}".format(oid_pk))
125127
curve = find_curve(oid_curve)
126128
point_str, empty = der.remove_bitstring(point_str_bitstring)
127129
if empty != b(""):
128130
raise der.UnexpectedDER("trailing junk after pubkey pointstring: %s" %
129131
binascii.hexlify(empty))
130-
assert point_str.startswith(b("\x00\x04"))
131-
return klass.from_string(point_str[2:], curve)
132+
# the point encoding is padded with a zero byte
133+
# raw encoding of point is invalid in DER files
134+
if not point_str.startswith(b("\x00")) or \
135+
len(point_str[1:]) == curve.verifying_key_length:
136+
raise der.UnexpectedDER("Malformed encoding of public point")
137+
return klass.from_string(point_str[1:], curve)
132138

133139
@classmethod
134140
def from_public_key_recovery(cls, signature, data, curve, hashfunc=sha1,
@@ -186,11 +192,11 @@ def to_string(self, encoding="raw"):
186192
def to_pem(self):
187193
return der.topem(self.to_der(), "PUBLIC KEY")
188194

189-
def to_der(self):
195+
def to_der(self, point_encoding="uncompressed"):
190196
order = self.pubkey.order
191197
x_str = number_to_string(self.pubkey.point.x(), order)
192198
y_str = number_to_string(self.pubkey.point.y(), order)
193-
point_str = b("\x00\x04") + x_str + y_str
199+
point_str = b("\x00") + self.to_string(point_encoding)
194200
return der.encode_sequence(der.encode_sequence(encoded_oid_ecPublicKey,
195201
self.curve.encoded_oid),
196202
der.encode_bitstring(point_str))
@@ -311,10 +317,11 @@ def to_pem(self):
311317
# TODO: "BEGIN ECPARAMETERS"
312318
return der.topem(self.to_der(), "EC PRIVATE KEY")
313319

314-
def to_der(self):
320+
def to_der(self, point_encoding="uncompressed"):
315321
# SEQ([int(1), octetstring(privkey),cont[0], oid(secp224r1),
316322
# cont[1],bitstring])
317-
encoded_vk = b("\x00\x04") + self.get_verifying_key().to_string()
323+
encoded_vk = b("\x00") + \
324+
self.get_verifying_key().to_string(point_encoding)
318325
return der.encode_sequence(der.encode_integer(1),
319326
der.encode_octet_string(self.to_string()),
320327
der.encode_constructed(0, self.curve.encoded_oid),

0 commit comments

Comments
 (0)