Skip to content

Commit 487f6d3

Browse files
committed
translate the UnexpectedDER exception to BadSignatureError
the users of VerifyingKey.verify() and VerifyingKey.verify_digest() should not need to use multiple exceptions to correctly catch invalid signatures
1 parent 9916c85 commit 487f6d3

File tree

2 files changed

+73
-2
lines changed

2 files changed

+73
-2
lines changed

src/ecdsa/keys.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,14 @@ def verify_digest(self, signature, digest, sigdecode=sigdecode_string):
136136
"for your digest (%d)" % (self.curve.name,
137137
8 * len(digest)))
138138
number = string_to_number(digest)
139-
r, s = sigdecode(signature, self.pubkey.order)
139+
try:
140+
r, s = sigdecode(signature, self.pubkey.order)
141+
except der.UnexpectedDER as e:
142+
raise BadSignatureError("Malformed formatting of signature", e)
140143
sig = ecdsa.Signature(r, s)
141144
if self.pubkey.verifies(number, sig):
142145
return True
143-
raise BadSignatureError
146+
raise BadSignatureError("Signature verification failed")
144147

145148

146149
class SigningKey:

src/ecdsa/test_malformed_sigs.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
from __future__ import with_statement, division
2+
3+
import unittest
4+
import os
5+
import time
6+
import shutil
7+
import subprocess
8+
import pytest
9+
from binascii import hexlify, unhexlify
10+
from hashlib import sha1, sha256, sha512
11+
import hashlib
12+
13+
from six import b, binary_type
14+
from .keys import SigningKey, VerifyingKey
15+
from .keys import BadSignatureError
16+
from . import util
17+
from .util import sigencode_der, sigencode_strings
18+
from .util import sigdecode_der, sigdecode_strings
19+
from .curves import curves, NIST256p, NIST521p
20+
from .ellipticcurve import Point
21+
from . import der
22+
from . import rfc6979
23+
import copy
24+
25+
sigs = []
26+
example_data = b("some data to sign")
27+
28+
# Just NIST256p with SHA256 is 560 test cases, all curves with all hashes is
29+
# few thousand slow test cases; execute the most interesting only
30+
31+
#for curve in curves:
32+
for curve in [NIST256p]:
33+
#for hash_alg in ["md5", "sha1", "sha224", "sha256", "sha384", "sha512"]:
34+
for hash_alg in ["sha256"]:
35+
key = SigningKey.generate(curve)
36+
signature = key.sign(example_data, hashfunc=getattr(hashlib, hash_alg),
37+
sigencode=sigencode_der)
38+
for pos in range(len(signature)):
39+
for xor in (1<<i for i in range(8)):
40+
sigs.append(pytest.param(
41+
key.verifying_key, hash_alg,
42+
signature, pos, xor,
43+
id="{0}-{1}-pos-{2}-xor-{3}".format(
44+
curve.name, hash_alg, pos, xor)))
45+
46+
47+
@pytest.mark.parametrize("verifying_key,hash_alg,signature,pos,xor", sigs)
48+
def test_fuzzed_der_signatures(verifying_key, hash_alg, signature, pos, xor):
49+
# check if a malformed DER encoded signature causes the same exception
50+
# to be raised irrespective of the type of error
51+
sig = bytearray(signature)
52+
sig[pos] ^= xor
53+
sig = binary_type(sig)
54+
55+
try:
56+
verifying_key.verify(sig, example_data, getattr(hashlib, hash_alg),
57+
sigdecode_der)
58+
assert False
59+
except BadSignatureError:
60+
assert True
61+
62+
63+
def __main__():
64+
unittest.main()
65+
66+
67+
if __name__ == "__main__":
68+
__main__()

0 commit comments

Comments
 (0)