1# Copyright 2016 Google LLC 
    2# 
    3# Licensed under the Apache License, Version 2.0 (the "License"); 
    4# you may not use this file except in compliance with the License. 
    5# You may obtain a copy of the License at 
    6# 
    7#      http://www.apache.org/licenses/LICENSE-2.0 
    8# 
    9# Unless required by applicable law or agreed to in writing, software 
    10# distributed under the License is distributed on an "AS IS" BASIS, 
    11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
    12# See the License for the specific language governing permissions and 
    13# limitations under the License. 
    14 
    15"""Cryptography helpers for verifying and signing messages. 
    16 
    17The simplest way to verify signatures is using :func:`verify_signature`:: 
    18 
    19    cert = open('certs.pem').read() 
    20    valid = crypt.verify_signature(message, signature, cert) 
    21 
    22If you're going to verify many messages with the same certificate, you can use 
    23:class:`RSAVerifier`:: 
    24 
    25    cert = open('certs.pem').read() 
    26    verifier = crypt.RSAVerifier.from_string(cert) 
    27    valid = verifier.verify(message, signature) 
    28 
    29To sign messages use :class:`RSASigner` with a private key:: 
    30 
    31    private_key = open('private_key.pem').read() 
    32    signer = crypt.RSASigner.from_string(private_key) 
    33    signature = signer.sign(message) 
    34 
    35The code above also works for :class:`ES256Signer` and :class:`ES256Verifier`. 
    36Note that these two classes are only available if your `cryptography` dependency 
    37version is at least 1.4.0. 
    38""" 
    39 
    40from google.auth.crypt import base 
    41from google.auth.crypt import rsa 
    42 
    43try: 
    44    from google.auth.crypt import es256 
    45except ImportError:  # pragma: NO COVER 
    46    es256 = None  # type: ignore 
    47 
    48if es256 is not None:  # pragma: NO COVER 
    49    __all__ = [ 
    50        "ES256Signer", 
    51        "ES256Verifier", 
    52        "RSASigner", 
    53        "RSAVerifier", 
    54        "Signer", 
    55        "Verifier", 
    56    ] 
    57else:  # pragma: NO COVER 
    58    __all__ = ["RSASigner", "RSAVerifier", "Signer", "Verifier"] 
    59 
    60 
    61# Aliases to maintain the v1.0.0 interface, as the crypt module was split 
    62# into submodules. 
    63Signer = base.Signer 
    64Verifier = base.Verifier 
    65RSASigner = rsa.RSASigner 
    66RSAVerifier = rsa.RSAVerifier 
    67 
    68if es256 is not None:  # pragma: NO COVER 
    69    ES256Signer = es256.ES256Signer 
    70    ES256Verifier = es256.ES256Verifier 
    71 
    72 
    73def verify_signature(message, signature, certs, verifier_cls=rsa.RSAVerifier): 
    74    """Verify an RSA or ECDSA cryptographic signature. 
    75 
    76    Checks that the provided ``signature`` was generated from ``bytes`` using 
    77    the private key associated with the ``cert``. 
    78 
    79    Args: 
    80        message (Union[str, bytes]): The plaintext message. 
    81        signature (Union[str, bytes]): The cryptographic signature to check. 
    82        certs (Union[Sequence, str, bytes]): The certificate or certificates 
    83            to use to check the signature. 
    84        verifier_cls (Optional[~google.auth.crypt.base.Signer]): Which verifier 
    85            class to use for verification. This can be used to select different 
    86            algorithms, such as RSA or ECDSA. Default value is :class:`RSAVerifier`. 
    87 
    88    Returns: 
    89        bool: True if the signature is valid, otherwise False. 
    90    """ 
    91    if isinstance(certs, (str, bytes)): 
    92        certs = [certs] 
    93 
    94    for cert in certs: 
    95        verifier = verifier_cls.from_string(cert) 
    96        if verifier.verify(message, signature): 
    97            return True 
    98    return False