feat: add cryptography as required dependency (#1929) · googleapis/google-auth-library-python@52558ae
@@ -12,19 +12,116 @@
1212# See the License for the specific language governing permissions and
1313# limitations under the License.
141415-"""RSA cryptography signer and verifier."""
15+"""
16+RSA cryptography signer and verifier.
161718+This file provides a shared wrapper, that defers to _python_rsa or _cryptography_rsa
19+for implmentations using different third party libraries
20+"""
172118-try:
19-# Prefer cryptograph-based RSA implementation.
20-from google.auth.crypt import _cryptography_rsa
22+from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
23+from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey
212422-RSASigner = _cryptography_rsa.RSASigner
23-RSAVerifier = _cryptography_rsa.RSAVerifier
24-except ImportError: # pragma: NO COVER
25-# Fallback to pure-python RSA implementation if cryptography is
26-# unavailable.
27-from google.auth.crypt import _python_rsa
25+from google.auth import _helpers
26+from google.auth.crypt import _cryptography_rsa
27+from google.auth.crypt import _python_rsa
28+from google.auth.crypt import base
282929-RSASigner = _python_rsa.RSASigner # type: ignore
30-RSAVerifier = _python_rsa.RSAVerifier # type: ignore
30+RSA_KEY_MODULE_PREFIX = "rsa.key"
31+32+33+class RSAVerifier(base.Verifier):
34+"""Verifies RSA cryptographic signatures using public keys.
35+36+ Args:
37+ public_key (Union["rsa.key.PublicKey", cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey]):
38+ The public key used to verify signatures.
39+ Raises:
40+ ValueError: if an unrecognized public key is provided
41+ """
42+43+def __init__(self, public_key):
44+module_str = public_key.__class__.__module__
45+if isinstance(public_key, RSAPublicKey):
46+impl_lib = _cryptography_rsa
47+elif module_str.startswith(RSA_KEY_MODULE_PREFIX):
48+impl_lib = _python_rsa
49+else:
50+raise ValueError(f"unrecognized public key type: {type(public_key)}")
51+self._impl = impl_lib.RSAVerifier(public_key)
52+53+@_helpers.copy_docstring(base.Verifier)
54+def verify(self, message, signature):
55+return self._impl.verify(message, signature)
56+57+@classmethod
58+def from_string(cls, public_key):
59+"""Construct a Verifier instance from a public key or public
60+ certificate string.
61+62+ Args:
63+ public_key (Union[str, bytes]): The public key in PEM format or the
64+ x509 public key certificate.
65+66+ Returns:
67+ google.auth.crypt.Verifier: The constructed verifier.
68+69+ Raises:
70+ ValueError: If the public_key can't be parsed.
71+ """
72+instance = cls.__new__(cls)
73+instance._impl = _cryptography_rsa.RSAVerifier.from_string(public_key)
74+return instance
75+76+77+class RSASigner(base.Signer, base.FromServiceAccountMixin):
78+"""Signs messages with an RSA private key.
79+80+ Args:
81+ private_key (Union["rsa.key.PrivateKey", cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey]):
82+ The private key to sign with.
83+ key_id (str): Optional key ID used to identify this private key. This
84+ can be useful to associate the private key with its associated
85+ public key or certificate.
86+87+ Raises:
88+ ValueError: if an unrecognized public key is provided
89+ """
90+91+def __init__(self, private_key, key_id=None):
92+module_str = private_key.__class__.__module__
93+if isinstance(private_key, RSAPrivateKey):
94+impl_lib = _cryptography_rsa
95+elif module_str.startswith(RSA_KEY_MODULE_PREFIX):
96+impl_lib = _python_rsa
97+else:
98+raise ValueError(f"unrecognized private key type: {type(private_key)}")
99+self._impl = impl_lib.RSASigner(private_key, key_id=key_id)
100+101+@property # type: ignore
102+@_helpers.copy_docstring(base.Signer)
103+def key_id(self):
104+return self._impl.key_id
105+106+@_helpers.copy_docstring(base.Signer)
107+def sign(self, message):
108+return self._impl.sign(message)
109+110+@classmethod
111+def from_string(cls, key, key_id=None):
112+"""Construct a Signer instance from a private key in PEM format.
113+114+ Args:
115+ key (str): Private key in PEM format.
116+ key_id (str): An optional key id used to identify the private key.
117+118+ Returns:
119+ google.auth.crypt.Signer: The constructed signer.
120+121+ Raises:
122+ ValueError: If the key cannot be parsed as PKCS#1 or PKCS#8 in
123+ PEM format.
124+ """
125+instance = cls.__new__(cls)
126+instance._impl = _cryptography_rsa.RSASigner.from_string(key, key_id=key_id)
127+return instance