Skip to content

Commit 20b3774

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 backport of 487f6d3
1 parent b0ea52b commit 20b3774

File tree

2 files changed

+73
-2
lines changed

2 files changed

+73
-2
lines changed

ecdsa/keys.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,14 @@ def verify_digest(self, signature, digest, sigdecode=sigdecode_string):
106106
"for your digest (%d)" % (self.curve.name,
107107
8*len(digest)))
108108
number = string_to_number(digest)
109-
r, s = sigdecode(signature, self.pubkey.order)
109+
try:
110+
r, s = sigdecode(signature, self.pubkey.order)
111+
except der.UnexpectedDER as e:
112+
raise BadSignatureError("Malformed formatting of signature", e)
110113
sig = ecdsa.Signature(r, s)
111114
if self.pubkey.verifies(number, sig):
112115
return True
113-
raise BadSignatureError
116+
raise BadSignatureError("Signature verification failed")
114117

115118
class SigningKey:
116119
def __init__(self, _error__please_use_generate=None):

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)