| # Copyright 2016 Google LLC |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| """Cryptography helpers for verifying and signing messages. |
| |
| The simplest way to verify signatures is using :func:`verify_signature`:: |
| |
| cert = open('certs.pem').read() |
| valid = crypt.verify_signature(message, signature, cert) |
| |
| If you're going to verify many messages with the same certificate, you can use |
| :class:`RSAVerifier`:: |
| |
| cert = open('certs.pem').read() |
| verifier = crypt.RSAVerifier.from_string(cert) |
| valid = verifier.verify(message, signature) |
| |
| To sign messages use :class:`RSASigner` with a private key:: |
| |
| private_key = open('private_key.pem').read() |
| signer = crypt.RSASigner.from_string(private_key) |
| signature = signer.sign(message) |
| |
| The code above also works for :class:`ES256Signer` and :class:`ES256Verifier`. |
| Note that these two classes are only available if your `cryptography` dependency |
| version is at least 1.4.0. |
| """ |
| |
| import six |
| |
| from google.auth.crypt import base |
| from google.auth.crypt import rsa |
| |
| try: |
| from google.auth.crypt import es256 |
| except ImportError: # pragma: NO COVER |
| es256 = None |
| |
| if es256 is not None: # pragma: NO COVER |
| __all__ = [ |
| "ES256Signer", |
| "ES256Verifier", |
| "RSASigner", |
| "RSAVerifier", |
| "Signer", |
| "Verifier", |
| ] |
| else: # pragma: NO COVER |
| __all__ = ["RSASigner", "RSAVerifier", "Signer", "Verifier"] |
| |
| |
| # Aliases to maintain the v1.0.0 interface, as the crypt module was split |
| # into submodules. |
| Signer = base.Signer |
| Verifier = base.Verifier |
| RSASigner = rsa.RSASigner |
| RSAVerifier = rsa.RSAVerifier |
| |
| if es256 is not None: # pragma: NO COVER |
| ES256Signer = es256.ES256Signer |
| ES256Verifier = es256.ES256Verifier |
| |
| |
| def verify_signature(message, signature, certs, verifier_cls=rsa.RSAVerifier): |
| """Verify an RSA or ECDSA cryptographic signature. |
| |
| Checks that the provided ``signature`` was generated from ``bytes`` using |
| the private key associated with the ``cert``. |
| |
| Args: |
| message (Union[str, bytes]): The plaintext message. |
| signature (Union[str, bytes]): The cryptographic signature to check. |
| certs (Union[Sequence, str, bytes]): The certificate or certificates |
| to use to check the signature. |
| verifier_cls (Optional[~google.auth.crypt.base.Signer]): Which verifier |
| class to use for verification. This can be used to select different |
| algorithms, such as RSA or ECDSA. Default value is :class:`RSAVerifier`. |
| |
| Returns: |
| bool: True if the signature is valid, otherwise False. |
| """ |
| if isinstance(certs, (six.text_type, six.binary_type)): |
| certs = [certs] |
| |
| for cert in certs: |
| verifier = verifier_cls.from_string(cert) |
| if verifier.verify(message, signature): |
| return True |
| return False |