64
64
string) is endianess dependant! Signature computed over ``array.array``
65
65
of integers on a big-endian system will not be verified on a
66
66
little-endian system and vice-versa.
67
+
68
+ set-like object
69
+ All the types that support the ``in`` operator, like ``list``,
70
+ ``tuple``, ``set``, ``frozenset``, etc.
67
71
"""
68
72
69
73
import binascii
@@ -332,7 +336,12 @@ def _from_hybrid(cls, string, curve, validate_point):
332
336
333
337
@classmethod
334
338
def from_string (
335
- cls , string , curve = NIST192p , hashfunc = sha1 , validate_point = True
339
+ cls ,
340
+ string ,
341
+ curve = NIST192p ,
342
+ hashfunc = sha1 ,
343
+ validate_point = True ,
344
+ valid_encodings = None ,
336
345
):
337
346
"""
338
347
Initialise the object from byte encoding of public key.
@@ -355,38 +364,55 @@ def from_string(
355
364
:param validate_point: whether to verify that the point lays on the
356
365
provided curve or not, defaults to True
357
366
:type validate_point: bool
367
+ :param valid_encodings: list of acceptable point encoding formats,
368
+ supported ones are: :term:`uncompressed`, :term:`compressed`,
369
+ :term:`hybrid`, and :term:`raw encoding` (specified with ``raw``
370
+ name). All formats by default (specified with ``None``).
371
+ :type valid_encodings: :term:`set-like object`
358
372
359
373
:raises MalformedPointError: if the public point does not lay on the
360
374
curve or the encoding is invalid
361
375
362
376
:return: Initialised VerifyingKey object
363
377
:rtype: VerifyingKey
364
378
"""
379
+ if valid_encodings is None :
380
+ valid_encodings = set (
381
+ ["uncompressed" , "compressed" , "hybrid" , "raw" ]
382
+ )
365
383
string = normalise_bytes (string )
366
384
sig_len = len (string )
367
- if sig_len == curve .verifying_key_length :
385
+ if sig_len == curve .verifying_key_length and "raw" in valid_encodings :
368
386
point = cls ._from_raw_encoding (string , curve )
369
- elif sig_len == curve .verifying_key_length + 1 :
370
- if string [:1 ] in (b ("\x06 " ), b ("\x07 " )):
387
+ elif sig_len == curve .verifying_key_length + 1 and (
388
+ "hybrid" in valid_encodings or "uncompressed" in valid_encodings
389
+ ):
390
+ if (
391
+ string [:1 ] in (b ("\x06 " ), b ("\x07 " ))
392
+ and "hybrid" in valid_encodings
393
+ ):
371
394
point = cls ._from_hybrid (string , curve , validate_point )
372
- elif string [:1 ] == b ("\x04 " ):
395
+ elif string [:1 ] == b ("\x04 " ) and "uncompressed" in valid_encodings :
373
396
point = cls ._from_raw_encoding (string [1 :], curve )
374
397
else :
375
398
raise MalformedPointError (
376
399
"Invalid X9.62 encoding of the public point"
377
400
)
378
- elif sig_len == curve .verifying_key_length // 2 + 1 :
401
+ elif (
402
+ sig_len == curve .verifying_key_length // 2 + 1
403
+ and "compressed" in valid_encodings
404
+ ):
379
405
point = cls ._from_compressed (string , curve )
380
406
else :
381
407
raise MalformedPointError (
382
408
"Length of string does not match lengths of "
383
- "any of the supported encodings of {0} "
384
- "curve." .format (curve .name )
409
+ "any of the enabled ({1}) encodings of {0} "
410
+ "curve." .format (curve .name , ", " . join ( valid_encodings ) )
385
411
)
386
412
return cls .from_public_point (point , curve , hashfunc , validate_point )
387
413
388
414
@classmethod
389
- def from_pem (cls , string , hashfunc = sha1 ):
415
+ def from_pem (cls , string , hashfunc = sha1 , valid_encodings = None ):
390
416
"""
391
417
Initialise from public key stored in :term:`PEM` format.
392
418
@@ -400,14 +426,23 @@ def from_pem(cls, string, hashfunc=sha1):
400
426
401
427
:param string: text with PEM-encoded public ECDSA key
402
428
:type string: str
429
+ :param valid_encodings: list of allowed point encodings.
430
+ By default :term:`uncompressed`, :term:`compressed`, and
431
+ :term:`hybrid`. To read malformed files, include
432
+ :term:`raw encoding` with ``raw`` in the list.
433
+ :type valid_encodings: :term:`set-like object
403
434
404
435
:return: Initialised VerifyingKey object
405
436
:rtype: VerifyingKey
406
437
"""
407
- return cls .from_der (der .unpem (string ), hashfunc = hashfunc )
438
+ return cls .from_der (
439
+ der .unpem (string ),
440
+ hashfunc = hashfunc ,
441
+ valid_encodings = valid_encodings ,
442
+ )
408
443
409
444
@classmethod
410
- def from_der (cls , string , hashfunc = sha1 ):
445
+ def from_der (cls , string , hashfunc = sha1 , valid_encodings = None ):
411
446
"""
412
447
Initialise the key stored in :term:`DER` format.
413
448
@@ -432,10 +467,17 @@ def from_der(cls, string, hashfunc=sha1):
432
467
433
468
:param string: binary string with the DER encoding of public ECDSA key
434
469
:type string: bytes-like object
470
+ :param valid_encodings: list of allowed point encodings.
471
+ By default :term:`uncompressed`, :term:`compressed`, and
472
+ :term:`hybrid`. To read malformed files, include
473
+ :term:`raw encoding` with ``raw`` in the list.
474
+ :type valid_encodings: :term:`set-like object
435
475
436
476
:return: Initialised VerifyingKey object
437
477
:rtype: VerifyingKey
438
478
"""
479
+ if valid_encodings is None :
480
+ valid_encodings = set (["uncompressed" , "compressed" , "hybrid" ])
439
481
string = normalise_bytes (string )
440
482
# [[oid_ecPublicKey,oid_curve], point_str_bitstring]
441
483
s1 , empty = der .remove_sequence (string )
@@ -467,7 +509,12 @@ def from_der(cls, string, hashfunc=sha1):
467
509
# raw encoding of point is invalid in DER files
468
510
if len (point_str ) == curve .verifying_key_length :
469
511
raise der .UnexpectedDER ("Malformed encoding of public point" )
470
- return cls .from_string (point_str , curve , hashfunc = hashfunc )
512
+ return cls .from_string (
513
+ point_str ,
514
+ curve ,
515
+ hashfunc = hashfunc ,
516
+ valid_encodings = valid_encodings ,
517
+ )
471
518
472
519
@classmethod
473
520
def from_public_key_recovery (
0 commit comments