We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
google.oauth2.service_account.Credential objects are not pickleable if cryptography is installed
#### Environment details

  - OS: MacOS 13.5.2
  - Python version: 3.9
  - pip version: 23.1.2
  - `google-auth` version: 2.22.0

#### Steps to reproduce

Install `cryptography`

Run:
```
import pickle
from google.oauth2 import service_account

credentials = service_account.Credentials.from_service_account_file("credentials.json")

pickle.dumps(credentials)
```

The object in question seems to be `credentials._signer` which is either a pickleable pure Python object if `cryptography` is not installed, or else an unpickleable `google.auth.crypt._cryptography_rsa.RSASigner` if it is. Specifically, the signer._key object is of type `cryptography.hazmat.backends.openssl.rsa._RSAPrivateKey`.

This conversation on SO seems related: https://stackoverflow.com/questions/39321606/cant-pickle-an-rsa-key-to-send-over-a-socket

This is impacting the Storage SDK's multiprocessing capability: https://github.com/googleapis/python-storage/issues/1116 despite efforts to work around it.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `google/auth/crypt/es256.py`
Content:
```
1 # Copyright 2017 Google Inc.
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 """ECDSA (ES256) verifier and signer that use the ``cryptography`` library.
16 """
17 
18 from cryptography import utils  # type: ignore
19 import cryptography.exceptions
20 from cryptography.hazmat import backends
21 from cryptography.hazmat.primitives import hashes
22 from cryptography.hazmat.primitives import serialization
23 from cryptography.hazmat.primitives.asymmetric import ec
24 from cryptography.hazmat.primitives.asymmetric import padding
25 from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature
26 from cryptography.hazmat.primitives.asymmetric.utils import encode_dss_signature
27 import cryptography.x509
28 
29 from google.auth import _helpers
30 from google.auth.crypt import base
31 
32 
33 _CERTIFICATE_MARKER = b"-----BEGIN CERTIFICATE-----"
34 _BACKEND = backends.default_backend()
35 _PADDING = padding.PKCS1v15()
36 
37 
38 class ES256Verifier(base.Verifier):
39     """Verifies ECDSA cryptographic signatures using public keys.
40 
41     Args:
42         public_key (
43                 cryptography.hazmat.primitives.asymmetric.ec.ECDSAPublicKey):
44             The public key used to verify signatures.
45     """
46 
47     def __init__(self, public_key):
48         self._pubkey = public_key
49 
50     @_helpers.copy_docstring(base.Verifier)
51     def verify(self, message, signature):
52         # First convert (r||s) raw signature to ASN1 encoded signature.
53         sig_bytes = _helpers.to_bytes(signature)
54         if len(sig_bytes) != 64:
55             return False
56         r = (
57             int.from_bytes(sig_bytes[:32], byteorder="big")
58             if _helpers.is_python_3()
59             else utils.int_from_bytes(sig_bytes[:32], byteorder="big")
60         )
61         s = (
62             int.from_bytes(sig_bytes[32:], byteorder="big")
63             if _helpers.is_python_3()
64             else utils.int_from_bytes(sig_bytes[32:], byteorder="big")
65         )
66         asn1_sig = encode_dss_signature(r, s)
67 
68         message = _helpers.to_bytes(message)
69         try:
70             self._pubkey.verify(asn1_sig, message, ec.ECDSA(hashes.SHA256()))
71             return True
72         except (ValueError, cryptography.exceptions.InvalidSignature):
73             return False
74 
75     @classmethod
76     def from_string(cls, public_key):
77         """Construct an Verifier instance from a public key or public
78         certificate string.
79 
80         Args:
81             public_key (Union[str, bytes]): The public key in PEM format or the
82                 x509 public key certificate.
83 
84         Returns:
85             Verifier: The constructed verifier.
86 
87         Raises:
88             ValueError: If the public key can't be parsed.
89         """
90         public_key_data = _helpers.to_bytes(public_key)
91 
92         if _CERTIFICATE_MARKER in public_key_data:
93             cert = cryptography.x509.load_pem_x509_certificate(
94                 public_key_data, _BACKEND
95             )
96             pubkey = cert.public_key()
97 
98         else:
99             pubkey = serialization.load_pem_public_key(public_key_data, _BACKEND)
100 
101         return cls(pubkey)
102 
103 
104 class ES256Signer(base.Signer, base.FromServiceAccountMixin):
105     """Signs messages with an ECDSA private key.
106 
107     Args:
108         private_key (
109                 cryptography.hazmat.primitives.asymmetric.ec.ECDSAPrivateKey):
110             The private key to sign with.
111         key_id (str): Optional key ID used to identify this private key. This
112             can be useful to associate the private key with its associated
113             public key or certificate.
114     """
115 
116     def __init__(self, private_key, key_id=None):
117         self._key = private_key
118         self._key_id = key_id
119 
120     @property  # type: ignore
121     @_helpers.copy_docstring(base.Signer)
122     def key_id(self):
123         return self._key_id
124 
125     @_helpers.copy_docstring(base.Signer)
126     def sign(self, message):
127         message = _helpers.to_bytes(message)
128         asn1_signature = self._key.sign(message, ec.ECDSA(hashes.SHA256()))
129 
130         # Convert ASN1 encoded signature to (r||s) raw signature.
131         (r, s) = decode_dss_signature(asn1_signature)
132         return (
133             (r.to_bytes(32, byteorder="big") + s.to_bytes(32, byteorder="big"))
134             if _helpers.is_python_3()
135             else (utils.int_to_bytes(r, 32) + utils.int_to_bytes(s, 32))
136         )
137 
138     @classmethod
139     def from_string(cls, key, key_id=None):
140         """Construct a RSASigner from a private key in PEM format.
141 
142         Args:
143             key (Union[bytes, str]): Private key in PEM format.
144             key_id (str): An optional key id used to identify the private key.
145 
146         Returns:
147             google.auth.crypt._cryptography_rsa.RSASigner: The
148             constructed signer.
149 
150         Raises:
151             ValueError: If ``key`` is not ``bytes`` or ``str`` (unicode).
152             UnicodeDecodeError: If ``key`` is ``bytes`` but cannot be decoded
153                 into a UTF-8 ``str``.
154             ValueError: If ``cryptography`` "Could not deserialize key data."
155         """
156         key = _helpers.to_bytes(key)
157         private_key = serialization.load_pem_private_key(
158             key, password=None, backend=_BACKEND
159         )
160         return cls(private_key, key_id=key_id)
161
```

Path: `google/auth/crypt/_cryptography_rsa.py`
Content:
```
1 # Copyright 2017 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 """RSA verifier and signer that use the ``cryptography`` library.
16 
17 This is a much faster implementation than the default (in
18 ``google.auth.crypt._python_rsa``), which depends on the pure-Python
19 ``rsa`` library.
20 """
21 
22 import cryptography.exceptions
23 from cryptography.hazmat import backends
24 from cryptography.hazmat.primitives import hashes
25 from cryptography.hazmat.primitives import serialization
26 from cryptography.hazmat.primitives.asymmetric import padding
27 import cryptography.x509
28 
29 from google.auth import _helpers
30 from google.auth.crypt import base
31 
32 _CERTIFICATE_MARKER = b"-----BEGIN CERTIFICATE-----"
33 _BACKEND = backends.default_backend()
34 _PADDING = padding.PKCS1v15()
35 _SHA256 = hashes.SHA256()
36 
37 
38 class RSAVerifier(base.Verifier):
39     """Verifies RSA cryptographic signatures using public keys.
40 
41     Args:
42         public_key (
43                 cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey):
44             The public key used to verify signatures.
45     """
46 
47     def __init__(self, public_key):
48         self._pubkey = public_key
49 
50     @_helpers.copy_docstring(base.Verifier)
51     def verify(self, message, signature):
52         message = _helpers.to_bytes(message)
53         try:
54             self._pubkey.verify(signature, message, _PADDING, _SHA256)
55             return True
56         except (ValueError, cryptography.exceptions.InvalidSignature):
57             return False
58 
59     @classmethod
60     def from_string(cls, public_key):
61         """Construct an Verifier instance from a public key or public
62         certificate string.
63 
64         Args:
65             public_key (Union[str, bytes]): The public key in PEM format or the
66                 x509 public key certificate.
67 
68         Returns:
69             Verifier: The constructed verifier.
70 
71         Raises:
72             ValueError: If the public key can't be parsed.
73         """
74         public_key_data = _helpers.to_bytes(public_key)
75 
76         if _CERTIFICATE_MARKER in public_key_data:
77             cert = cryptography.x509.load_pem_x509_certificate(
78                 public_key_data, _BACKEND
79             )
80             pubkey = cert.public_key()
81 
82         else:
83             pubkey = serialization.load_pem_public_key(public_key_data, _BACKEND)
84 
85         return cls(pubkey)
86 
87 
88 class RSASigner(base.Signer, base.FromServiceAccountMixin):
89     """Signs messages with an RSA private key.
90 
91     Args:
92         private_key (
93                 cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey):
94             The private key to sign with.
95         key_id (str): Optional key ID used to identify this private key. This
96             can be useful to associate the private key with its associated
97             public key or certificate.
98     """
99 
100     def __init__(self, private_key, key_id=None):
101         self._key = private_key
102         self._key_id = key_id
103 
104     @property  # type: ignore
105     @_helpers.copy_docstring(base.Signer)
106     def key_id(self):
107         return self._key_id
108 
109     @_helpers.copy_docstring(base.Signer)
110     def sign(self, message):
111         message = _helpers.to_bytes(message)
112         return self._key.sign(message, _PADDING, _SHA256)
113 
114     @classmethod
115     def from_string(cls, key, key_id=None):
116         """Construct a RSASigner from a private key in PEM format.
117 
118         Args:
119             key (Union[bytes, str]): Private key in PEM format.
120             key_id (str): An optional key id used to identify the private key.
121 
122         Returns:
123             google.auth.crypt._cryptography_rsa.RSASigner: The
124             constructed signer.
125 
126         Raises:
127             ValueError: If ``key`` is not ``bytes`` or ``str`` (unicode).
128             UnicodeDecodeError: If ``key`` is ``bytes`` but cannot be decoded
129                 into a UTF-8 ``str``.
130             ValueError: If ``cryptography`` "Could not deserialize key data."
131         """
132         key = _helpers.to_bytes(key)
133         private_key = serialization.load_pem_private_key(
134             key, password=None, backend=_BACKEND
135         )
136         return cls(private_key, key_id=key_id)
137
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/google/auth/crypt/_cryptography_rsa.py b/google/auth/crypt/_cryptography_rsa.py
--- a/google/auth/crypt/_cryptography_rsa.py
+++ b/google/auth/crypt/_cryptography_rsa.py
@@ -134,3 +134,18 @@
             key, password=None, backend=_BACKEND
         )
         return cls(private_key, key_id=key_id)
+
+    def __getstate__(self):
+        """Pickle helper that serializes the _key attribute."""
+        state = self.__dict__.copy()
+        state["_key"] = self._key.private_bytes(
+            encoding=serialization.Encoding.PEM,
+            format=serialization.PrivateFormat.PKCS8,
+            encryption_algorithm=serialization.NoEncryption(),
+        )
+        return state
+
+    def __setstate__(self, state):
+        """Pickle helper that deserializes the _key attribute."""
+        state["_key"] = serialization.load_pem_private_key(state["_key"], None)
+        self.__dict__.update(state)
diff --git a/google/auth/crypt/es256.py b/google/auth/crypt/es256.py
--- a/google/auth/crypt/es256.py
+++ b/google/auth/crypt/es256.py
@@ -158,3 +158,18 @@
             key, password=None, backend=_BACKEND
         )
         return cls(private_key, key_id=key_id)
+
+    def __getstate__(self):
+        """Pickle helper that serializes the _key attribute."""
+        state = self.__dict__.copy()
+        state["_key"] = self._key.private_bytes(
+            encoding=serialization.Encoding.PEM,
+            format=serialization.PrivateFormat.PKCS8,
+            encryption_algorithm=serialization.NoEncryption(),
+        )
+        return state
+
+    def __setstate__(self, state):
+        """Pickle helper that deserializes the _key attribute."""
+        state["_key"] = serialization.load_pem_private_key(state["_key"], None)
+        self.__dict__.update(state)

{"golden_diff": "diff --git a/google/auth/crypt/_cryptography_rsa.py b/google/auth/crypt/_cryptography_rsa.py\n--- a/google/auth/crypt/_cryptography_rsa.py\n+++ b/google/auth/crypt/_cryptography_rsa.py\n@@ -134,3 +134,18 @@\n             key, password=None, backend=_BACKEND\n         )\n         return cls(private_key, key_id=key_id)\n+\n+    def __getstate__(self):\n+        \"\"\"Pickle helper that serializes the _key attribute.\"\"\"\n+        state = self.__dict__.copy()\n+        state[\"_key\"] = self._key.private_bytes(\n+            encoding=serialization.Encoding.PEM,\n+            format=serialization.PrivateFormat.PKCS8,\n+            encryption_algorithm=serialization.NoEncryption(),\n+        )\n+        return state\n+\n+    def __setstate__(self, state):\n+        \"\"\"Pickle helper that deserializes the _key attribute.\"\"\"\n+        state[\"_key\"] = serialization.load_pem_private_key(state[\"_key\"], None)\n+        self.__dict__.update(state)\ndiff --git a/google/auth/crypt/es256.py b/google/auth/crypt/es256.py\n--- a/google/auth/crypt/es256.py\n+++ b/google/auth/crypt/es256.py\n@@ -158,3 +158,18 @@\n             key, password=None, backend=_BACKEND\n         )\n         return cls(private_key, key_id=key_id)\n+\n+    def __getstate__(self):\n+        \"\"\"Pickle helper that serializes the _key attribute.\"\"\"\n+        state = self.__dict__.copy()\n+        state[\"_key\"] = self._key.private_bytes(\n+            encoding=serialization.Encoding.PEM,\n+            format=serialization.PrivateFormat.PKCS8,\n+            encryption_algorithm=serialization.NoEncryption(),\n+        )\n+        return state\n+\n+    def __setstate__(self, state):\n+        \"\"\"Pickle helper that deserializes the _key attribute.\"\"\"\n+        state[\"_key\"] = serialization.load_pem_private_key(state[\"_key\"], None)\n+        self.__dict__.update(state)\n", "issue": "google.oauth2.service_account.Credential objects are not pickleable if cryptography is installed\n#### Environment details\r\n\r\n  - OS: MacOS 13.5.2\r\n  - Python version: 3.9\r\n  - pip version: 23.1.2\r\n  - `google-auth` version: 2.22.0\r\n\r\n#### Steps to reproduce\r\n\r\nInstall `cryptography`\r\n\r\nRun:\r\n```\r\nimport pickle\r\nfrom google.oauth2 import service_account\r\n\r\ncredentials = service_account.Credentials.from_service_account_file(\"credentials.json\")\r\n\r\npickle.dumps(credentials)\r\n```\r\n\r\nThe object in question seems to be `credentials._signer` which is either a pickleable pure Python object if `cryptography` is not installed, or else an unpickleable `google.auth.crypt._cryptography_rsa.RSASigner` if it is. Specifically, the signer._key object is of type `cryptography.hazmat.backends.openssl.rsa._RSAPrivateKey`.\r\n\r\nThis conversation on SO seems related: https://stackoverflow.com/questions/39321606/cant-pickle-an-rsa-key-to-send-over-a-socket\r\n\r\nThis is impacting the Storage SDK's multiprocessing capability: https://github.com/googleapis/python-storage/issues/1116 despite efforts to work around it.\n", "before_files": [{"content": "# Copyright 2017 Google Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"ECDSA (ES256) verifier and signer that use the ``cryptography`` library.\n\"\"\"\n\nfrom cryptography import utils  # type: ignore\nimport cryptography.exceptions\nfrom cryptography.hazmat import backends\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.hazmat.primitives import serialization\nfrom cryptography.hazmat.primitives.asymmetric import ec\nfrom cryptography.hazmat.primitives.asymmetric import padding\nfrom cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature\nfrom cryptography.hazmat.primitives.asymmetric.utils import encode_dss_signature\nimport cryptography.x509\n\nfrom google.auth import _helpers\nfrom google.auth.crypt import base\n\n\n_CERTIFICATE_MARKER = b\"-----BEGIN CERTIFICATE-----\"\n_BACKEND = backends.default_backend()\n_PADDING = padding.PKCS1v15()\n\n\nclass ES256Verifier(base.Verifier):\n    \"\"\"Verifies ECDSA cryptographic signatures using public keys.\n\n    Args:\n        public_key (\n                cryptography.hazmat.primitives.asymmetric.ec.ECDSAPublicKey):\n            The public key used to verify signatures.\n    \"\"\"\n\n    def __init__(self, public_key):\n        self._pubkey = public_key\n\n    @_helpers.copy_docstring(base.Verifier)\n    def verify(self, message, signature):\n        # First convert (r||s) raw signature to ASN1 encoded signature.\n        sig_bytes = _helpers.to_bytes(signature)\n        if len(sig_bytes) != 64:\n            return False\n        r = (\n            int.from_bytes(sig_bytes[:32], byteorder=\"big\")\n            if _helpers.is_python_3()\n            else utils.int_from_bytes(sig_bytes[:32], byteorder=\"big\")\n        )\n        s = (\n            int.from_bytes(sig_bytes[32:], byteorder=\"big\")\n            if _helpers.is_python_3()\n            else utils.int_from_bytes(sig_bytes[32:], byteorder=\"big\")\n        )\n        asn1_sig = encode_dss_signature(r, s)\n\n        message = _helpers.to_bytes(message)\n        try:\n            self._pubkey.verify(asn1_sig, message, ec.ECDSA(hashes.SHA256()))\n            return True\n        except (ValueError, cryptography.exceptions.InvalidSignature):\n            return False\n\n    @classmethod\n    def from_string(cls, public_key):\n        \"\"\"Construct an Verifier instance from a public key or public\n        certificate string.\n\n        Args:\n            public_key (Union[str, bytes]): The public key in PEM format or the\n                x509 public key certificate.\n\n        Returns:\n            Verifier: The constructed verifier.\n\n        Raises:\n            ValueError: If the public key can't be parsed.\n        \"\"\"\n        public_key_data = _helpers.to_bytes(public_key)\n\n        if _CERTIFICATE_MARKER in public_key_data:\n            cert = cryptography.x509.load_pem_x509_certificate(\n                public_key_data, _BACKEND\n            )\n            pubkey = cert.public_key()\n\n        else:\n            pubkey = serialization.load_pem_public_key(public_key_data, _BACKEND)\n\n        return cls(pubkey)\n\n\nclass ES256Signer(base.Signer, base.FromServiceAccountMixin):\n    \"\"\"Signs messages with an ECDSA private key.\n\n    Args:\n        private_key (\n                cryptography.hazmat.primitives.asymmetric.ec.ECDSAPrivateKey):\n            The private key to sign with.\n        key_id (str): Optional key ID used to identify this private key. This\n            can be useful to associate the private key with its associated\n            public key or certificate.\n    \"\"\"\n\n    def __init__(self, private_key, key_id=None):\n        self._key = private_key\n        self._key_id = key_id\n\n    @property  # type: ignore\n    @_helpers.copy_docstring(base.Signer)\n    def key_id(self):\n        return self._key_id\n\n    @_helpers.copy_docstring(base.Signer)\n    def sign(self, message):\n        message = _helpers.to_bytes(message)\n        asn1_signature = self._key.sign(message, ec.ECDSA(hashes.SHA256()))\n\n        # Convert ASN1 encoded signature to (r||s) raw signature.\n        (r, s) = decode_dss_signature(asn1_signature)\n        return (\n            (r.to_bytes(32, byteorder=\"big\") + s.to_bytes(32, byteorder=\"big\"))\n            if _helpers.is_python_3()\n            else (utils.int_to_bytes(r, 32) + utils.int_to_bytes(s, 32))\n        )\n\n    @classmethod\n    def from_string(cls, key, key_id=None):\n        \"\"\"Construct a RSASigner from a private key in PEM format.\n\n        Args:\n            key (Union[bytes, str]): Private key in PEM format.\n            key_id (str): An optional key id used to identify the private key.\n\n        Returns:\n            google.auth.crypt._cryptography_rsa.RSASigner: The\n            constructed signer.\n\n        Raises:\n            ValueError: If ``key`` is not ``bytes`` or ``str`` (unicode).\n            UnicodeDecodeError: If ``key`` is ``bytes`` but cannot be decoded\n                into a UTF-8 ``str``.\n            ValueError: If ``cryptography`` \"Could not deserialize key data.\"\n        \"\"\"\n        key = _helpers.to_bytes(key)\n        private_key = serialization.load_pem_private_key(\n            key, password=None, backend=_BACKEND\n        )\n        return cls(private_key, key_id=key_id)\n", "path": "google/auth/crypt/es256.py"}, {"content": "# Copyright 2017 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"RSA verifier and signer that use the ``cryptography`` library.\n\nThis is a much faster implementation than the default (in\n``google.auth.crypt._python_rsa``), which depends on the pure-Python\n``rsa`` library.\n\"\"\"\n\nimport cryptography.exceptions\nfrom cryptography.hazmat import backends\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.hazmat.primitives import serialization\nfrom cryptography.hazmat.primitives.asymmetric import padding\nimport cryptography.x509\n\nfrom google.auth import _helpers\nfrom google.auth.crypt import base\n\n_CERTIFICATE_MARKER = b\"-----BEGIN CERTIFICATE-----\"\n_BACKEND = backends.default_backend()\n_PADDING = padding.PKCS1v15()\n_SHA256 = hashes.SHA256()\n\n\nclass RSAVerifier(base.Verifier):\n    \"\"\"Verifies RSA cryptographic signatures using public keys.\n\n    Args:\n        public_key (\n                cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey):\n            The public key used to verify signatures.\n    \"\"\"\n\n    def __init__(self, public_key):\n        self._pubkey = public_key\n\n    @_helpers.copy_docstring(base.Verifier)\n    def verify(self, message, signature):\n        message = _helpers.to_bytes(message)\n        try:\n            self._pubkey.verify(signature, message, _PADDING, _SHA256)\n            return True\n        except (ValueError, cryptography.exceptions.InvalidSignature):\n            return False\n\n    @classmethod\n    def from_string(cls, public_key):\n        \"\"\"Construct an Verifier instance from a public key or public\n        certificate string.\n\n        Args:\n            public_key (Union[str, bytes]): The public key in PEM format or the\n                x509 public key certificate.\n\n        Returns:\n            Verifier: The constructed verifier.\n\n        Raises:\n            ValueError: If the public key can't be parsed.\n        \"\"\"\n        public_key_data = _helpers.to_bytes(public_key)\n\n        if _CERTIFICATE_MARKER in public_key_data:\n            cert = cryptography.x509.load_pem_x509_certificate(\n                public_key_data, _BACKEND\n            )\n            pubkey = cert.public_key()\n\n        else:\n            pubkey = serialization.load_pem_public_key(public_key_data, _BACKEND)\n\n        return cls(pubkey)\n\n\nclass RSASigner(base.Signer, base.FromServiceAccountMixin):\n    \"\"\"Signs messages with an RSA private key.\n\n    Args:\n        private_key (\n                cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey):\n            The private key to sign with.\n        key_id (str): Optional key ID used to identify this private key. This\n            can be useful to associate the private key with its associated\n            public key or certificate.\n    \"\"\"\n\n    def __init__(self, private_key, key_id=None):\n        self._key = private_key\n        self._key_id = key_id\n\n    @property  # type: ignore\n    @_helpers.copy_docstring(base.Signer)\n    def key_id(self):\n        return self._key_id\n\n    @_helpers.copy_docstring(base.Signer)\n    def sign(self, message):\n        message = _helpers.to_bytes(message)\n        return self._key.sign(message, _PADDING, _SHA256)\n\n    @classmethod\n    def from_string(cls, key, key_id=None):\n        \"\"\"Construct a RSASigner from a private key in PEM format.\n\n        Args:\n            key (Union[bytes, str]): Private key in PEM format.\n            key_id (str): An optional key id used to identify the private key.\n\n        Returns:\n            google.auth.crypt._cryptography_rsa.RSASigner: The\n            constructed signer.\n\n        Raises:\n            ValueError: If ``key`` is not ``bytes`` or ``str`` (unicode).\n            UnicodeDecodeError: If ``key`` is ``bytes`` but cannot be decoded\n                into a UTF-8 ``str``.\n            ValueError: If ``cryptography`` \"Could not deserialize key data.\"\n        \"\"\"\n        key = _helpers.to_bytes(key)\n        private_key = serialization.load_pem_private_key(\n            key, password=None, backend=_BACKEND\n        )\n        return cls(private_key, key_id=key_id)\n", "path": "google/auth/crypt/_cryptography_rsa.py"}], "after_files": [{"content": "# Copyright 2017 Google Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"ECDSA (ES256) verifier and signer that use the ``cryptography`` library.\n\"\"\"\n\nfrom cryptography import utils  # type: ignore\nimport cryptography.exceptions\nfrom cryptography.hazmat import backends\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.hazmat.primitives import serialization\nfrom cryptography.hazmat.primitives.asymmetric import ec\nfrom cryptography.hazmat.primitives.asymmetric import padding\nfrom cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature\nfrom cryptography.hazmat.primitives.asymmetric.utils import encode_dss_signature\nimport cryptography.x509\n\nfrom google.auth import _helpers\nfrom google.auth.crypt import base\n\n\n_CERTIFICATE_MARKER = b\"-----BEGIN CERTIFICATE-----\"\n_BACKEND = backends.default_backend()\n_PADDING = padding.PKCS1v15()\n\n\nclass ES256Verifier(base.Verifier):\n    \"\"\"Verifies ECDSA cryptographic signatures using public keys.\n\n    Args:\n        public_key (\n                cryptography.hazmat.primitives.asymmetric.ec.ECDSAPublicKey):\n            The public key used to verify signatures.\n    \"\"\"\n\n    def __init__(self, public_key):\n        self._pubkey = public_key\n\n    @_helpers.copy_docstring(base.Verifier)\n    def verify(self, message, signature):\n        # First convert (r||s) raw signature to ASN1 encoded signature.\n        sig_bytes = _helpers.to_bytes(signature)\n        if len(sig_bytes) != 64:\n            return False\n        r = (\n            int.from_bytes(sig_bytes[:32], byteorder=\"big\")\n            if _helpers.is_python_3()\n            else utils.int_from_bytes(sig_bytes[:32], byteorder=\"big\")\n        )\n        s = (\n            int.from_bytes(sig_bytes[32:], byteorder=\"big\")\n            if _helpers.is_python_3()\n            else utils.int_from_bytes(sig_bytes[32:], byteorder=\"big\")\n        )\n        asn1_sig = encode_dss_signature(r, s)\n\n        message = _helpers.to_bytes(message)\n        try:\n            self._pubkey.verify(asn1_sig, message, ec.ECDSA(hashes.SHA256()))\n            return True\n        except (ValueError, cryptography.exceptions.InvalidSignature):\n            return False\n\n    @classmethod\n    def from_string(cls, public_key):\n        \"\"\"Construct an Verifier instance from a public key or public\n        certificate string.\n\n        Args:\n            public_key (Union[str, bytes]): The public key in PEM format or the\n                x509 public key certificate.\n\n        Returns:\n            Verifier: The constructed verifier.\n\n        Raises:\n            ValueError: If the public key can't be parsed.\n        \"\"\"\n        public_key_data = _helpers.to_bytes(public_key)\n\n        if _CERTIFICATE_MARKER in public_key_data:\n            cert = cryptography.x509.load_pem_x509_certificate(\n                public_key_data, _BACKEND\n            )\n            pubkey = cert.public_key()\n\n        else:\n            pubkey = serialization.load_pem_public_key(public_key_data, _BACKEND)\n\n        return cls(pubkey)\n\n\nclass ES256Signer(base.Signer, base.FromServiceAccountMixin):\n    \"\"\"Signs messages with an ECDSA private key.\n\n    Args:\n        private_key (\n                cryptography.hazmat.primitives.asymmetric.ec.ECDSAPrivateKey):\n            The private key to sign with.\n        key_id (str): Optional key ID used to identify this private key. This\n            can be useful to associate the private key with its associated\n            public key or certificate.\n    \"\"\"\n\n    def __init__(self, private_key, key_id=None):\n        self._key = private_key\n        self._key_id = key_id\n\n    @property  # type: ignore\n    @_helpers.copy_docstring(base.Signer)\n    def key_id(self):\n        return self._key_id\n\n    @_helpers.copy_docstring(base.Signer)\n    def sign(self, message):\n        message = _helpers.to_bytes(message)\n        asn1_signature = self._key.sign(message, ec.ECDSA(hashes.SHA256()))\n\n        # Convert ASN1 encoded signature to (r||s) raw signature.\n        (r, s) = decode_dss_signature(asn1_signature)\n        return (\n            (r.to_bytes(32, byteorder=\"big\") + s.to_bytes(32, byteorder=\"big\"))\n            if _helpers.is_python_3()\n            else (utils.int_to_bytes(r, 32) + utils.int_to_bytes(s, 32))\n        )\n\n    @classmethod\n    def from_string(cls, key, key_id=None):\n        \"\"\"Construct a RSASigner from a private key in PEM format.\n\n        Args:\n            key (Union[bytes, str]): Private key in PEM format.\n            key_id (str): An optional key id used to identify the private key.\n\n        Returns:\n            google.auth.crypt._cryptography_rsa.RSASigner: The\n            constructed signer.\n\n        Raises:\n            ValueError: If ``key`` is not ``bytes`` or ``str`` (unicode).\n            UnicodeDecodeError: If ``key`` is ``bytes`` but cannot be decoded\n                into a UTF-8 ``str``.\n            ValueError: If ``cryptography`` \"Could not deserialize key data.\"\n        \"\"\"\n        key = _helpers.to_bytes(key)\n        private_key = serialization.load_pem_private_key(\n            key, password=None, backend=_BACKEND\n        )\n        return cls(private_key, key_id=key_id)\n\n    def __getstate__(self):\n        \"\"\"Pickle helper that serializes the _key attribute.\"\"\"\n        state = self.__dict__.copy()\n        state[\"_key\"] = self._key.private_bytes(\n            encoding=serialization.Encoding.PEM,\n            format=serialization.PrivateFormat.PKCS8,\n            encryption_algorithm=serialization.NoEncryption(),\n        )\n        return state\n\n    def __setstate__(self, state):\n        \"\"\"Pickle helper that deserializes the _key attribute.\"\"\"\n        state[\"_key\"] = serialization.load_pem_private_key(state[\"_key\"], None)\n        self.__dict__.update(state)\n", "path": "google/auth/crypt/es256.py"}, {"content": "# Copyright 2017 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"RSA verifier and signer that use the ``cryptography`` library.\n\nThis is a much faster implementation than the default (in\n``google.auth.crypt._python_rsa``), which depends on the pure-Python\n``rsa`` library.\n\"\"\"\n\nimport cryptography.exceptions\nfrom cryptography.hazmat import backends\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.hazmat.primitives import serialization\nfrom cryptography.hazmat.primitives.asymmetric import padding\nimport cryptography.x509\n\nfrom google.auth import _helpers\nfrom google.auth.crypt import base\n\n_CERTIFICATE_MARKER = b\"-----BEGIN CERTIFICATE-----\"\n_BACKEND = backends.default_backend()\n_PADDING = padding.PKCS1v15()\n_SHA256 = hashes.SHA256()\n\n\nclass RSAVerifier(base.Verifier):\n    \"\"\"Verifies RSA cryptographic signatures using public keys.\n\n    Args:\n        public_key (\n                cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey):\n            The public key used to verify signatures.\n    \"\"\"\n\n    def __init__(self, public_key):\n        self._pubkey = public_key\n\n    @_helpers.copy_docstring(base.Verifier)\n    def verify(self, message, signature):\n        message = _helpers.to_bytes(message)\n        try:\n            self._pubkey.verify(signature, message, _PADDING, _SHA256)\n            return True\n        except (ValueError, cryptography.exceptions.InvalidSignature):\n            return False\n\n    @classmethod\n    def from_string(cls, public_key):\n        \"\"\"Construct an Verifier instance from a public key or public\n        certificate string.\n\n        Args:\n            public_key (Union[str, bytes]): The public key in PEM format or the\n                x509 public key certificate.\n\n        Returns:\n            Verifier: The constructed verifier.\n\n        Raises:\n            ValueError: If the public key can't be parsed.\n        \"\"\"\n        public_key_data = _helpers.to_bytes(public_key)\n\n        if _CERTIFICATE_MARKER in public_key_data:\n            cert = cryptography.x509.load_pem_x509_certificate(\n                public_key_data, _BACKEND\n            )\n            pubkey = cert.public_key()\n\n        else:\n            pubkey = serialization.load_pem_public_key(public_key_data, _BACKEND)\n\n        return cls(pubkey)\n\n\nclass RSASigner(base.Signer, base.FromServiceAccountMixin):\n    \"\"\"Signs messages with an RSA private key.\n\n    Args:\n        private_key (\n                cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey):\n            The private key to sign with.\n        key_id (str): Optional key ID used to identify this private key. This\n            can be useful to associate the private key with its associated\n            public key or certificate.\n    \"\"\"\n\n    def __init__(self, private_key, key_id=None):\n        self._key = private_key\n        self._key_id = key_id\n\n    @property  # type: ignore\n    @_helpers.copy_docstring(base.Signer)\n    def key_id(self):\n        return self._key_id\n\n    @_helpers.copy_docstring(base.Signer)\n    def sign(self, message):\n        message = _helpers.to_bytes(message)\n        return self._key.sign(message, _PADDING, _SHA256)\n\n    @classmethod\n    def from_string(cls, key, key_id=None):\n        \"\"\"Construct a RSASigner from a private key in PEM format.\n\n        Args:\n            key (Union[bytes, str]): Private key in PEM format.\n            key_id (str): An optional key id used to identify the private key.\n\n        Returns:\n            google.auth.crypt._cryptography_rsa.RSASigner: The\n            constructed signer.\n\n        Raises:\n            ValueError: If ``key`` is not ``bytes`` or ``str`` (unicode).\n            UnicodeDecodeError: If ``key`` is ``bytes`` but cannot be decoded\n                into a UTF-8 ``str``.\n            ValueError: If ``cryptography`` \"Could not deserialize key data.\"\n        \"\"\"\n        key = _helpers.to_bytes(key)\n        private_key = serialization.load_pem_private_key(\n            key, password=None, backend=_BACKEND\n        )\n        return cls(private_key, key_id=key_id)\n\n    def __getstate__(self):\n        \"\"\"Pickle helper that serializes the _key attribute.\"\"\"\n        state = self.__dict__.copy()\n        state[\"_key\"] = self._key.private_bytes(\n            encoding=serialization.Encoding.PEM,\n            format=serialization.PrivateFormat.PKCS8,\n            encryption_algorithm=serialization.NoEncryption(),\n        )\n        return state\n\n    def __setstate__(self, state):\n        \"\"\"Pickle helper that deserializes the _key attribute.\"\"\"\n        state[\"_key\"] = serialization.load_pem_private_key(state[\"_key\"], None)\n        self.__dict__.update(state)\n", "path": "google/auth/crypt/_cryptography_rsa.py"}]}