We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add GAE Signer


--- 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/app_engine.py`
Content:
```
1 # Copyright 2016 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 """Google App Engine standard environment credentials.
16 
17 This module provides authentication for application running on App Engine in
18 the standard environment using the `App Identity API`_.
19 
20 
21 .. _App Identity API:
22     https://cloud.google.com/appengine/docs/python/appidentity/
23 """
24 
25 import datetime
26 
27 from google.auth import _helpers
28 from google.auth import credentials
29 
30 try:
31     from google.appengine.api import app_identity
32 except ImportError:
33     app_identity = None
34 
35 
36 def get_project_id():
37     """Gets the project ID for the current App Engine application.
38 
39     Returns:
40         str: The project ID
41 
42     Raises:
43         EnvironmentError: If the App Engine APIs are unavailable.
44     """
45     if app_identity is None:
46         raise EnvironmentError(
47             'The App Engine APIs are not available.')
48     return app_identity.get_application_id()
49 
50 
51 class Credentials(credentials.Scoped, credentials.Signing,
52                   credentials.Credentials):
53     """App Engine standard environment credentials.
54 
55     These credentials use the App Engine App Identity API to obtain access
56     tokens.
57     """
58 
59     def __init__(self, scopes=None, service_account_id=None):
60         """
61         Args:
62             scopes (Sequence[str]): Scopes to request from the App Identity
63                 API.
64             service_account_id (str): The service account ID passed into
65                 :func:`google.appengine.api.app_identity.get_access_token`.
66                 If not specified, the default application service account
67                 ID will be used.
68 
69         Raises:
70             EnvironmentError: If the App Engine APIs are unavailable.
71         """
72         if app_identity is None:
73             raise EnvironmentError(
74                 'The App Engine APIs are not available.')
75 
76         super(Credentials, self).__init__()
77         self._scopes = scopes
78         self._service_account_id = service_account_id
79 
80     @_helpers.copy_docstring(credentials.Credentials)
81     def refresh(self, request):
82         # pylint: disable=unused-argument
83         token, ttl = app_identity.get_access_token(
84             self._scopes, self._service_account_id)
85         expiry = _helpers.utcnow() + datetime.timedelta(seconds=ttl)
86 
87         self.token, self.expiry = token, expiry
88 
89     @property
90     def service_account_email(self):
91         """The service account email."""
92         if self._service_account_id is None:
93             self._service_account_id = app_identity.get_service_account_name()
94         return self._service_account_id
95 
96     @property
97     def requires_scopes(self):
98         """Checks if the credentials requires scopes.
99 
100         Returns:
101             bool: True if there are no scopes set otherwise False.
102         """
103         return not self._scopes
104 
105     @_helpers.copy_docstring(credentials.Scoped)
106     def with_scopes(self, scopes):
107         return Credentials(
108             scopes=scopes, service_account_id=self._service_account_id)
109 
110     @_helpers.copy_docstring(credentials.Signing)
111     def sign_bytes(self, message):
112         return app_identity.sign_blob(message)
113 
114     @property
115     @_helpers.copy_docstring(credentials.Signing)
116     def signer_email(self):
117         return self.service_account_email
118
```

Path: `google/auth/crypt.py`
Content:
```
1 # Copyright 2016 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 """Cryptography helpers for verifying and signing messages.
16 
17 Uses the ``rsa``, ``pyasn1`` and ``pyasn1_modules`` packages
18 to parse PEM files storing PKCS#1 or PKCS#8 keys as well as
19 certificates. There is no support for p12 files.
20 
21 The simplest way to verify signatures is using :func:`verify_signature`::
22 
23     cert = open('certs.pem').read()
24     valid = crypt.verify_signature(message, signature, cert)
25 
26 If you're going to verify many messages with the same certificate, you can use
27 :class:`Verifier`::
28 
29     cert = open('certs.pem').read()
30     verifier = crypt.Verifier.from_string(cert)
31     valid = verifier.verify(message, signature)
32 
33 
34 To sign messages use :class:`Signer` with a private key::
35 
36     private_key = open('private_key.pem').read()
37     signer = crypt.Signer(private_key)
38     signature = signer.sign(message)
39 
40 """
41 
42 from pyasn1.codec.der import decoder
43 from pyasn1_modules import pem
44 from pyasn1_modules.rfc2459 import Certificate
45 from pyasn1_modules.rfc5208 import PrivateKeyInfo
46 import rsa
47 import six
48 
49 from google.auth import _helpers
50 
51 _POW2 = (128, 64, 32, 16, 8, 4, 2, 1)
52 _CERTIFICATE_MARKER = b'-----BEGIN CERTIFICATE-----'
53 _PKCS1_MARKER = ('-----BEGIN RSA PRIVATE KEY-----',
54                  '-----END RSA PRIVATE KEY-----')
55 _PKCS8_MARKER = ('-----BEGIN PRIVATE KEY-----',
56                  '-----END PRIVATE KEY-----')
57 _PKCS8_SPEC = PrivateKeyInfo()
58 
59 
60 def _bit_list_to_bytes(bit_list):
61     """Converts an iterable of 1s and 0s to bytes.
62 
63     Combines the list 8 at a time, treating each group of 8 bits
64     as a single byte.
65 
66     Args:
67         bit_list (Sequence): Sequence of 1s and 0s.
68 
69     Returns:
70         bytes: The decoded bytes.
71     """
72     num_bits = len(bit_list)
73     byte_vals = bytearray()
74     for start in six.moves.xrange(0, num_bits, 8):
75         curr_bits = bit_list[start:start + 8]
76         char_val = sum(val * digit
77                        for val, digit in six.moves.zip(_POW2, curr_bits))
78         byte_vals.append(char_val)
79     return bytes(byte_vals)
80 
81 
82 class Verifier(object):
83     """This object is used to verify cryptographic signatures.
84 
85     Args:
86         public_key (rsa.key.PublicKey): The public key used to verify
87             signatures.
88     """
89 
90     def __init__(self, public_key):
91         self._pubkey = public_key
92 
93     def verify(self, message, signature):
94         """Verifies a message against a cryptographic signature.
95 
96         Args:
97             message (Union[str, bytes]): The message to verify.
98             signature (Union[str, bytes]): The cryptography signature to check.
99 
100         Returns:
101             bool: True if message was signed by the private key associated
102             with the public key that this object was constructed with.
103         """
104         message = _helpers.to_bytes(message)
105         try:
106             return rsa.pkcs1.verify(message, signature, self._pubkey)
107         except (ValueError, rsa.pkcs1.VerificationError):
108             return False
109 
110     @classmethod
111     def from_string(cls, public_key):
112         """Construct an Verifier instance from a public key or public
113         certificate string.
114 
115         Args:
116             public_key (Union[str, bytes]): The public key in PEM format or the
117                 x509 public key certificate.
118 
119         Returns:
120             Verifier: The constructed verifier.
121 
122         Raises:
123             ValueError: If the public_key can't be parsed.
124         """
125         public_key = _helpers.to_bytes(public_key)
126         is_x509_cert = _CERTIFICATE_MARKER in public_key
127 
128         # If this is a certificate, extract the public key info.
129         if is_x509_cert:
130             der = rsa.pem.load_pem(public_key, 'CERTIFICATE')
131             asn1_cert, remaining = decoder.decode(der, asn1Spec=Certificate())
132             if remaining != b'':
133                 raise ValueError('Unused bytes', remaining)
134 
135             cert_info = asn1_cert['tbsCertificate']['subjectPublicKeyInfo']
136             key_bytes = _bit_list_to_bytes(cert_info['subjectPublicKey'])
137             pubkey = rsa.PublicKey.load_pkcs1(key_bytes, 'DER')
138         else:
139             pubkey = rsa.PublicKey.load_pkcs1(public_key, 'PEM')
140         return cls(pubkey)
141 
142 
143 def verify_signature(message, signature, certs):
144     """Verify a cryptographic signature.
145 
146     Checks that the provided ``signature`` was generated from ``bytes`` using
147     the private key associated with the ``cert``.
148 
149     Args:
150         message (Union[str, bytes]): The plaintext message.
151         signature (Union[str, bytes]): The cryptographic signature to check.
152         certs (Union[Sequence, str, bytes]): The certificate or certificates
153             to use to check the signature.
154 
155     Returns:
156         bool: True if the signature is valid, otherwise False.
157     """
158     if isinstance(certs, (six.text_type, six.binary_type)):
159         certs = [certs]
160 
161     for cert in certs:
162         verifier = Verifier.from_string(cert)
163         if verifier.verify(message, signature):
164             return True
165     return False
166 
167 
168 class Signer(object):
169     """Signs messages with a private key.
170 
171     Args:
172         private_key (rsa.key.PrivateKey): The private key to sign with.
173         key_id (str): Optional key ID used to identify this private key. This
174             can be useful to associate the private key with its associated
175             public key or certificate.
176     """
177 
178     def __init__(self, private_key, key_id=None):
179         self._key = private_key
180         self.key_id = key_id
181 
182     def sign(self, message):
183         """Signs a message.
184 
185         Args:
186             message (Union[str, bytes]): The message to be signed.
187 
188         Returns:
189             bytes: The signature of the message for the given key.
190         """
191         message = _helpers.to_bytes(message)
192         return rsa.pkcs1.sign(message, self._key, 'SHA-256')
193 
194     @classmethod
195     def from_string(cls, key, key_id=None):
196         """Construct an Signer instance from a private key in PEM format.
197 
198         Args:
199             key (str): Private key in PEM format.
200             key_id (str): An optional key id used to identify the private key.
201 
202         Returns:
203             Signer: The constructed signer.
204 
205         Raises:
206             ValueError: If the key cannot be parsed as PKCS#1 or PKCS#8 in
207                 PEM format.
208         """
209         key = _helpers.from_bytes(key)  # PEM expects str in Python 3
210         marker_id, key_bytes = pem.readPemBlocksFromFile(
211             six.StringIO(key), _PKCS1_MARKER, _PKCS8_MARKER)
212 
213         # Key is in pkcs1 format.
214         if marker_id == 0:
215             private_key = rsa.key.PrivateKey.load_pkcs1(
216                 key_bytes, format='DER')
217         # Key is in pkcs8.
218         elif marker_id == 1:
219             key_info, remaining = decoder.decode(
220                 key_bytes, asn1Spec=_PKCS8_SPEC)
221             if remaining != b'':
222                 raise ValueError('Unused bytes', remaining)
223             private_key_info = key_info.getComponentByName('privateKey')
224             private_key = rsa.key.PrivateKey.load_pkcs1(
225                 private_key_info.asOctets(), format='DER')
226         else:
227             raise ValueError('No key could be detected.')
228 
229         return cls(private_key, key_id=key_id)
230
```
--- 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/app_engine.py b/google/auth/app_engine.py
--- a/google/auth/app_engine.py
+++ b/google/auth/app_engine.py
@@ -12,10 +12,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Google App Engine standard environment credentials.
+"""Google App Engine standard environment support.
 
-This module provides authentication for application running on App Engine in
-the standard environment using the `App Identity API`_.
+This module provides authentication and signing for applications running on App
+Engine in the standard environment using the `App Identity API`_.
 
 
 .. _App Identity API:
@@ -33,6 +33,29 @@
     app_identity = None
 
 
+class Signer(object):
+    """Signs messages using the App Engine app identity service.
+
+    This can be used in place of :class:`google.auth.crypt.Signer` when
+    running in the App Engine standard environment.
+    """
+    def __init__(self):
+        self.key_id = None
+
+    @staticmethod
+    def sign(message):
+        """Signs a message.
+
+        Args:
+            message (Union[str, bytes]): The message to be signed.
+
+        Returns:
+            bytes: The signature of the message.
+        """
+        message = _helpers.to_bytes(message)
+        return app_identity.sign_blob(message)
+
+
 def get_project_id():
     """Gets the project ID for the current App Engine application.
 
@@ -109,7 +132,7 @@
 
     @_helpers.copy_docstring(credentials.Signing)
     def sign_bytes(self, message):
-        return app_identity.sign_blob(message)
+        return Signer().sign(message)
 
     @property
     @_helpers.copy_docstring(credentials.Signing)
diff --git a/google/auth/crypt.py b/google/auth/crypt.py
--- a/google/auth/crypt.py
+++ b/google/auth/crypt.py
@@ -186,7 +186,7 @@
             message (Union[str, bytes]): The message to be signed.
 
         Returns:
-            bytes: The signature of the message for the given key.
+            bytes: The signature of the message.
         """
         message = _helpers.to_bytes(message)
         return rsa.pkcs1.sign(message, self._key, 'SHA-256')

{"golden_diff": "diff --git a/google/auth/app_engine.py b/google/auth/app_engine.py\n--- a/google/auth/app_engine.py\n+++ b/google/auth/app_engine.py\n@@ -12,10 +12,10 @@\n # See the License for the specific language governing permissions and\n # limitations under the License.\n \n-\"\"\"Google App Engine standard environment credentials.\n+\"\"\"Google App Engine standard environment support.\n \n-This module provides authentication for application running on App Engine in\n-the standard environment using the `App Identity API`_.\n+This module provides authentication and signing for applications running on App\n+Engine in the standard environment using the `App Identity API`_.\n \n \n .. _App Identity API:\n@@ -33,6 +33,29 @@\n     app_identity = None\n \n \n+class Signer(object):\n+    \"\"\"Signs messages using the App Engine app identity service.\n+\n+    This can be used in place of :class:`google.auth.crypt.Signer` when\n+    running in the App Engine standard environment.\n+    \"\"\"\n+    def __init__(self):\n+        self.key_id = None\n+\n+    @staticmethod\n+    def sign(message):\n+        \"\"\"Signs a message.\n+\n+        Args:\n+            message (Union[str, bytes]): The message to be signed.\n+\n+        Returns:\n+            bytes: The signature of the message.\n+        \"\"\"\n+        message = _helpers.to_bytes(message)\n+        return app_identity.sign_blob(message)\n+\n+\n def get_project_id():\n     \"\"\"Gets the project ID for the current App Engine application.\n \n@@ -109,7 +132,7 @@\n \n     @_helpers.copy_docstring(credentials.Signing)\n     def sign_bytes(self, message):\n-        return app_identity.sign_blob(message)\n+        return Signer().sign(message)\n \n     @property\n     @_helpers.copy_docstring(credentials.Signing)\ndiff --git a/google/auth/crypt.py b/google/auth/crypt.py\n--- a/google/auth/crypt.py\n+++ b/google/auth/crypt.py\n@@ -186,7 +186,7 @@\n             message (Union[str, bytes]): The message to be signed.\n \n         Returns:\n-            bytes: The signature of the message for the given key.\n+            bytes: The signature of the message.\n         \"\"\"\n         message = _helpers.to_bytes(message)\n         return rsa.pkcs1.sign(message, self._key, 'SHA-256')\n", "issue": "Add GAE Signer\n\n", "before_files": [{"content": "# Copyright 2016 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\"\"\"Google App Engine standard environment credentials.\n\nThis module provides authentication for application running on App Engine in\nthe standard environment using the `App Identity API`_.\n\n\n.. _App Identity API:\n    https://cloud.google.com/appengine/docs/python/appidentity/\n\"\"\"\n\nimport datetime\n\nfrom google.auth import _helpers\nfrom google.auth import credentials\n\ntry:\n    from google.appengine.api import app_identity\nexcept ImportError:\n    app_identity = None\n\n\ndef get_project_id():\n    \"\"\"Gets the project ID for the current App Engine application.\n\n    Returns:\n        str: The project ID\n\n    Raises:\n        EnvironmentError: If the App Engine APIs are unavailable.\n    \"\"\"\n    if app_identity is None:\n        raise EnvironmentError(\n            'The App Engine APIs are not available.')\n    return app_identity.get_application_id()\n\n\nclass Credentials(credentials.Scoped, credentials.Signing,\n                  credentials.Credentials):\n    \"\"\"App Engine standard environment credentials.\n\n    These credentials use the App Engine App Identity API to obtain access\n    tokens.\n    \"\"\"\n\n    def __init__(self, scopes=None, service_account_id=None):\n        \"\"\"\n        Args:\n            scopes (Sequence[str]): Scopes to request from the App Identity\n                API.\n            service_account_id (str): The service account ID passed into\n                :func:`google.appengine.api.app_identity.get_access_token`.\n                If not specified, the default application service account\n                ID will be used.\n\n        Raises:\n            EnvironmentError: If the App Engine APIs are unavailable.\n        \"\"\"\n        if app_identity is None:\n            raise EnvironmentError(\n                'The App Engine APIs are not available.')\n\n        super(Credentials, self).__init__()\n        self._scopes = scopes\n        self._service_account_id = service_account_id\n\n    @_helpers.copy_docstring(credentials.Credentials)\n    def refresh(self, request):\n        # pylint: disable=unused-argument\n        token, ttl = app_identity.get_access_token(\n            self._scopes, self._service_account_id)\n        expiry = _helpers.utcnow() + datetime.timedelta(seconds=ttl)\n\n        self.token, self.expiry = token, expiry\n\n    @property\n    def service_account_email(self):\n        \"\"\"The service account email.\"\"\"\n        if self._service_account_id is None:\n            self._service_account_id = app_identity.get_service_account_name()\n        return self._service_account_id\n\n    @property\n    def requires_scopes(self):\n        \"\"\"Checks if the credentials requires scopes.\n\n        Returns:\n            bool: True if there are no scopes set otherwise False.\n        \"\"\"\n        return not self._scopes\n\n    @_helpers.copy_docstring(credentials.Scoped)\n    def with_scopes(self, scopes):\n        return Credentials(\n            scopes=scopes, service_account_id=self._service_account_id)\n\n    @_helpers.copy_docstring(credentials.Signing)\n    def sign_bytes(self, message):\n        return app_identity.sign_blob(message)\n\n    @property\n    @_helpers.copy_docstring(credentials.Signing)\n    def signer_email(self):\n        return self.service_account_email\n", "path": "google/auth/app_engine.py"}, {"content": "# Copyright 2016 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\"\"\"Cryptography helpers for verifying and signing messages.\n\nUses the ``rsa``, ``pyasn1`` and ``pyasn1_modules`` packages\nto parse PEM files storing PKCS#1 or PKCS#8 keys as well as\ncertificates. There is no support for p12 files.\n\nThe simplest way to verify signatures is using :func:`verify_signature`::\n\n    cert = open('certs.pem').read()\n    valid = crypt.verify_signature(message, signature, cert)\n\nIf you're going to verify many messages with the same certificate, you can use\n:class:`Verifier`::\n\n    cert = open('certs.pem').read()\n    verifier = crypt.Verifier.from_string(cert)\n    valid = verifier.verify(message, signature)\n\n\nTo sign messages use :class:`Signer` with a private key::\n\n    private_key = open('private_key.pem').read()\n    signer = crypt.Signer(private_key)\n    signature = signer.sign(message)\n\n\"\"\"\n\nfrom pyasn1.codec.der import decoder\nfrom pyasn1_modules import pem\nfrom pyasn1_modules.rfc2459 import Certificate\nfrom pyasn1_modules.rfc5208 import PrivateKeyInfo\nimport rsa\nimport six\n\nfrom google.auth import _helpers\n\n_POW2 = (128, 64, 32, 16, 8, 4, 2, 1)\n_CERTIFICATE_MARKER = b'-----BEGIN CERTIFICATE-----'\n_PKCS1_MARKER = ('-----BEGIN RSA PRIVATE KEY-----',\n                 '-----END RSA PRIVATE KEY-----')\n_PKCS8_MARKER = ('-----BEGIN PRIVATE KEY-----',\n                 '-----END PRIVATE KEY-----')\n_PKCS8_SPEC = PrivateKeyInfo()\n\n\ndef _bit_list_to_bytes(bit_list):\n    \"\"\"Converts an iterable of 1s and 0s to bytes.\n\n    Combines the list 8 at a time, treating each group of 8 bits\n    as a single byte.\n\n    Args:\n        bit_list (Sequence): Sequence of 1s and 0s.\n\n    Returns:\n        bytes: The decoded bytes.\n    \"\"\"\n    num_bits = len(bit_list)\n    byte_vals = bytearray()\n    for start in six.moves.xrange(0, num_bits, 8):\n        curr_bits = bit_list[start:start + 8]\n        char_val = sum(val * digit\n                       for val, digit in six.moves.zip(_POW2, curr_bits))\n        byte_vals.append(char_val)\n    return bytes(byte_vals)\n\n\nclass Verifier(object):\n    \"\"\"This object is used to verify cryptographic signatures.\n\n    Args:\n        public_key (rsa.key.PublicKey): The public key used to verify\n            signatures.\n    \"\"\"\n\n    def __init__(self, public_key):\n        self._pubkey = public_key\n\n    def verify(self, message, signature):\n        \"\"\"Verifies a message against a cryptographic signature.\n\n        Args:\n            message (Union[str, bytes]): The message to verify.\n            signature (Union[str, bytes]): The cryptography signature to check.\n\n        Returns:\n            bool: True if message was signed by the private key associated\n            with the public key that this object was constructed with.\n        \"\"\"\n        message = _helpers.to_bytes(message)\n        try:\n            return rsa.pkcs1.verify(message, signature, self._pubkey)\n        except (ValueError, rsa.pkcs1.VerificationError):\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 = _helpers.to_bytes(public_key)\n        is_x509_cert = _CERTIFICATE_MARKER in public_key\n\n        # If this is a certificate, extract the public key info.\n        if is_x509_cert:\n            der = rsa.pem.load_pem(public_key, 'CERTIFICATE')\n            asn1_cert, remaining = decoder.decode(der, asn1Spec=Certificate())\n            if remaining != b'':\n                raise ValueError('Unused bytes', remaining)\n\n            cert_info = asn1_cert['tbsCertificate']['subjectPublicKeyInfo']\n            key_bytes = _bit_list_to_bytes(cert_info['subjectPublicKey'])\n            pubkey = rsa.PublicKey.load_pkcs1(key_bytes, 'DER')\n        else:\n            pubkey = rsa.PublicKey.load_pkcs1(public_key, 'PEM')\n        return cls(pubkey)\n\n\ndef verify_signature(message, signature, certs):\n    \"\"\"Verify a cryptographic signature.\n\n    Checks that the provided ``signature`` was generated from ``bytes`` using\n    the private key associated with the ``cert``.\n\n    Args:\n        message (Union[str, bytes]): The plaintext message.\n        signature (Union[str, bytes]): The cryptographic signature to check.\n        certs (Union[Sequence, str, bytes]): The certificate or certificates\n            to use to check the signature.\n\n    Returns:\n        bool: True if the signature is valid, otherwise False.\n    \"\"\"\n    if isinstance(certs, (six.text_type, six.binary_type)):\n        certs = [certs]\n\n    for cert in certs:\n        verifier = Verifier.from_string(cert)\n        if verifier.verify(message, signature):\n            return True\n    return False\n\n\nclass Signer(object):\n    \"\"\"Signs messages with a private key.\n\n    Args:\n        private_key (rsa.key.PrivateKey): 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    def sign(self, message):\n        \"\"\"Signs a message.\n\n        Args:\n            message (Union[str, bytes]): The message to be signed.\n\n        Returns:\n            bytes: The signature of the message for the given key.\n        \"\"\"\n        message = _helpers.to_bytes(message)\n        return rsa.pkcs1.sign(message, self._key, 'SHA-256')\n\n    @classmethod\n    def from_string(cls, key, key_id=None):\n        \"\"\"Construct an Signer instance from a private key in PEM format.\n\n        Args:\n            key (str): Private key in PEM format.\n            key_id (str): An optional key id used to identify the private key.\n\n        Returns:\n            Signer: The constructed signer.\n\n        Raises:\n            ValueError: If the key cannot be parsed as PKCS#1 or PKCS#8 in\n                PEM format.\n        \"\"\"\n        key = _helpers.from_bytes(key)  # PEM expects str in Python 3\n        marker_id, key_bytes = pem.readPemBlocksFromFile(\n            six.StringIO(key), _PKCS1_MARKER, _PKCS8_MARKER)\n\n        # Key is in pkcs1 format.\n        if marker_id == 0:\n            private_key = rsa.key.PrivateKey.load_pkcs1(\n                key_bytes, format='DER')\n        # Key is in pkcs8.\n        elif marker_id == 1:\n            key_info, remaining = decoder.decode(\n                key_bytes, asn1Spec=_PKCS8_SPEC)\n            if remaining != b'':\n                raise ValueError('Unused bytes', remaining)\n            private_key_info = key_info.getComponentByName('privateKey')\n            private_key = rsa.key.PrivateKey.load_pkcs1(\n                private_key_info.asOctets(), format='DER')\n        else:\n            raise ValueError('No key could be detected.')\n\n        return cls(private_key, key_id=key_id)\n", "path": "google/auth/crypt.py"}], "after_files": [{"content": "# Copyright 2016 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\"\"\"Google App Engine standard environment support.\n\nThis module provides authentication and signing for applications running on App\nEngine in the standard environment using the `App Identity API`_.\n\n\n.. _App Identity API:\n    https://cloud.google.com/appengine/docs/python/appidentity/\n\"\"\"\n\nimport datetime\n\nfrom google.auth import _helpers\nfrom google.auth import credentials\n\ntry:\n    from google.appengine.api import app_identity\nexcept ImportError:\n    app_identity = None\n\n\nclass Signer(object):\n    \"\"\"Signs messages using the App Engine app identity service.\n\n    This can be used in place of :class:`google.auth.crypt.Signer` when\n    running in the App Engine standard environment.\n    \"\"\"\n    def __init__(self):\n        self.key_id = None\n\n    @staticmethod\n    def sign(message):\n        \"\"\"Signs a message.\n\n        Args:\n            message (Union[str, bytes]): The message to be signed.\n\n        Returns:\n            bytes: The signature of the message.\n        \"\"\"\n        message = _helpers.to_bytes(message)\n        return app_identity.sign_blob(message)\n\n\ndef get_project_id():\n    \"\"\"Gets the project ID for the current App Engine application.\n\n    Returns:\n        str: The project ID\n\n    Raises:\n        EnvironmentError: If the App Engine APIs are unavailable.\n    \"\"\"\n    if app_identity is None:\n        raise EnvironmentError(\n            'The App Engine APIs are not available.')\n    return app_identity.get_application_id()\n\n\nclass Credentials(credentials.Scoped, credentials.Signing,\n                  credentials.Credentials):\n    \"\"\"App Engine standard environment credentials.\n\n    These credentials use the App Engine App Identity API to obtain access\n    tokens.\n    \"\"\"\n\n    def __init__(self, scopes=None, service_account_id=None):\n        \"\"\"\n        Args:\n            scopes (Sequence[str]): Scopes to request from the App Identity\n                API.\n            service_account_id (str): The service account ID passed into\n                :func:`google.appengine.api.app_identity.get_access_token`.\n                If not specified, the default application service account\n                ID will be used.\n\n        Raises:\n            EnvironmentError: If the App Engine APIs are unavailable.\n        \"\"\"\n        if app_identity is None:\n            raise EnvironmentError(\n                'The App Engine APIs are not available.')\n\n        super(Credentials, self).__init__()\n        self._scopes = scopes\n        self._service_account_id = service_account_id\n\n    @_helpers.copy_docstring(credentials.Credentials)\n    def refresh(self, request):\n        # pylint: disable=unused-argument\n        token, ttl = app_identity.get_access_token(\n            self._scopes, self._service_account_id)\n        expiry = _helpers.utcnow() + datetime.timedelta(seconds=ttl)\n\n        self.token, self.expiry = token, expiry\n\n    @property\n    def service_account_email(self):\n        \"\"\"The service account email.\"\"\"\n        if self._service_account_id is None:\n            self._service_account_id = app_identity.get_service_account_name()\n        return self._service_account_id\n\n    @property\n    def requires_scopes(self):\n        \"\"\"Checks if the credentials requires scopes.\n\n        Returns:\n            bool: True if there are no scopes set otherwise False.\n        \"\"\"\n        return not self._scopes\n\n    @_helpers.copy_docstring(credentials.Scoped)\n    def with_scopes(self, scopes):\n        return Credentials(\n            scopes=scopes, service_account_id=self._service_account_id)\n\n    @_helpers.copy_docstring(credentials.Signing)\n    def sign_bytes(self, message):\n        return Signer().sign(message)\n\n    @property\n    @_helpers.copy_docstring(credentials.Signing)\n    def signer_email(self):\n        return self.service_account_email\n", "path": "google/auth/app_engine.py"}, {"content": "# Copyright 2016 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\"\"\"Cryptography helpers for verifying and signing messages.\n\nUses the ``rsa``, ``pyasn1`` and ``pyasn1_modules`` packages\nto parse PEM files storing PKCS#1 or PKCS#8 keys as well as\ncertificates. There is no support for p12 files.\n\nThe simplest way to verify signatures is using :func:`verify_signature`::\n\n    cert = open('certs.pem').read()\n    valid = crypt.verify_signature(message, signature, cert)\n\nIf you're going to verify many messages with the same certificate, you can use\n:class:`Verifier`::\n\n    cert = open('certs.pem').read()\n    verifier = crypt.Verifier.from_string(cert)\n    valid = verifier.verify(message, signature)\n\n\nTo sign messages use :class:`Signer` with a private key::\n\n    private_key = open('private_key.pem').read()\n    signer = crypt.Signer(private_key)\n    signature = signer.sign(message)\n\n\"\"\"\n\nfrom pyasn1.codec.der import decoder\nfrom pyasn1_modules import pem\nfrom pyasn1_modules.rfc2459 import Certificate\nfrom pyasn1_modules.rfc5208 import PrivateKeyInfo\nimport rsa\nimport six\n\nfrom google.auth import _helpers\n\n_POW2 = (128, 64, 32, 16, 8, 4, 2, 1)\n_CERTIFICATE_MARKER = b'-----BEGIN CERTIFICATE-----'\n_PKCS1_MARKER = ('-----BEGIN RSA PRIVATE KEY-----',\n                 '-----END RSA PRIVATE KEY-----')\n_PKCS8_MARKER = ('-----BEGIN PRIVATE KEY-----',\n                 '-----END PRIVATE KEY-----')\n_PKCS8_SPEC = PrivateKeyInfo()\n\n\ndef _bit_list_to_bytes(bit_list):\n    \"\"\"Converts an iterable of 1s and 0s to bytes.\n\n    Combines the list 8 at a time, treating each group of 8 bits\n    as a single byte.\n\n    Args:\n        bit_list (Sequence): Sequence of 1s and 0s.\n\n    Returns:\n        bytes: The decoded bytes.\n    \"\"\"\n    num_bits = len(bit_list)\n    byte_vals = bytearray()\n    for start in six.moves.xrange(0, num_bits, 8):\n        curr_bits = bit_list[start:start + 8]\n        char_val = sum(val * digit\n                       for val, digit in six.moves.zip(_POW2, curr_bits))\n        byte_vals.append(char_val)\n    return bytes(byte_vals)\n\n\nclass Verifier(object):\n    \"\"\"This object is used to verify cryptographic signatures.\n\n    Args:\n        public_key (rsa.key.PublicKey): The public key used to verify\n            signatures.\n    \"\"\"\n\n    def __init__(self, public_key):\n        self._pubkey = public_key\n\n    def verify(self, message, signature):\n        \"\"\"Verifies a message against a cryptographic signature.\n\n        Args:\n            message (Union[str, bytes]): The message to verify.\n            signature (Union[str, bytes]): The cryptography signature to check.\n\n        Returns:\n            bool: True if message was signed by the private key associated\n            with the public key that this object was constructed with.\n        \"\"\"\n        message = _helpers.to_bytes(message)\n        try:\n            return rsa.pkcs1.verify(message, signature, self._pubkey)\n        except (ValueError, rsa.pkcs1.VerificationError):\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 = _helpers.to_bytes(public_key)\n        is_x509_cert = _CERTIFICATE_MARKER in public_key\n\n        # If this is a certificate, extract the public key info.\n        if is_x509_cert:\n            der = rsa.pem.load_pem(public_key, 'CERTIFICATE')\n            asn1_cert, remaining = decoder.decode(der, asn1Spec=Certificate())\n            if remaining != b'':\n                raise ValueError('Unused bytes', remaining)\n\n            cert_info = asn1_cert['tbsCertificate']['subjectPublicKeyInfo']\n            key_bytes = _bit_list_to_bytes(cert_info['subjectPublicKey'])\n            pubkey = rsa.PublicKey.load_pkcs1(key_bytes, 'DER')\n        else:\n            pubkey = rsa.PublicKey.load_pkcs1(public_key, 'PEM')\n        return cls(pubkey)\n\n\ndef verify_signature(message, signature, certs):\n    \"\"\"Verify a cryptographic signature.\n\n    Checks that the provided ``signature`` was generated from ``bytes`` using\n    the private key associated with the ``cert``.\n\n    Args:\n        message (Union[str, bytes]): The plaintext message.\n        signature (Union[str, bytes]): The cryptographic signature to check.\n        certs (Union[Sequence, str, bytes]): The certificate or certificates\n            to use to check the signature.\n\n    Returns:\n        bool: True if the signature is valid, otherwise False.\n    \"\"\"\n    if isinstance(certs, (six.text_type, six.binary_type)):\n        certs = [certs]\n\n    for cert in certs:\n        verifier = Verifier.from_string(cert)\n        if verifier.verify(message, signature):\n            return True\n    return False\n\n\nclass Signer(object):\n    \"\"\"Signs messages with a private key.\n\n    Args:\n        private_key (rsa.key.PrivateKey): 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    def sign(self, message):\n        \"\"\"Signs a message.\n\n        Args:\n            message (Union[str, bytes]): The message to be signed.\n\n        Returns:\n            bytes: The signature of the message.\n        \"\"\"\n        message = _helpers.to_bytes(message)\n        return rsa.pkcs1.sign(message, self._key, 'SHA-256')\n\n    @classmethod\n    def from_string(cls, key, key_id=None):\n        \"\"\"Construct an Signer instance from a private key in PEM format.\n\n        Args:\n            key (str): Private key in PEM format.\n            key_id (str): An optional key id used to identify the private key.\n\n        Returns:\n            Signer: The constructed signer.\n\n        Raises:\n            ValueError: If the key cannot be parsed as PKCS#1 or PKCS#8 in\n                PEM format.\n        \"\"\"\n        key = _helpers.from_bytes(key)  # PEM expects str in Python 3\n        marker_id, key_bytes = pem.readPemBlocksFromFile(\n            six.StringIO(key), _PKCS1_MARKER, _PKCS8_MARKER)\n\n        # Key is in pkcs1 format.\n        if marker_id == 0:\n            private_key = rsa.key.PrivateKey.load_pkcs1(\n                key_bytes, format='DER')\n        # Key is in pkcs8.\n        elif marker_id == 1:\n            key_info, remaining = decoder.decode(\n                key_bytes, asn1Spec=_PKCS8_SPEC)\n            if remaining != b'':\n                raise ValueError('Unused bytes', remaining)\n            private_key_info = key_info.getComponentByName('privateKey')\n            private_key = rsa.key.PrivateKey.load_pkcs1(\n                private_key_info.asOctets(), format='DER')\n        else:\n            raise ValueError('No key could be detected.')\n\n        return cls(private_key, key_id=key_id)\n", "path": "google/auth/crypt.py"}]}