1""" 2Primary classes for performing signing and verification operations. 3 4.. glossary:: 5 6 raw encoding 7 Conversion of public, private keys and signatures (which in 8 mathematical sense are integers or pairs of integers) to strings of 9 bytes that does not use any special tags or encoding rules. 10 For any given curve, all keys of the same type or signatures will be 11 encoded to byte strings of the same length. In more formal sense, 12 the integers are encoded as big-endian, constant length byte strings, 13 where the string length is determined by the curve order (e.g. 14 for NIST256p the order is 256 bits long, so the private key will be 32 15 bytes long while public key will be 64 bytes long). The encoding of a 16 single integer is zero-padded on the left if the numerical value is 17 low. In case of public keys and signatures, which are comprised of two 18 integers, the integers are simply concatenated. 19 20 uncompressed 21 The most common formatting specified in PKIX standards. Specified in 22 X9.62 and SEC1 standards. The only difference between it and 23 :term:`raw encoding` is the prepending of a 0x04 byte. Thus an 24 uncompressed NIST256p public key encoding will be 65 bytes long. 25 26 compressed 27 The public point representation that uses half of bytes of the 28 :term:`uncompressed` encoding (rounded up). It uses the first byte of 29 the encoding to specify the sign of the y coordinate and encodes the 30 x coordinate as-is. The first byte of the encoding is equal to 31 0x02 or 0x03. Compressed encoding of NIST256p public key will be 33 32 bytes long. 33 34 hybrid 35 A combination of :term:`uncompressed` and :term:`compressed` encodings. 36 Both x and y coordinates are stored just as in :term:`compressed` 37 encoding, but the first byte reflects the sign of the y coordinate. The 38 first byte of the encoding will be equal to 0x06 or 0x7. Hybrid 39 encoding of NIST256p public key will be 65 bytes long. 40 41 PEM 42 The acronym stands for Privacy Enhanced Email, but currently it is used 43 primarily as the way to encode :term:`DER` objects into text that can 44 be either easily copy-pasted or transferred over email. 45 It uses headers like ``-----BEGIN <type of contents>-----`` and footers 46 like ``-----END <type of contents>-----`` to separate multiple 47 types of objects in the same file or the object from the surrounding 48 comments. The actual object stored is base64 encoded. 49 50 DER 51 Distinguished Encoding Rules, the way to encode :term:`ASN.1` objects 52 deterministically and uniquely into byte strings. 53 54 ASN.1 55 Abstract Syntax Notation 1 is a standard description language for 56 specifying serialisation and deserialisation of data structures in a 57 portable and cross-platform way. 58 59 bytes-like object 60 All the types that implement the buffer protocol. That includes 61 ``str`` (only on python2), ``bytes``, ``bytesarray``, ``array.array` 62 and ``memoryview`` of those objects. 63 Please note that ``array.array` serialisation (converting it to byte 64 string) is endianess dependant! Signature computed over ``array.array`` 65 of integers on a big-endian system will not be verified on a 66 little-endian system and vice-versa. 67""" 68 69import binascii 70from hashlib import sha1 71from six import PY3, b 72from . import ecdsa 73from . import der 74from . import rfc6979 75from . import ellipticcurve 76from .curves import NIST192p, find_curve 77from .numbertheory import square_root_mod_prime, SquareRootError 78from .ecdsa import RSZeroError 79from .util import string_to_number, number_to_string, randrange 80from .util import sigencode_string, sigdecode_string 81from .util import oid_ecPublicKey, encoded_oid_ecPublicKey, MalformedSignature 82from ._compat import normalise_bytes 83 84 85__all__ = ["BadSignatureError", "BadDigestError", "VerifyingKey", "SigningKey", 86 "MalformedPointError"] 87 88 89class BadSignatureError(Exception): 90 """ 91 Raised when verification of signature failed. 92 93 Will be raised irrespective of reason of the failure: 94 95 * the calculated or provided hash does not match the signature 96 * the signature does not match the curve/public key 97 * the encoding of the signature is malformed 98 * the size of the signature does not match the curve of the VerifyingKey 99 """ 100 101 pass 102 103 104class BadDigestError(Exception): 105 """Raised in case the selected hash is too large for the curve.""" 106 107 pass 108 109 110class MalformedPointError(AssertionError): 111 """Raised in case the encoding of private or public key is malformed.""" 112 113 pass 114 115 116class VerifyingKey(object): 117 """ 118 Class for handling keys that can verify signatures (public keys). 119 120 :ivar ecdsa.curves.Curve curve: The Curve over which all the cryptographic 121 operations will take place 122 :ivar default_hashfunc: the function that will be used for hashing the 123 data. Should implement the same API as hashlib.sha1 124 :vartype default_hashfunc: callable 125 :ivar pubkey: the actual public key 126 :vartype pubkey: ecdsa.ecdsa.Public_key 127 """ 128 129 def __init__(self, _error__please_use_generate=None): 130 """Unsupported, please use one of the classmethods to initialise.""" 131 if not _error__please_use_generate: 132 raise TypeError("Please use VerifyingKey.generate() to " 133 "construct me") 134 self.curve = None 135 self.default_hashfunc = None 136 self.pubkey = None 137 138 def __repr__(self): 139 pub_key = self.to_string("compressed") 140 return "VerifyingKey.from_string({0!r}, {1!r}, {2})".format( 141 pub_key, self.curve, self.default_hashfunc().name) 142 143 def __eq__(self, other): 144 """Return True if the points are identical, False otherwise.""" 145 if isinstance(other, VerifyingKey): 146 return self.curve == other.curve \ 147 and self.pubkey == other.pubkey 148 return NotImplemented 149 150 @classmethod 151 def from_public_point(cls, point, curve=NIST192p, hashfunc=sha1, 152 validate_point=True): 153 """ 154 Initialise the object from a Point object. 155 156 This is a low-level method, generally you will not want to use it. 157 158 :param point: The point to wrap around, the actual public key 159 :type point: ecdsa.ellipticcurve.Point 160 :param curve: The curve on which the point needs to reside, defaults 161 to NIST192p 162 :type curve: ecdsa.curves.Curve 163 :param hashfunc: The default hash function that will be used for 164 verification, needs to implement the same interface 165 as hashlib.sha1 166 :type hashfunc: callable 167 :type bool validate_point: whether to check if the point lies on curve 168 should always be used if the public point is not a result 169 of our own calculation 170 171 :raises MalformedPointError: if the public point does not lie on the 172 curve 173 174 :return: Initialised VerifyingKey object 175 :rtype: VerifyingKey 176 """ 177 self = cls(_error__please_use_generate=True) 178 if not isinstance(point, ellipticcurve.PointJacobi): 179 point = ellipticcurve.PointJacobi.from_affine(point) 180 self.curve = curve 181 self.default_hashfunc = hashfunc 182 try: 183 self.pubkey = ecdsa.Public_key(curve.generator, point, 184 validate_point) 185 except ecdsa.InvalidPointError: 186 raise MalformedPointError("Point does not lie on the curve") 187 self.pubkey.order = curve.order 188 return self 189 190 def precompute(self): 191 self.pubkey.point = ellipticcurve.PointJacobi.from_affine( 192 self.pubkey.point, True) 193 194 @staticmethod 195 def _from_raw_encoding(string, curve): 196 """ 197 Decode public point from :term:`raw encoding`. 198 199 :term:`raw encoding` is the same as the :term:`uncompressed` encoding, 200 but without the 0x04 byte at the beginning. 201 """ 202 order = curve.order 203 # real assert, from_string() should not call us with different length 204 assert len(string) == curve.verifying_key_length 205 xs = string[:curve.baselen] 206 ys = string[curve.baselen:] 207 if len(xs) != curve.baselen: 208 raise MalformedPointError("Unexpected length of encoded x") 209 if len(ys) != curve.baselen: 210 raise MalformedPointError("Unexpected length of encoded y") 211 x = string_to_number(xs) 212 y = string_to_number(ys) 213 214 return ellipticcurve.PointJacobi(curve.curve, x, y, 1, order) 215 216 @staticmethod 217 def _from_compressed(string, curve): 218 """Decode public point from compressed encoding.""" 219 if string[:1] not in (b('\x02'), b('\x03')): 220 raise MalformedPointError("Malformed compressed point encoding") 221 222 is_even = string[:1] == b('\x02') 223 x = string_to_number(string[1:]) 224 order = curve.order 225 p = curve.curve.p() 226 alpha = (pow(x, 3, p) + (curve.curve.a() * x) + curve.curve.b()) % p 227 try: 228 beta = square_root_mod_prime(alpha, p) 229 except SquareRootError as e: 230 raise MalformedPointError( 231 "Encoding does not correspond to a point on curve", e) 232 if is_even == bool(beta & 1): 233 y = p - beta 234 else: 235 y = beta 236 return ellipticcurve.PointJacobi(curve.curve, x, y, 1, order) 237 238 @classmethod 239 def _from_hybrid(cls, string, curve, validate_point): 240 """Decode public point from hybrid encoding.""" 241 # real assert, from_string() should not call us with different types 242 assert string[:1] in (b('\x06'), b('\x07')) 243 244 # primarily use the uncompressed as it's easiest to handle 245 point = cls._from_raw_encoding(string[1:], curve) 246 247 # but validate if it's self-consistent if we're asked to do that 248 if validate_point \ 249 and (point.y() & 1 and string[:1] != b('\x07') 250 or (not point.y() & 1) and string[:1] != b('\x06')): 251 raise MalformedPointError("Inconsistent hybrid point encoding") 252 253 return point 254 255 @classmethod 256 def from_string(cls, string, curve=NIST192p, hashfunc=sha1, 257 validate_point=True): 258 """ 259 Initialise the object from byte encoding of public key. 260 261 The method does accept and automatically detect the type of point 262 encoding used. It supports the :term:`raw encoding`, 263 :term:`uncompressed`, :term:`compressed` and :term:`hybrid` encodings. 264 265 Note, while the method is named "from_string" it's a misnomer from 266 Python 2 days when there were no binary strings. In Python 3 the 267 input needs to be a bytes-like object. 268 269 :param string: single point encoding of the public key 270 :type string: :term:`bytes-like object` 271 :param curve: the curve on which the public key is expected to lie 272 :type curve: ecdsa.curves.Curve 273 :param hashfunc: The default hash function that will be used for 274 verification, needs to implement the same interface as hashlib.sha1 275 :type hashfunc: callable 276 :param validate_point: whether to verify that the point lies on the 277 provided curve or not, defaults to True 278 :type validate_point: bool 279 280 :raises MalformedPointError: if the public point does not lie on the 281 curve or the encoding is invalid 282 283 :return: Initialised VerifyingKey object 284 :rtype: VerifyingKey 285 """ 286 string = normalise_bytes(string) 287 sig_len = len(string) 288 if sig_len == curve.verifying_key_length: 289 point = cls._from_raw_encoding(string, curve) 290 elif sig_len == curve.verifying_key_length + 1: 291 if string[:1] in (b('\x06'), b('\x07')): 292 point = cls._from_hybrid(string, curve, validate_point) 293 elif string[:1] == b('\x04'): 294 point = cls._from_raw_encoding(string[1:], curve) 295 else: 296 raise MalformedPointError( 297 "Invalid X9.62 encoding of the public point") 298 elif sig_len == curve.baselen + 1: 299 point = cls._from_compressed(string, curve) 300 else: 301 raise MalformedPointError( 302 "Length of string does not match lengths of " 303 "any of the supported encodings of {0} " 304 "curve.".format(curve.name)) 305 return cls.from_public_point(point, curve, hashfunc, 306 validate_point) 307 308 @classmethod 309 def from_pem(cls, string, hashfunc=sha1): 310 """ 311 Initialise from public key stored in :term:`PEM` format. 312 313 The PEM header of the key should be ``BEGIN PUBLIC KEY``. 314 315 See the :func:`~VerifyingKey.from_der()` method for details of the 316 format supported. 317 318 Note: only a single PEM object encoding is supported in provided 319 string. 320 321 :param string: text with PEM-encoded public ECDSA key 322 :type string: str 323 324 :return: Initialised VerifyingKey object 325 :rtype: VerifyingKey 326 """ 327 return cls.from_der(der.unpem(string), hashfunc=hashfunc) 328 329 @classmethod 330 def from_der(cls, string, hashfunc=sha1): 331 """ 332 Initialise the key stored in :term:`DER` format. 333 334 The expected format of the key is the SubjectPublicKeyInfo structure 335 from RFC5912 (for RSA keys, it's known as the PKCS#1 format):: 336 337 SubjectPublicKeyInfo {PUBLIC-KEY: IOSet} ::= SEQUENCE { 338 algorithm AlgorithmIdentifier {PUBLIC-KEY, {IOSet}}, 339 subjectPublicKey BIT STRING 340 } 341 342 Note: only public EC keys are supported by this method. The 343 SubjectPublicKeyInfo.algorithm.algorithm field must specify 344 id-ecPublicKey (see RFC3279). 345 346 Only the named curve encoding is supported, thus the 347 SubjectPublicKeyInfo.algorithm.parameters field needs to be an 348 object identifier. A sequence in that field indicates an explicit 349 parameter curve encoding, this format is not supported. A NULL object 350 in that field indicates an "implicitlyCA" encoding, where the curve 351 parameters come from CA certificate, those, again, are not supported. 352 353 :param string: binary string with the DER encoding of public ECDSA key 354 :type string: bytes-like object 355 356 :return: Initialised VerifyingKey object 357 :rtype: VerifyingKey 358 """ 359 string = normalise_bytes(string) 360 # [[oid_ecPublicKey,oid_curve], point_str_bitstring] 361 s1, empty = der.remove_sequence(string) 362 if empty != b"": 363 raise der.UnexpectedDER("trailing junk after DER pubkey: %s" % 364 binascii.hexlify(empty)) 365 s2, point_str_bitstring = der.remove_sequence(s1) 366 # s2 = oid_ecPublicKey,oid_curve 367 oid_pk, rest = der.remove_object(s2) 368 oid_curve, empty = der.remove_object(rest) 369 if empty != b"": 370 raise der.UnexpectedDER("trailing junk after DER pubkey objects: %s" % 371 binascii.hexlify(empty)) 372 if not oid_pk == oid_ecPublicKey: 373 raise der.UnexpectedDER("Unexpected object identifier in DER " 374 "encoding: {0!r}".format(oid_pk)) 375 curve = find_curve(oid_curve) 376 point_str, empty = der.remove_bitstring(point_str_bitstring, 0) 377 if empty != b"": 378 raise der.UnexpectedDER("trailing junk after pubkey pointstring: %s" % 379 binascii.hexlify(empty)) 380 # raw encoding of point is invalid in DER files 381 if len(point_str) == curve.verifying_key_length: 382 raise der.UnexpectedDER("Malformed encoding of public point") 383 return cls.from_string(point_str, curve, hashfunc=hashfunc) 384 385 @classmethod 386 def from_public_key_recovery(cls, signature, data, curve, hashfunc=sha1, 387 sigdecode=sigdecode_string): 388 """ 389 Return keys that can be used as verifiers of the provided signature. 390 391 Tries to recover the public key that can be used to verify the 392 signature, usually returns two keys like that. 393 394 :param signature: the byte string with the encoded signature 395 :type signature: bytes-like object 396 :param data: the data to be hashed for signature verification 397 :type data: bytes-like object 398 :param curve: the curve over which the signature was performed 399 :type curve: ecdsa.curves.Curve 400 :param hashfunc: The default hash function that will be used for 401 verification, needs to implement the same interface as hashlib.sha1 402 :type hashfunc: callable 403 :param sigdecode: Callable to define the way the signature needs to 404 be decoded to an object, needs to handle `signature` as the 405 first parameter, the curve order (an int) as the second and return 406 a tuple with two integers, "r" as the first one and "s" as the 407 second one. See :func:`ecdsa.util.sigdecode_string` and 408 :func:`ecdsa.util.sigdecode_der` for examples. 409 :type sigdecode: callable 410 411 :return: Initialised VerifyingKey objects 412 :rtype: list of VerifyingKey 413 """ 414 data = normalise_bytes(data) 415 digest = hashfunc(data).digest() 416 return cls.from_public_key_recovery_with_digest( 417 signature, digest, curve, hashfunc=hashfunc, 418 sigdecode=sigdecode) 419 420 @classmethod 421 def from_public_key_recovery_with_digest( 422 cls, signature, digest, curve, 423 hashfunc=sha1, sigdecode=sigdecode_string): 424 """ 425 Return keys that can be used as verifiers of the provided signature. 426 427 Tries to recover the public key that can be used to verify the 428 signature, usually returns two keys like that. 429 430 :param signature: the byte string with the encoded signature 431 :type signature: bytes-like object 432 :param digest: the hash value of the message signed by the signature 433 :type digest: bytes-like object 434 :param curve: the curve over which the signature was performed 435 :type curve: ecdsa.curves.Curve 436 :param hashfunc: The default hash function that will be used for 437 verification, needs to implement the same interface as hashlib.sha1 438 :type hashfunc: callable 439 :param sigdecode: Callable to define the way the signature needs to 440 be decoded to an object, needs to handle `signature` as the 441 first parameter, the curve order (an int) as the second and return 442 a tuple with two integers, "r" as the first one and "s" as the 443 second one. See :func:`ecdsa.util.sigdecode_string` and 444 :func:`ecdsa.util.sigdecode_der` for examples. 445 :type sigdecode: callable 446 447 448 :return: Initialised VerifyingKey object 449 :rtype: VerifyingKey 450 """ 451 generator = curve.generator 452 r, s = sigdecode(signature, generator.order()) 453 sig = ecdsa.Signature(r, s) 454 455 digest = normalise_bytes(digest) 456 digest_as_number = string_to_number(digest) 457 pks = sig.recover_public_keys(digest_as_number, generator) 458 459 # Transforms the ecdsa.Public_key object into a VerifyingKey 460 verifying_keys = [cls.from_public_point(pk.point, curve, hashfunc) 461 for pk in pks] 462 return verifying_keys 463 464 def _raw_encode(self): 465 """Convert the public key to the :term:`raw encoding`.""" 466 order = self.pubkey.order 467 x_str = number_to_string(self.pubkey.point.x(), order) 468 y_str = number_to_string(self.pubkey.point.y(), order) 469 return x_str + y_str 470 471 def _compressed_encode(self): 472 """Encode the public point into the compressed form.""" 473 order = self.pubkey.order 474 x_str = number_to_string(self.pubkey.point.x(), order) 475 if self.pubkey.point.y() & 1: 476 return b('\x03') + x_str 477 else: 478 return b('\x02') + x_str 479 480 def _hybrid_encode(self): 481 """Encode the public point into the hybrid form.""" 482 raw_enc = self._raw_encode() 483 if self.pubkey.point.y() & 1: 484 return b('\x07') + raw_enc 485 else: 486 return b('\x06') + raw_enc 487 488 def to_string(self, encoding="raw"): 489 """ 490 Convert the public key to a byte string. 491 492 The method by default uses the :term:`raw encoding` (specified 493 by `encoding="raw"`. It can also output keys in :term:`uncompressed`, 494 :term:`compressed` and :term:`hybrid` formats. 495 496 Remember that the curve identification is not part of the encoding 497 so to decode the point using :func:`~VerifyingKey.from_string`, curve 498 needs to be specified. 499 500 Note: while the method is called "to_string", it's a misnomer from 501 Python 2 days when character strings and byte strings shared type. 502 On Python 3 the returned type will be `bytes`. 503 504 :return: :term:`raw encoding` of the public key (public point) on the 505 curve 506 :rtype: bytes 507 """ 508 assert encoding in ("raw", "uncompressed", "compressed", "hybrid") 509 if encoding == "raw": 510 return self._raw_encode() 511 elif encoding == "uncompressed": 512 return b('\x04') + self._raw_encode() 513 elif encoding == "hybrid": 514 return self._hybrid_encode() 515 else: 516 return self._compressed_encode() 517 518 def to_pem(self, point_encoding="uncompressed"): 519 """ 520 Convert the public key to the :term:`PEM` format. 521 522 The PEM header of the key will be ``BEGIN PUBLIC KEY``. 523 524 The format of the key is described in the 525 :func:`~VerifyingKey.from_der()` method. 526 This method supports only "named curve" encoding of keys. 527 528 :param str point_encoding: specification of the encoding format 529 of public keys. "uncompressed" is most portable, "compressed" is 530 smallest. "hybrid" is uncommon and unsupported by most 531 implementations, it is as big as "uncompressed". 532 533 :return: portable encoding of the public key 534 :rtype: str 535 """ 536 return der.topem(self.to_der(point_encoding), "PUBLIC KEY") 537 538 def to_der(self, point_encoding="uncompressed"): 539 """ 540 Convert the public key to the :term:`DER` format. 541 542 The format of the key is described in the 543 :func:`~VerifyingKey.from_der()` method. 544 This method supports only "named curve" encoding of keys. 545 546 :param str point_encoding: specification of the encoding format 547 of public keys. "uncompressed" is most portable, "compressed" is 548 smallest. "hybrid" is uncommon and unsupported by most 549 implementations, it is as big as "uncompressed". 550 551 :return: DER encoding of the public key 552 :rtype: bytes 553 """ 554 if point_encoding == "raw": 555 raise ValueError("raw point_encoding not allowed in DER") 556 point_str = self.to_string(point_encoding) 557 return der.encode_sequence(der.encode_sequence(encoded_oid_ecPublicKey, 558 self.curve.encoded_oid), 559 # 0 is the number of unused bits in the 560 # bit string 561 der.encode_bitstring(point_str, 0)) 562 563 def verify(self, signature, data, hashfunc=None, 564 sigdecode=sigdecode_string): 565 """ 566 Verify a signature made over provided data. 567 568 Will hash `data` to verify the signature. 569 570 By default expects signature in :term:`raw encoding`. Can also be used 571 to verify signatures in ASN.1 DER encoding by using 572 :func:`ecdsa.util.sigdecode_der` 573 as the `sigdecode` parameter. 574 575 :param signature: encoding of the signature 576 :type signature: sigdecode method dependant 577 :param data: data signed by the `signature`, will be hashed using 578 `hashfunc`, if specified, or default hash function 579 :type data: bytes like object 580 :param hashfunc: The default hash function that will be used for 581 verification, needs to implement the same interface as hashlib.sha1 582 :type hashfunc: callable 583 :param sigdecode: Callable to define the way the signature needs to 584 be decoded to an object, needs to handle `signature` as the 585 first parameter, the curve order (an int) as the second and return 586 a tuple with two integers, "r" as the first one and "s" as the 587 second one. See :func:`ecdsa.util.sigdecode_string` and 588 :func:`ecdsa.util.sigdecode_der` for examples. 589 :type sigdecode: callable 590 591 :raises BadSignatureError: if the signature is invalid or malformed 592 593 :return: True if the verification was successful 594 :rtype: bool 595 """ 596 # signature doesn't have to be a bytes-like-object so don't normalise 597 # it, the decoders will do that 598 data = normalise_bytes(data) 599 600 hashfunc = hashfunc or self.default_hashfunc 601 digest = hashfunc(data).digest() 602 return self.verify_digest(signature, digest, sigdecode, True) 603 604 def verify_digest(self, signature, digest, sigdecode=sigdecode_string, 605 allow_truncate=False): 606 """ 607 Verify a signature made over provided hash value. 608 609 By default expects signature in :term:`raw encoding`. Can also be used 610 to verify signatures in ASN.1 DER encoding by using 611 :func:`ecdsa.util.sigdecode_der` 612 as the `sigdecode` parameter. 613 614 :param signature: encoding of the signature 615 :type signature: sigdecode method dependant 616 :param digest: raw hash value that the signature authenticates. 617 :type digest: bytes like object 618 :param sigdecode: Callable to define the way the signature needs to 619 be decoded to an object, needs to handle `signature` as the 620 first parameter, the curve order (an int) as the second and return 621 a tuple with two integers, "r" as the first one and "s" as the 622 second one. See :func:`ecdsa.util.sigdecode_string` and 623 :func:`ecdsa.util.sigdecode_der` for examples. 624 :type sigdecode: callable 625 :param bool allow_truncate: if True, the provided digest can have 626 bigger bit-size than the order of the curve, the extra bits (at 627 the end of the digest) will be truncated. Use it when verifying 628 SHA-384 output using NIST256p or in similar situations. 629 630 :raises BadSignatureError: if the signature is invalid or malformed 631 :raises BadDigestError: if the provided digest is too big for the curve 632 associated with this VerifyingKey and allow_truncate was not set 633 634 :return: True if the verification was successful 635 :rtype: bool 636 """ 637 # signature doesn't have to be a bytes-like-object so don't normalise 638 # it, the decoders will do that 639 digest = normalise_bytes(digest) 640 if allow_truncate: 641 digest = digest[:self.curve.baselen] 642 if len(digest) > self.curve.baselen: 643 raise BadDigestError("this curve (%s) is too short " 644 "for your digest (%d)" % (self.curve.name, 645 8 * len(digest))) 646 number = string_to_number(digest) 647 try: 648 r, s = sigdecode(signature, self.pubkey.order) 649 except (der.UnexpectedDER, MalformedSignature) as e: 650 raise BadSignatureError("Malformed formatting of signature", e) 651 sig = ecdsa.Signature(r, s) 652 if self.pubkey.verifies(number, sig): 653 return True 654 raise BadSignatureError("Signature verification failed") 655 656 657class SigningKey(object): 658 """ 659 Class for handling keys that can create signatures (private keys). 660 661 :ivar ecdsa.curves.Curve curve: The Curve over which all the cryptographic 662 operations will take place 663 :ivar default_hashfunc: the function that will be used for hashing the 664 data. Should implement the same API as hashlib.sha1 665 :ivar int baselen: the length of a :term:`raw encoding` of private key 666 :ivar ecdsa.keys.VerifyingKey verifying_key: the public key 667 associated with this private key 668 :ivar ecdsa.ecdsa.Private_key privkey: the actual private key 669 """ 670 671 def __init__(self, _error__please_use_generate=None): 672 """Unsupported, please use one of the classmethods to initialise.""" 673 if not _error__please_use_generate: 674 raise TypeError("Please use SigningKey.generate() to construct me") 675 self.curve = None 676 self.default_hashfunc = None 677 self.baselen = None 678 self.verifying_key = None 679 self.privkey = None 680 681 def __eq__(self, other): 682 """Return True if the points are identical, False otherwise.""" 683 if isinstance(other, SigningKey): 684 return self.curve == other.curve \ 685 and self.verifying_key == other.verifying_key \ 686 and self.privkey == other.privkey 687 return NotImplemented 688 689 @classmethod 690 def generate(cls, curve=NIST192p, entropy=None, hashfunc=sha1): 691 """ 692 Generate a random private key. 693 694 :param curve: The curve on which the point needs to reside, defaults 695 to NIST192p 696 :type curve: ecdsa.curves.Curve 697 :param entropy: Source of randomness for generating the private keys, 698 should provide cryptographically secure random numbers if the keys 699 need to be secure. Uses os.urandom() by default. 700 :type entropy: callable 701 :param hashfunc: The default hash function that will be used for 702 signing, needs to implement the same interface 703 as hashlib.sha1 704 :type hashfunc: callable 705 706 :return: Initialised SigningKey object 707 :rtype: SigningKey 708 """ 709 secexp = randrange(curve.order, entropy) 710 return cls.from_secret_exponent(secexp, curve, hashfunc) 711 712 @classmethod 713 def from_secret_exponent(cls, secexp, curve=NIST192p, hashfunc=sha1): 714 """ 715 Create a private key from a random integer. 716 717 Note: it's a low level method, it's recommended to use the 718 :func:`~SigningKey.generate` method to create private keys. 719 720 :param int secexp: secret multiplier (the actual private key in ECDSA). 721 Needs to be an integer between 1 and the curve order. 722 :param curve: The curve on which the point needs to reside 723 :type curve: ecdsa.curves.Curve 724 :param hashfunc: The default hash function that will be used for 725 signing, needs to implement the same interface 726 as hashlib.sha1 727 :type hashfunc: callable 728 729 :raises MalformedPointError: when the provided secexp is too large 730 or too small for the curve selected 731 :raises RuntimeError: if the generation of public key from private 732 key failed 733 734 :return: Initialised SigningKey object 735 :rtype: SigningKey 736 """ 737 self = cls(_error__please_use_generate=True) 738 self.curve = curve 739 self.default_hashfunc = hashfunc 740 self.baselen = curve.baselen 741 n = curve.order 742 if not 1 <= secexp < n: 743 raise MalformedPointError( 744 "Invalid value for secexp, expected integer between 1 and {0}" 745 .format(n)) 746 pubkey_point = curve.generator * secexp 747 if hasattr(pubkey_point, "scale"): 748 pubkey_point = pubkey_point.scale() 749 self.verifying_key = VerifyingKey.from_public_point(pubkey_point, curve, 750 hashfunc, False) 751 pubkey = self.verifying_key.pubkey 752 self.privkey = ecdsa.Private_key(pubkey, secexp) 753 self.privkey.order = n 754 return self 755 756 @classmethod 757 def from_string(cls, string, curve=NIST192p, hashfunc=sha1): 758 """ 759 Decode the private key from :term:`raw encoding`. 760 761 Note: the name of this method is a misnomer coming from days of 762 Python 2, when binary strings and character strings shared a type. 763 In Python 3, the expected type is `bytes`. 764 765 :param string: the raw encoding of the private key 766 :type string: bytes like object 767 :param curve: The curve on which the point needs to reside 768 :type curve: ecdsa.curves.Curve 769 :param hashfunc: The default hash function that will be used for 770 signing, needs to implement the same interface 771 as hashlib.sha1 772 :type hashfunc: callable 773 774 :raises MalformedPointError: if the length of encoding doesn't match 775 the provided curve or the encoded values is too large 776 :raises RuntimeError: if the generation of public key from private 777 key failed 778 779 :return: Initialised SigningKey object 780 :rtype: SigningKey 781 """ 782 string = normalise_bytes(string) 783 if len(string) != curve.baselen: 784 raise MalformedPointError( 785 "Invalid length of private key, received {0}, expected {1}" 786 .format(len(string), curve.baselen)) 787 secexp = string_to_number(string) 788 return cls.from_secret_exponent(secexp, curve, hashfunc) 789 790 @classmethod 791 def from_pem(cls, string, hashfunc=sha1): 792 """ 793 Initialise from key stored in :term:`PEM` format. 794 795 Note, the only PEM format supported is the un-encrypted RFC5915 796 (the sslay format) supported by OpenSSL, the more common PKCS#8 format 797 is NOT supported (see: 798 https://github.com/warner/python-ecdsa/issues/113 ) 799 800 ``openssl ec -in pkcs8.pem -out sslay.pem`` can be used to 801 convert PKCS#8 file to this legacy format. 802 803 The legacy format files have the header with the string 804 ``BEGIN EC PRIVATE KEY``. 805 Encrypted files (ones that include the string 806 ``Proc-Type: 4,ENCRYPTED`` 807 right after the PEM header) are not supported. 808 809 See :func:`~SigningKey.from_der` for ASN.1 syntax of the objects in 810 this files. 811 812 :param string: text with PEM-encoded private ECDSA key 813 :type string: str 814 815 :raises MalformedPointError: if the length of encoding doesn't match 816 the provided curve or the encoded values is too large 817 :raises RuntimeError: if the generation of public key from private 818 key failed 819 :raises UnexpectedDER: if the encoding of the PEM file is incorrect 820 821 :return: Initialised VerifyingKey object 822 :rtype: VerifyingKey 823 """ 824 # the privkey pem may have multiple sections, commonly it also has 825 # "EC PARAMETERS", we need just "EC PRIVATE KEY". 826 if PY3 and isinstance(string, str): 827 string = string.encode() 828 privkey_pem = string[string.index(b("-----BEGIN EC PRIVATE KEY-----")):] 829 return cls.from_der(der.unpem(privkey_pem), hashfunc) 830 831 @classmethod 832 def from_der(cls, string, hashfunc=sha1): 833 """ 834 Initialise from key stored in :term:`DER` format. 835 836 Note, the only DER format supported is the RFC5915 837 (the sslay format) supported by OpenSSL, the more common PKCS#8 format 838 is NOT supported (see: 839 https://github.com/warner/python-ecdsa/issues/113 ) 840 841 ``openssl ec -in pkcs8.pem -outform der -out sslay.der`` can be 842 used to convert PKCS#8 file to this legacy format. 843 844 The encoding of the ASN.1 object in those files follows following 845 syntax specified in RFC5915:: 846 847 ECPrivateKey ::= SEQUENCE { 848 version INTEGER { ecPrivkeyVer1(1) }} (ecPrivkeyVer1), 849 privateKey OCTET STRING, 850 parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, 851 publicKey [1] BIT STRING OPTIONAL 852 } 853 854 The only format supported for the `parameters` field is the named 855 curve method. Explicit encoding of curve parameters is not supported. 856 857 While `parameters` field is defined as optional, this implementation 858 requires its presence for correct parsing of the keys. 859 860 `publicKey` field is ignored completely (errors, if any, in it will 861 be undetected). 862 863 :param string: binary string with DER-encoded private ECDSA key 864 :type string: bytes like object 865 866 :raises MalformedPointError: if the length of encoding doesn't match 867 the provided curve or the encoded values is too large 868 :raises RuntimeError: if the generation of public key from private 869 key failed 870 :raises UnexpectedDER: if the encoding of the DER file is incorrect 871 872 :return: Initialised VerifyingKey object 873 :rtype: VerifyingKey 874 """ 875 string = normalise_bytes(string) 876 s, empty = der.remove_sequence(string) 877 if empty != b(""): 878 raise der.UnexpectedDER("trailing junk after DER privkey: %s" % 879 binascii.hexlify(empty)) 880 one, s = der.remove_integer(s) 881 if one != 1: 882 raise der.UnexpectedDER("expected '1' at start of DER privkey," 883 " got %d" % one) 884 privkey_str, s = der.remove_octet_string(s) 885 tag, curve_oid_str, s = der.remove_constructed(s) 886 if tag != 0: 887 raise der.UnexpectedDER("expected tag 0 in DER privkey," 888 " got %d" % tag) 889 curve_oid, empty = der.remove_object(curve_oid_str) 890 if empty != b(""): 891 raise der.UnexpectedDER("trailing junk after DER privkey " 892 "curve_oid: %s" % binascii.hexlify(empty)) 893 curve = find_curve(curve_oid) 894 895 # we don't actually care about the following fields 896 # 897 # tag, pubkey_bitstring, s = der.remove_constructed(s) 898 # if tag != 1: 899 # raise der.UnexpectedDER("expected tag 1 in DER privkey, got %d" 900 # % tag) 901 # pubkey_str = der.remove_bitstring(pubkey_bitstring, 0) 902 # if empty != "": 903 # raise der.UnexpectedDER("trailing junk after DER privkey " 904 # "pubkeystr: %s" % binascii.hexlify(empty)) 905 906 # our from_string method likes fixed-length privkey strings 907 if len(privkey_str) < curve.baselen: 908 privkey_str = b("\x00") * (curve.baselen - len(privkey_str)) + privkey_str 909 return cls.from_string(privkey_str, curve, hashfunc) 910 911 def to_string(self): 912 """ 913 Convert the private key to :term:`raw encoding`. 914 915 Note: while the method is named "to_string", its name comes from 916 Python 2 days, when binary and character strings used the same type. 917 The type used in Python 3 is `bytes`. 918 919 :return: raw encoding of private key 920 :rtype: bytes 921 """ 922 secexp = self.privkey.secret_multiplier 923 s = number_to_string(secexp, self.privkey.order) 924 return s 925 926 def to_pem(self, point_encoding="uncompressed"): 927 """ 928 Convert the private key to the :term:`PEM` format. 929 930 See :func:`~SigningKey.from_pem` method for format description. 931 932 Only the named curve format is supported. 933 The public key will be included in generated string. 934 935 The PEM header will specify ``BEGIN EC PRIVATE KEY`` 936 937 :param str point_encoding: format to use for encoding public point 938 939 :return: PEM encoded private key 940 :rtype: str 941 """ 942 # TODO: "BEGIN ECPARAMETERS" 943 return der.topem(self.to_der(point_encoding), "EC PRIVATE KEY") 944 945 def to_der(self, point_encoding="uncompressed"): 946 """ 947 Convert the private key to the :term:`DER` format. 948 949 See :func:`~SigningKey.from_der` method for format specification. 950 951 Only the named curve format is supported. 952 The public key will be included in the generated string. 953 954 :param str point_encoding: format to use for encoding public point 955 956 :return: DER encoded private key 957 :rtype: bytes 958 """ 959 # SEQ([int(1), octetstring(privkey),cont[0], oid(secp224r1), 960 # cont[1],bitstring]) 961 if point_encoding == "raw": 962 raise ValueError("raw encoding not allowed in DER") 963 encoded_vk = self.get_verifying_key().to_string(point_encoding) 964 # the 0 in encode_bitstring specifies the number of unused bits 965 # in the `encoded_vk` string 966 return der.encode_sequence( 967 der.encode_integer(1), 968 der.encode_octet_string(self.to_string()), 969 der.encode_constructed(0, self.curve.encoded_oid), 970 der.encode_constructed(1, der.encode_bitstring(encoded_vk, 0))) 971 972 def get_verifying_key(self): 973 """ 974 Return the VerifyingKey associated with this private key. 975 976 Equivalent to reading the `verifying_key` field of an instance. 977 978 :return: a public key that can be used to verify the signatures made 979 with this SigningKey 980 :rtype: VerifyingKey 981 """ 982 return self.verifying_key 983 984 def sign_deterministic(self, data, hashfunc=None, 985 sigencode=sigencode_string, 986 extra_entropy=b''): 987 """ 988 Create signature over data using the deterministic RFC6679 algorithm. 989 990 The data will be hashed using the `hashfunc` function before signing. 991 992 This is the recommended method for performing signatures when hashing 993 of data is necessary. 994 995 :param data: data to be hashed and computed signature over 996 :type data: bytes like object 997 :param hashfunc: hash function to use for computing the signature, 998 if unspecified, the default hash function selected during 999 object initialisation will be used (see 1000 `VerifyingKey.default_hashfunc`). The object needs to implement 1001 the same interface as hashlib.sha1. 1002 :type hashfunc: callable 1003 :param sigencode: function used to encode the signature. 1004 The function needs to accept three parameters: the two integers 1005 that are the signature and the order of the curve over which the 1006 signature was computed. It needs to return an encoded signature. 1007 See `ecdsa.util.sigencode_string` and `ecdsa.util.sigencode_der` 1008 as examples of such functions. 1009 :type sigencode: callable 1010 :param extra_entropy: additional data that will be fed into the random 1011 number generator used in the RFC6979 process. Entirely optional. 1012 :type extra_entropy: bytes like object 1013 1014 :return: encoded signature over `data` 1015 :rtype: bytes or sigencode function dependant type 1016 """ 1017 hashfunc = hashfunc or self.default_hashfunc 1018 data = normalise_bytes(data) 1019 extra_entropy = normalise_bytes(extra_entropy) 1020 digest = hashfunc(data).digest() 1021 1022 return self.sign_digest_deterministic( 1023 digest, hashfunc=hashfunc, sigencode=sigencode, 1024 extra_entropy=extra_entropy, allow_truncate=True) 1025 1026 def sign_digest_deterministic(self, digest, hashfunc=None, 1027 sigencode=sigencode_string, 1028 extra_entropy=b'', allow_truncate=False): 1029 """ 1030 Create signature for digest using the deterministic RFC6679 algorithm. 1031 1032 `digest` should be the output of cryptographically secure hash function 1033 like SHA256 or SHA-3-256. 1034 1035 This is the recommended method for performing signatures when no 1036 hashing of data is necessary. 1037 1038 :param digest: hash of data that will be signed 1039 :type digest: bytes like object 1040 :param hashfunc: hash function to use for computing the random "k" 1041 value from RFC6979 process, 1042 if unspecified, the default hash function selected during 1043 object initialisation will be used (see 1044 `VerifyingKey.default_hashfunc`). The object needs to implement 1045 the same interface as hashlib.sha1. 1046 :type hashfunc: callable 1047 :param sigencode: function used to encode the signature. 1048 The function needs to accept three parameters: the two integers 1049 that are the signature and the order of the curve over which the 1050 signature was computed. It needs to return an encoded signature. 1051 See `ecdsa.util.sigencode_string` and `ecdsa.util.sigencode_der` 1052 as examples of such functions. 1053 :type sigencode: callable 1054 :param extra_entropy: additional data that will be fed into the random 1055 number generator used in the RFC6979 process. Entirely optional. 1056 :type extra_entropy: bytes like object 1057 :param bool allow_truncate: if True, the provided digest can have 1058 bigger bit-size than the order of the curve, the extra bits (at 1059 the end of the digest) will be truncated. Use it when signing 1060 SHA-384 output using NIST256p or in similar situations. 1061 1062 :return: encoded signature for the `digest` hash 1063 :rtype: bytes or sigencode function dependant type 1064 """ 1065 secexp = self.privkey.secret_multiplier 1066 hashfunc = hashfunc or self.default_hashfunc 1067 digest = normalise_bytes(digest) 1068 extra_entropy = normalise_bytes(extra_entropy) 1069 1070 def simple_r_s(r, s, order): 1071 return r, s, order 1072 1073 retry_gen = 0 1074 while True: 1075 k = rfc6979.generate_k( 1076 self.curve.generator.order(), secexp, hashfunc, digest, 1077 retry_gen=retry_gen, extra_entropy=extra_entropy) 1078 try: 1079 r, s, order = self.sign_digest(digest, 1080 sigencode=simple_r_s, 1081 k=k, 1082 allow_truncate=allow_truncate) 1083 break 1084 except RSZeroError: 1085 retry_gen += 1 1086 1087 return sigencode(r, s, order) 1088 1089 def sign(self, data, entropy=None, hashfunc=None, 1090 sigencode=sigencode_string, k=None): 1091 """ 1092 Create signature over data using the probabilistic ECDSA algorithm. 1093 1094 This method uses the standard ECDSA algorithm that requires a 1095 cryptographically secure random number generator. 1096 1097 It's recommended to use the :func:`~SigningKey.sign_deterministic` 1098 method instead of this one. 1099 1100 :param data: data that will be hashed for signing 1101 :type data: bytes like object 1102 :param callable entropy: randomness source, os.urandom by default 1103 :param hashfunc: hash function to use for hashing the provided `data`. 1104 If unspecified the default hash function selected during 1105 object initialisation will be used (see 1106 `VerifyingKey.default_hashfunc`). 1107 Should behave like hashlib.sha1. The output length of the 1108 hash (in bytes) must not be longer than the length of the curve 1109 order (rounded up to the nearest byte), so using SHA256 with 1110 NIST256p is ok, but SHA256 with NIST192p is not. (In the 2**-96ish 1111 unlikely event of a hash output larger than the curve order, the 1112 hash will effectively be wrapped mod n). 1113 Use hashfunc=hashlib.sha1 to match openssl's -ecdsa-with-SHA1 mode, 1114 or hashfunc=hashlib.sha256 for openssl-1.0.0's -ecdsa-with-SHA256. 1115 :type hashfunc: callable 1116 :param sigencode: function used to encode the signature. 1117 The function needs to accept three parameters: the two integers 1118 that are the signature and the order of the curve over which the 1119 signature was computed. It needs to return an encoded signature. 1120 See `ecdsa.util.sigencode_string` and `ecdsa.util.sigencode_der` 1121 as examples of such functions. 1122 :type sigencode: callable 1123 :param int k: a pre-selected nonce for calculating the signature. 1124 In typical use cases, it should be set to None (the default) to 1125 allow its generation from an entropy source. 1126 1127 :raises RSZeroError: in the unlikely event when "r" parameter or 1128 "s" parameter is equal 0 as that would leak the key. Calee should 1129 try a better entropy source or different 'k' in such case. 1130 1131 :return: encoded signature of the hash of `data` 1132 :rtype: bytes or sigencode function dependant type 1133 """ 1134 hashfunc = hashfunc or self.default_hashfunc 1135 data = normalise_bytes(data) 1136 h = hashfunc(data).digest() 1137 return self.sign_digest(h, entropy, sigencode, k, allow_truncate=True) 1138 1139 def sign_digest(self, digest, entropy=None, sigencode=sigencode_string, 1140 k=None, allow_truncate=False): 1141 """ 1142 Create signature over digest using the probabilistic ECDSA algorithm. 1143 1144 This method uses the standard ECDSA algorithm that requires a 1145 cryptographically secure random number generator. 1146 1147 This method does not hash the input. 1148 1149 It's recommended to use the 1150 :func:`~SigningKey.sign_digest_deterministic` method 1151 instead of this one. 1152 1153 :param digest: hash value that will be signed 1154 :type digest: bytes like object 1155 :param callable entropy: randomness source, os.urandom by default 1156 :param sigencode: function used to encode the signature. 1157 The function needs to accept three parameters: the two integers 1158 that are the signature and the order of the curve over which the 1159 signature was computed. It needs to return an encoded signature. 1160 See `ecdsa.util.sigencode_string` and `ecdsa.util.sigencode_der` 1161 as examples of such functions. 1162 :type sigencode: callable 1163 :param int k: a pre-selected nonce for calculating the signature. 1164 In typical use cases, it should be set to None (the default) to 1165 allow its generation from an entropy source. 1166 :param bool allow_truncate: if True, the provided digest can have 1167 bigger bit-size than the order of the curve, the extra bits (at 1168 the end of the digest) will be truncated. Use it when signing 1169 SHA-384 output using NIST256p or in similar situations. 1170 1171 :raises RSZeroError: in the unlikely event when "r" parameter or 1172 "s" parameter is equal 0 as that would leak the key. Calee should 1173 try a better entropy source in such case. 1174 1175 :return: encoded signature for the `digest` hash 1176 :rtype: bytes or sigencode function dependant type 1177 """ 1178 digest = normalise_bytes(digest) 1179 if allow_truncate: 1180 digest = digest[:self.curve.baselen] 1181 if len(digest) > self.curve.baselen: 1182 raise BadDigestError("this curve (%s) is too short " 1183 "for your digest (%d)" % (self.curve.name, 1184 8 * len(digest))) 1185 number = string_to_number(digest) 1186 r, s = self.sign_number(number, entropy, k) 1187 return sigencode(r, s, self.privkey.order) 1188 1189 def sign_number(self, number, entropy=None, k=None): 1190 """ 1191 Sign an integer directly. 1192 1193 Note, this is a low level method, usually you will want to use 1194 :func:`~SigningKey.sign_deterministic` or 1195 :func:`~SigningKey.sign_digest_deterministic`. 1196 1197 :param int number: number to sign using the probabilistic ECDSA 1198 algorithm. 1199 :param callable entropy: entropy source, os.urandom by default 1200 :param int k: pre-selected nonce for signature operation. If unset 1201 it will be selected at random using the entropy source. 1202 1203 :raises RSZeroError: in the unlikely event when "r" parameter or 1204 "s" parameter is equal 0 as that would leak the key. Calee should 1205 try a different 'k' in such case. 1206 1207 :return: the "r" and "s" parameters of the signature 1208 :rtype: tuple of ints 1209 """ 1210 order = self.privkey.order 1211 1212 if k is not None: 1213 _k = k 1214 else: 1215 _k = randrange(order, entropy) 1216 1217 assert 1 <= _k < order 1218 sig = self.privkey.sign(number, _k) 1219 return sig.r, sig.s 1220