|
15 | 15 | """ECDSA (ES256) verifier and signer that use the ``cryptography`` library. |
16 | 16 | """ |
17 | 17 |
|
| 18 | +from cryptography import utils |
18 | 19 | import cryptography.exceptions |
19 | 20 | from cryptography.hazmat import backends |
20 | 21 | from cryptography.hazmat.primitives import hashes |
21 | 22 | from cryptography.hazmat.primitives import serialization |
22 | 23 | from cryptography.hazmat.primitives.asymmetric import ec |
23 | 24 | from cryptography.hazmat.primitives.asymmetric import padding |
| 25 | +from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature |
| 26 | +from cryptography.hazmat.primitives.asymmetric.utils import encode_dss_signature |
24 | 27 | import cryptography.x509 |
25 | 28 | import pkg_resources |
26 | 29 |
|
@@ -58,9 +61,17 @@ def __init__(self, public_key): |
58 | 61 |
|
59 | 62 | @_helpers.copy_docstring(base.Verifier) |
60 | 63 | def verify(self, message, signature): |
| 64 | + # First convert (r||s) raw signature to ASN1 encoded signature. |
| 65 | + sig_bytes = _helpers.to_bytes(signature) |
| 66 | + if len(sig_bytes) != 64: |
| 67 | + return False |
| 68 | + r = utils.int_from_bytes(sig_bytes[:32], byteorder="big") |
| 69 | + s = utils.int_from_bytes(sig_bytes[32:], byteorder="big") |
| 70 | + asn1_sig = encode_dss_signature(r, s) |
| 71 | + |
61 | 72 | message = _helpers.to_bytes(message) |
62 | 73 | try: |
63 | | - self._pubkey.verify(signature, message, ec.ECDSA(hashes.SHA256())) |
| 74 | + self._pubkey.verify(asn1_sig, message, ec.ECDSA(hashes.SHA256())) |
64 | 75 | return True |
65 | 76 | except (ValueError, cryptography.exceptions.InvalidSignature): |
66 | 77 | return False |
@@ -118,7 +129,11 @@ def key_id(self): |
118 | 129 | @_helpers.copy_docstring(base.Signer) |
119 | 130 | def sign(self, message): |
120 | 131 | message = _helpers.to_bytes(message) |
121 | | - return self._key.sign(message, ec.ECDSA(hashes.SHA256())) |
| 132 | + asn1_signature = self._key.sign(message, ec.ECDSA(hashes.SHA256())) |
| 133 | + |
| 134 | + # Convert ASN1 encoded signature to (r||s) raw signature. |
| 135 | + (r, s) = decode_dss_signature(asn1_signature) |
| 136 | + return utils.int_to_bytes(r, 32) + utils.int_to_bytes(s, 32) |
122 | 137 |
|
123 | 138 | @classmethod |
124 | 139 | def from_string(cls, key, key_id=None): |
|
0 commit comments