__init__.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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. """Cryptography helpers for verifying and signing messages.
  15. The simplest way to verify signatures is using :func:`verify_signature`::
  16. cert = open('certs.pem').read()
  17. valid = crypt.verify_signature(message, signature, cert)
  18. If you're going to verify many messages with the same certificate, you can use
  19. :class:`RSAVerifier`::
  20. cert = open('certs.pem').read()
  21. verifier = crypt.RSAVerifier.from_string(cert)
  22. valid = verifier.verify(message, signature)
  23. To sign messages use :class:`RSASigner` with a private key::
  24. private_key = open('private_key.pem').read()
  25. signer = crypt.RSASigner.from_string(private_key)
  26. signature = signer.sign(message)
  27. The code above also works for :class:`ES256Signer` and :class:`ES256Verifier`.
  28. Note that these two classes are only available if your `cryptography` dependency
  29. version is at least 1.4.0.
  30. """
  31. import six
  32. from google.auth.crypt import base
  33. from google.auth.crypt import rsa
  34. try:
  35. from google.auth.crypt import es256
  36. except ImportError: # pragma: NO COVER
  37. es256 = None
  38. if es256 is not None: # pragma: NO COVER
  39. __all__ = [
  40. "ES256Signer",
  41. "ES256Verifier",
  42. "RSASigner",
  43. "RSAVerifier",
  44. "Signer",
  45. "Verifier",
  46. ]
  47. else: # pragma: NO COVER
  48. __all__ = ["RSASigner", "RSAVerifier", "Signer", "Verifier"]
  49. # Aliases to maintain the v1.0.0 interface, as the crypt module was split
  50. # into submodules.
  51. Signer = base.Signer
  52. Verifier = base.Verifier
  53. RSASigner = rsa.RSASigner
  54. RSAVerifier = rsa.RSAVerifier
  55. if es256 is not None: # pragma: NO COVER
  56. ES256Signer = es256.ES256Signer
  57. ES256Verifier = es256.ES256Verifier
  58. def verify_signature(message, signature, certs, verifier_cls=rsa.RSAVerifier):
  59. """Verify an RSA or ECDSA cryptographic signature.
  60. Checks that the provided ``signature`` was generated from ``bytes`` using
  61. the private key associated with the ``cert``.
  62. Args:
  63. message (Union[str, bytes]): The plaintext message.
  64. signature (Union[str, bytes]): The cryptographic signature to check.
  65. certs (Union[Sequence, str, bytes]): The certificate or certificates
  66. to use to check the signature.
  67. verifier_cls (Optional[~google.auth.crypt.base.Signer]): Which verifier
  68. class to use for verification. This can be used to select different
  69. algorithms, such as RSA or ECDSA. Default value is :class:`RSAVerifier`.
  70. Returns:
  71. bool: True if the signature is valid, otherwise False.
  72. """
  73. if isinstance(certs, (six.text_type, six.binary_type)):
  74. certs = [certs]
  75. for cert in certs:
  76. verifier = verifier_cls.from_string(cert)
  77. if verifier.verify(message, signature):
  78. return True
  79. return False