Skip to content

Commit af2d6d8

Browse files
committed
Merge pull request #1518 from dhermes/fix-1408
Removing crypto code and just relying on oauth2client helpers.
2 parents 1193eab + 7ee5e6a commit af2d6d8

File tree

3 files changed

+30
-484
lines changed

3 files changed

+30
-484
lines changed

gcloud/credentials.py

Lines changed: 12 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,7 @@
1919
import six
2020
from six.moves.urllib.parse import urlencode # pylint: disable=F0401
2121

22-
try:
23-
from OpenSSL import crypto
24-
except ImportError: # pragma: NO COVER
25-
# pyOpenSSL can't be installed on App Engine, but it will not
26-
# be needed there since app_identity is used.
27-
crypto = None
28-
2922
from oauth2client import client
30-
from oauth2client import crypt
31-
from oauth2client.service_account import ServiceAccountCredentials
32-
try:
33-
from oauth2client.contrib.appengine import (
34-
AppAssertionCredentials as _GAECreds)
35-
except ImportError:
36-
class _GAECreds(object):
37-
"""Dummy class if not in App Engine environment."""
38-
39-
try:
40-
from google.appengine.api import app_identity
41-
except ImportError:
42-
app_identity = None
4323

4424
from gcloud._helpers import UTC
4525
from gcloud._helpers import _NOW
@@ -102,95 +82,10 @@ def get_credentials():
10282
return client.GoogleCredentials.get_application_default()
10383

10484

105-
def _get_pem_key(credentials):
106-
"""Gets private key for a PEM payload from a credentials object.
107-
108-
:type credentials: :class:`service_account.ServiceAccountCredentials`,
109-
:param credentials: The credentials used to create a private key
110-
for signing text.
111-
112-
:rtype: :class:`OpenSSL.crypto.PKey`
113-
:returns: A PKey object used to sign text.
114-
:raises: `TypeError` if `credentials` is the wrong type.
115-
`EnvironmentError` if `crypto` did not import successfully.
116-
"""
117-
if isinstance(credentials, ServiceAccountCredentials):
118-
if credentials._private_key_pkcs12 is not None:
119-
# Take our PKCS12 (.p12) text and convert to PEM text.
120-
pem_text = crypt.pkcs12_key_as_pem(
121-
credentials._private_key_pkcs12,
122-
credentials._private_key_password)
123-
else:
124-
pem_text = credentials._private_key_pkcs8_pem
125-
else:
126-
raise TypeError((credentials,
127-
'not a valid service account credentials type'))
128-
129-
if crypto is None:
130-
raise EnvironmentError(
131-
'pyOpenSSL must be installed to load a private key')
132-
return crypto.load_privatekey(crypto.FILETYPE_PEM, pem_text)
133-
134-
135-
def _get_signature_bytes(credentials, string_to_sign):
136-
"""Uses crypto attributes of credentials to sign a string/bytes.
137-
138-
:type credentials: :class:`service_account.ServiceAccountCredentials`,
139-
:class:`_GAECreds`
140-
:param credentials: The credentials used for signing text (typically
141-
involves the creation of a PKey).
142-
143-
:type string_to_sign: string
144-
:param string_to_sign: The string to be signed by the credentials.
145-
146-
:rtype: bytes
147-
:returns: Signed bytes produced by the credentials.
148-
:raises: `EnvironmentError` if `crypto` did not import successfully.
149-
"""
150-
if isinstance(credentials, _GAECreds):
151-
_, signed_bytes = app_identity.sign_blob(string_to_sign)
152-
return signed_bytes
153-
else:
154-
# Sign the string with the PKey.
155-
pkey = _get_pem_key(credentials)
156-
if not isinstance(string_to_sign, six.binary_type):
157-
string_to_sign = string_to_sign.encode('utf-8')
158-
if crypto is None:
159-
raise EnvironmentError(
160-
'pyOpenSSL must be installed to sign content using a '
161-
'private key')
162-
return crypto.sign(pkey, string_to_sign, 'SHA256')
163-
164-
165-
def _get_service_account_name(credentials):
166-
"""Determines service account name from a credentials object.
167-
168-
:type credentials: :class:`service_account.ServiceAccountCredentials`,
169-
:class:`_GAECreds`
170-
:param credentials: The credentials used to determine the service
171-
account name.
172-
173-
:rtype: string
174-
:returns: Service account name associated with the credentials.
175-
:raises: :class:`ValueError` if the credentials are not a valid service
176-
account type.
177-
"""
178-
service_account_name = None
179-
if isinstance(credentials, ServiceAccountCredentials):
180-
service_account_name = credentials.service_account_email
181-
elif isinstance(credentials, _GAECreds):
182-
service_account_name = app_identity.get_service_account_name()
183-
184-
if service_account_name is None:
185-
raise ValueError('Service account name could not be determined '
186-
'from credentials')
187-
return service_account_name
188-
189-
19085
def _get_signed_query_params(credentials, expiration, string_to_sign):
19186
"""Gets query parameters for creating a signed URL.
19287
193-
:type credentials: :class:`service_account.ServiceAccountCredentials`
88+
:type credentials: :class:`oauth2client.client.AssertionCredentials`
19489
:param credentials: The credentials used to create a private key
19590
for signing text.
19691
@@ -204,9 +99,9 @@ def _get_signed_query_params(credentials, expiration, string_to_sign):
20499
:returns: Query parameters matching the signing credentials with a
205100
signed payload.
206101
"""
207-
signature_bytes = _get_signature_bytes(credentials, string_to_sign)
102+
_, signature_bytes = credentials.sign_blob(string_to_sign)
208103
signature = base64.b64encode(signature_bytes)
209-
service_account_name = _get_service_account_name(credentials)
104+
service_account_name = credentials.service_account_email
210105
return {
211106
'GoogleAccessId': service_account_name,
212107
'Expires': str(expiration),
@@ -246,6 +141,15 @@ def generate_signed_url(credentials, resource, expiration,
246141
response_disposition=None, generation=None):
247142
"""Generate signed URL to provide query-string auth'n to a resource.
248143
144+
.. note::
145+
146+
Assumes ``credentials`` implements a ``sign_blob()`` method that takes
147+
bytes to sign and returns a pair of the key ID (unused here) and the
148+
signed bytes (this is abstract in the base class
149+
:class:`oauth2client.client.AssertionCredentials`). Also assumes
150+
``credentials`` has a ``service_account_email`` property which
151+
identifies the credentials.
152+
249153
.. note::
250154
251155
If you are on Google Compute Engine, you can't generate a signed URL.

0 commit comments

Comments
 (0)