11from __future__ import with_statement , division
22
3- import unittest
3+ try :
4+ import unittest2 as unittest
5+ except ImportError :
6+ import unittest
47import os
58import time
69import shutil
1013
1114from .six import b , print_ , binary_type
1215from .keys import SigningKey , VerifyingKey
13- from .keys import BadSignatureError
16+ from .keys import BadSignatureError , MalformedPointError , BadDigestError
1417from . import util
1518from .util import sigencode_der , sigencode_strings
1619from .util import sigdecode_der , sigdecode_strings
20+ from .util import encoded_oid_ecPublicKey , MalformedSignature
1721from .curves import Curve , UnknownCurveError
1822from .curves import NIST192p , NIST224p , NIST256p , NIST384p , NIST521p , SECP256k1
1923from .ellipticcurve import Point
2024from . import der
2125from . import rfc6979
26+ from . import ecdsa
2227
2328class SubprocessError (Exception ):
2429 pass
@@ -258,6 +263,47 @@ def order(self): return 123456789
258263 pub2 = VerifyingKey .from_pem (pem )
259264 self .assertTruePubkeysEqual (pub1 , pub2 )
260265
266+ def test_vk_from_der_garbage_after_curve_oid (self ):
267+ type_oid_der = encoded_oid_ecPublicKey
268+ curve_oid_der = der .encode_oid (* (1 , 2 , 840 , 10045 , 3 , 1 , 1 )) + \
269+ b ('garbage' )
270+ enc_type_der = der .encode_sequence (type_oid_der , curve_oid_der )
271+ point_der = der .encode_bitstring (b'\x00 \xff ' )
272+ to_decode = der .encode_sequence (enc_type_der , point_der )
273+
274+ with self .assertRaises (der .UnexpectedDER ):
275+ VerifyingKey .from_der (to_decode )
276+
277+ def test_vk_from_der_invalid_key_type (self ):
278+ type_oid_der = der .encode_oid (* (1 , 2 , 3 ))
279+ curve_oid_der = der .encode_oid (* (1 , 2 , 840 , 10045 , 3 , 1 , 1 ))
280+ enc_type_der = der .encode_sequence (type_oid_der , curve_oid_der )
281+ point_der = der .encode_bitstring (b'\x00 \xff ' )
282+ to_decode = der .encode_sequence (enc_type_der , point_der )
283+
284+ with self .assertRaises (der .UnexpectedDER ):
285+ VerifyingKey .from_der (to_decode )
286+
287+ def test_vk_from_der_garbage_after_point_string (self ):
288+ type_oid_der = encoded_oid_ecPublicKey
289+ curve_oid_der = der .encode_oid (* (1 , 2 , 840 , 10045 , 3 , 1 , 1 ))
290+ enc_type_der = der .encode_sequence (type_oid_der , curve_oid_der )
291+ point_der = der .encode_bitstring (b'\x00 \xff ' ) + b ('garbage' )
292+ to_decode = der .encode_sequence (enc_type_der , point_der )
293+
294+ with self .assertRaises (der .UnexpectedDER ):
295+ VerifyingKey .from_der (to_decode )
296+
297+ def test_vk_from_der_invalid_bitstring (self ):
298+ type_oid_der = encoded_oid_ecPublicKey
299+ curve_oid_der = der .encode_oid (* (1 , 2 , 840 , 10045 , 3 , 1 , 1 ))
300+ enc_type_der = der .encode_sequence (type_oid_der , curve_oid_der )
301+ point_der = der .encode_bitstring (b'\x08 \xff ' )
302+ to_decode = der .encode_sequence (enc_type_der , point_der )
303+
304+ with self .assertRaises (der .UnexpectedDER ):
305+ VerifyingKey .from_der (to_decode )
306+
261307 def test_signature_strings (self ):
262308 priv1 = SigningKey .generate ()
263309 pub1 = priv1 .get_verifying_key ()
@@ -281,6 +327,86 @@ def test_signature_strings(self):
281327 self .assertEqual (type (sig_der ), binary_type )
282328 self .assertTrue (pub1 .verify (sig_der , data , sigdecode = sigdecode_der ))
283329
330+ def test_sig_decode_strings_with_invalid_count (self ):
331+ with self .assertRaises (MalformedSignature ):
332+ sigdecode_strings ([b ('one' ), b ('two' ), b ('three' )], 0xff )
333+
334+ def test_sig_decode_strings_with_wrong_r_len (self ):
335+ with self .assertRaises (MalformedSignature ):
336+ sigdecode_strings ([b ('one' ), b ('two' )], 0xff )
337+
338+ def test_sig_decode_strings_with_wrong_s_len (self ):
339+ with self .assertRaises (MalformedSignature ):
340+ sigdecode_strings ([b ('\xa0 ' ), b ('\xb0 \xff ' )], 0xff )
341+
342+ def test_verify_with_too_long_input (self ):
343+ sk = SigningKey .generate ()
344+ vk = sk .verifying_key
345+
346+ with self .assertRaises (BadDigestError ):
347+ vk .verify_digest (None , b ('\x00 ' ) * 128 )
348+
349+ def test_sk_from_secret_exponent_with_wrong_sec_exponent (self ):
350+ with self .assertRaises (MalformedPointError ):
351+ SigningKey .from_secret_exponent (0 )
352+
353+ def test_sk_from_string_with_wrong_len_string (self ):
354+ with self .assertRaises (MalformedPointError ):
355+ SigningKey .from_string (b ('\x01 ' ))
356+
357+ def test_sk_from_der_with_junk_after_sequence (self ):
358+ ver_der = der .encode_integer (1 )
359+ to_decode = der .encode_sequence (ver_der ) + b ('garbage' )
360+
361+ with self .assertRaises (der .UnexpectedDER ):
362+ SigningKey .from_der (to_decode )
363+
364+ def test_sk_from_der_with_wrong_version (self ):
365+ ver_der = der .encode_integer (0 )
366+ to_decode = der .encode_sequence (ver_der )
367+
368+ with self .assertRaises (der .UnexpectedDER ):
369+ SigningKey .from_der (to_decode )
370+
371+ def test_sk_from_der_invalid_const_tag (self ):
372+ ver_der = der .encode_integer (1 )
373+ privkey_der = der .encode_octet_string (b ('\x00 \xff ' ))
374+ curve_oid_der = der .encode_oid (* (1 , 2 , 3 ))
375+ const_der = der .encode_constructed (1 , curve_oid_der )
376+ to_decode = der .encode_sequence (ver_der , privkey_der , const_der ,
377+ curve_oid_der )
378+
379+ with self .assertRaises (der .UnexpectedDER ):
380+ SigningKey .from_der (to_decode )
381+
382+ def test_sk_from_der_garbage_after_privkey_oid (self ):
383+ ver_der = der .encode_integer (1 )
384+ privkey_der = der .encode_octet_string (b ('\x00 \xff ' ))
385+ curve_oid_der = der .encode_oid (* (1 , 2 , 3 )) + b ('garbage' )
386+ const_der = der .encode_constructed (0 , curve_oid_der )
387+ to_decode = der .encode_sequence (ver_der , privkey_der , const_der ,
388+ curve_oid_der )
389+
390+ with self .assertRaises (der .UnexpectedDER ):
391+ SigningKey .from_der (to_decode )
392+
393+ def test_sk_from_der_with_short_privkey (self ):
394+ ver_der = der .encode_integer (1 )
395+ privkey_der = der .encode_octet_string (b ('\x00 \xff ' ))
396+ curve_oid_der = der .encode_oid (* (1 , 2 , 840 , 10045 , 3 , 1 , 1 ))
397+ const_der = der .encode_constructed (0 , curve_oid_der )
398+ to_decode = der .encode_sequence (ver_der , privkey_der , const_der ,
399+ curve_oid_der )
400+
401+ sk = SigningKey .from_der (to_decode )
402+ self .assertEqual (sk .privkey .secret_multiplier , 255 )
403+
404+ def test_sign_with_too_long_hash (self ):
405+ sk = SigningKey .from_secret_exponent (12 )
406+
407+ with self .assertRaises (BadDigestError ):
408+ sk .sign_digest (b ('\xff ' ) * 64 )
409+
284410 def test_hashfunc (self ):
285411 sk = SigningKey .generate (curve = NIST256p , hashfunc = sha256 )
286412 data = b ("security level is 128 bits" )
@@ -299,6 +425,49 @@ def test_hashfunc(self):
299425 curve = NIST256p )
300426 self .assertTrue (vk3 .verify (sig , data , hashfunc = sha256 ))
301427
428+ def test_decoding_with_malformed_uncompressed (self ):
429+ enc = b ('\x0c \xe0 \x1d \xe0 d\x1c \x8e S\x8a \xc0 \x9e K\xa8 x !\xd5 \xc2 \xc3 '
430+ '\xfd \xc8 \xa0 c\xff \xfb \x02 \xb9 \xc4 \x84 )\x1a \x0f \x8b \x87 \xa4 '
431+ 'z\x8a #\xb5 \x97 \xec O\xb6 \xa0 HQ\x89 *' )
432+
433+ with self .assertRaises (MalformedPointError ):
434+ VerifyingKey .from_string (b ('\x02 ' ) + enc )
435+
436+ def test_decoding_with_point_not_on_curve (self ):
437+ enc = b ('\x0c \xe0 \x1d \xe0 d\x1c \x8e S\x8a \xc0 \x9e K\xa8 x !\xd5 \xc2 \xc3 '
438+ '\xfd \xc8 \xa0 c\xff \xfb \x02 \xb9 \xc4 \x84 )\x1a \x0f \x8b \x87 \xa4 '
439+ 'z\x8a #\xb5 \x97 \xec O\xb6 \xa0 HQ\x89 *' )
440+
441+ with self .assertRaises (MalformedPointError ):
442+ VerifyingKey .from_string (enc [:47 ] + b ('\x00 ' ))
443+
444+ def test_decoding_with_point_at_infinity (self ):
445+ # decoding it is unsupported, as it's not necessary to encode it
446+ with self .assertRaises (MalformedPointError ):
447+ VerifyingKey .from_string (b ('\x00 ' ))
448+
449+ def test_from_string_with_invalid_curve_too_short_ver_key_len (self ):
450+ # both verifying_key_length and baselen are calculated internally
451+ # by the Curve constructor, but since we depend on them verify
452+ # that inconsistent values are detected
453+ curve = Curve ("test" , ecdsa .curve_192 , ecdsa .generator_192 , (1 , 2 ))
454+ curve .verifying_key_length = 16
455+ curve .baselen = 32
456+
457+ with self .assertRaises (MalformedPointError ):
458+ VerifyingKey .from_string (b ('\x00 ' )* 16 , curve )
459+
460+ def test_from_string_with_invalid_curve_too_long_ver_key_len (self ):
461+ # both verifying_key_length and baselen are calculated internally
462+ # by the Curve constructor, but since we depend on them verify
463+ # that inconsistent values are detected
464+ curve = Curve ("test" , ecdsa .curve_192 , ecdsa .generator_192 , (1 , 2 ))
465+ curve .verifying_key_length = 16
466+ curve .baselen = 16
467+
468+ with self .assertRaises (MalformedPointError ):
469+ VerifyingKey .from_string (b ('\x00 ' )* 16 , curve )
470+
302471
303472class OpenSSL (unittest .TestCase ):
304473 # test interoperability with OpenSSL tools. Note that openssl's ECDSA
0 commit comments