Skip to content

Commit

Permalink
translate the UnexpectedDER exception to BadSignatureError
Browse files Browse the repository at this point in the history
the users of VerifyingKey.verify() and VerifyingKey.verify_digest()
should not need to use multiple exceptions to correctly catch invalid
signatures

backport of 487f6d3
  • Loading branch information
tomato42 committed Oct 7, 2019
1 parent b0ea52b commit 20b3774
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 2 deletions.
7 changes: 5 additions & 2 deletions ecdsa/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,14 @@ def verify_digest(self, signature, digest, sigdecode=sigdecode_string):
"for your digest (%d)" % (self.curve.name,
8*len(digest)))
number = string_to_number(digest)
r, s = sigdecode(signature, self.pubkey.order)
try:
r, s = sigdecode(signature, self.pubkey.order)
except der.UnexpectedDER as e:
raise BadSignatureError("Malformed formatting of signature", e)
sig = ecdsa.Signature(r, s)
if self.pubkey.verifies(number, sig):
return True
raise BadSignatureError
raise BadSignatureError("Signature verification failed")

class SigningKey:
def __init__(self, _error__please_use_generate=None):
Expand Down
68 changes: 68 additions & 0 deletions ecdsa/test_malformed_sigs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from __future__ import with_statement, division

import unittest
import os
import time
import shutil
import subprocess
import pytest
from binascii import hexlify, unhexlify
from hashlib import sha1, sha256, sha512
import hashlib

from six import b, binary_type
from .keys import SigningKey, VerifyingKey
from .keys import BadSignatureError
from . import util
from .util import sigencode_der, sigencode_strings
from .util import sigdecode_der, sigdecode_strings
from .curves import curves, NIST256p, NIST521p
from .ellipticcurve import Point
from . import der
from . import rfc6979
import copy

sigs = []
example_data = b("some data to sign")

# Just NIST256p with SHA256 is 560 test cases, all curves with all hashes is
# few thousand slow test cases; execute the most interesting only

#for curve in curves:
for curve in [NIST256p]:
#for hash_alg in ["md5", "sha1", "sha224", "sha256", "sha384", "sha512"]:
for hash_alg in ["sha256"]:
key = SigningKey.generate(curve)
signature = key.sign(example_data, hashfunc=getattr(hashlib, hash_alg),
sigencode=sigencode_der)
for pos in range(len(signature)):
for xor in (1<<i for i in range(8)):
sigs.append(pytest.param(
key.verifying_key, hash_alg,
signature, pos, xor,
id="{0}-{1}-pos-{2}-xor-{3}".format(
curve.name, hash_alg, pos, xor)))


@pytest.mark.parametrize("verifying_key,hash_alg,signature,pos,xor", sigs)
def test_fuzzed_der_signatures(verifying_key, hash_alg, signature, pos, xor):
# check if a malformed DER encoded signature causes the same exception
# to be raised irrespective of the type of error
sig = bytearray(signature)
sig[pos] ^= xor
sig = binary_type(sig)

try:
verifying_key.verify(sig, example_data, getattr(hashlib, hash_alg),
sigdecode_der)
assert False
except BadSignatureError:
assert True


def __main__():
unittest.main()


if __name__ == "__main__":
__main__()

0 comments on commit 20b3774

Please sign in to comment.