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