1
1
from __future__ import with_statement , division
2
2
3
- import unittest
3
+ try :
4
+ import unittest2 as unittest
5
+ except ImportError :
6
+ import unittest
4
7
import os
5
8
import time
6
9
import shutil
10
13
11
14
from .six import b , print_ , binary_type
12
15
from .keys import SigningKey , VerifyingKey
13
- from .keys import BadSignatureError
16
+ from .keys import BadSignatureError , MalformedPointError , BadDigestError
14
17
from . import util
15
18
from .util import sigencode_der , sigencode_strings
16
19
from .util import sigdecode_der , sigdecode_strings
20
+ from .util import encoded_oid_ecPublicKey , MalformedSignature
17
21
from .curves import Curve , UnknownCurveError
18
22
from .curves import NIST192p , NIST224p , NIST256p , NIST384p , NIST521p , SECP256k1
19
23
from .ellipticcurve import Point
20
24
from . import der
21
25
from . import rfc6979
26
+ from . import ecdsa
22
27
23
28
class SubprocessError (Exception ):
24
29
pass
@@ -258,6 +263,47 @@ def order(self): return 123456789
258
263
pub2 = VerifyingKey .from_pem (pem )
259
264
self .assertTruePubkeysEqual (pub1 , pub2 )
260
265
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
+
261
307
def test_signature_strings (self ):
262
308
priv1 = SigningKey .generate ()
263
309
pub1 = priv1 .get_verifying_key ()
@@ -281,6 +327,86 @@ def test_signature_strings(self):
281
327
self .assertEqual (type (sig_der ), binary_type )
282
328
self .assertTrue (pub1 .verify (sig_der , data , sigdecode = sigdecode_der ))
283
329
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
+
284
410
def test_hashfunc (self ):
285
411
sk = SigningKey .generate (curve = NIST256p , hashfunc = sha256 )
286
412
data = b ("security level is 128 bits" )
@@ -299,6 +425,49 @@ def test_hashfunc(self):
299
425
curve = NIST256p )
300
426
self .assertTrue (vk3 .verify (sig , data , hashfunc = sha256 ))
301
427
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
+
302
471
303
472
class OpenSSL (unittest .TestCase ):
304
473
# test interoperability with OpenSSL tools. Note that openssl's ECDSA
0 commit comments