auth_token hashes PKI token once

auth_token was hashing the PKI token multiple times. With this
change, the token is hashed once.

Change-Id: I70d3339d09deb2d3528f141d37138971038f4075
Related-Bug: #1174499
This commit is contained in:
Brant Knudson 2014-05-06 19:33:46 -05:00
parent 3d6d749e6f
commit 41b3abd42d
3 changed files with 38 additions and 20 deletions

View File

@ -164,7 +164,6 @@ from keystoneclient.middleware import memcache_crypt
from keystoneclient.openstack.common import jsonutils
from keystoneclient.openstack.common import memorycache
from keystoneclient.openstack.common import timeutils
from keystoneclient import utils
# alternative middleware configuration in the main application's
@ -876,10 +875,10 @@ class AuthProtocol(object):
raise InvalidUserToken(
'Token authorization failed')
elif cms.is_pkiz(user_token):
verified = self.verify_pkiz_token(user_token)
verified = self.verify_pkiz_token(user_token, token_id)
data = jsonutils.loads(verified)
elif cms.is_asn1_token(user_token):
verified = self.verify_signed_token(user_token)
verified = self.verify_signed_token(user_token, token_id)
data = jsonutils.loads(verified)
else:
data = self.verify_uuid_token(user_token, retry)
@ -1210,11 +1209,8 @@ class AuthProtocol(object):
raise InvalidUserToken()
def is_signed_token_revoked(self, signed_text):
def is_signed_token_revoked(self, token_id):
"""Indicate whether the token appears in the revocation list."""
if isinstance(signed_text, six.text_type):
signed_text = signed_text.encode('utf-8')
token_id = utils.hash_signed_token(signed_text)
is_revoked = self._is_token_id_in_revoked_list(token_id)
if is_revoked:
self.LOG.debug('Token is marked as having been revoked')
@ -1261,17 +1257,17 @@ class AuthProtocol(object):
self.LOG.error('CMS Verify output: %s', err.output)
raise
def verify_signed_token(self, signed_text):
def verify_signed_token(self, signed_text, token_id):
"""Check that the token is unrevoked and has a valid signature."""
if self.is_signed_token_revoked(signed_text):
if self.is_signed_token_revoked(token_id):
raise InvalidUserToken('Token has been revoked')
formatted = cms.token_to_cms(signed_text)
verified = self.cms_verify(formatted)
return verified
def verify_pkiz_token(self, signed_text):
if self.is_signed_token_revoked(signed_text):
def verify_pkiz_token(self, signed_text, token_id):
if self.is_signed_token_revoked(token_id):
raise InvalidUserToken('Token has been revoked')
try:
uncompressed = cms.pkiz_uncompress(signed_text)

View File

@ -31,6 +31,12 @@ CMSDIR = os.path.join(ROOTDIR, 'examples', 'pki', 'cms')
KEYDIR = os.path.join(ROOTDIR, 'examples', 'pki', 'private')
def _hash_signed_token_safe(signed_text, **kwargs):
if isinstance(signed_text, six.text_type):
signed_text = signed_text.encode('utf-8')
return utils.hash_signed_token(signed_text, **kwargs)
class Examples(fixtures.Fixture):
"""Example tokens and certs loaded from the examples directory.
@ -58,10 +64,14 @@ class Examples(fixtures.Fixture):
with open(os.path.join(CMSDIR, 'auth_token_scoped.pem')) as f:
self.SIGNED_TOKEN_SCOPED = cms.cms_to_token(f.read())
self.SIGNED_TOKEN_SCOPED_HASH = _hash_signed_token_safe(
self.SIGNED_TOKEN_SCOPED)
with open(os.path.join(CMSDIR, 'auth_token_unscoped.pem')) as f:
self.SIGNED_TOKEN_UNSCOPED = cms.cms_to_token(f.read())
with open(os.path.join(CMSDIR, 'auth_v3_token_scoped.pem')) as f:
self.SIGNED_v3_TOKEN_SCOPED = cms.cms_to_token(f.read())
self.SIGNED_v3_TOKEN_SCOPED_HASH = _hash_signed_token_safe(
self.SIGNED_v3_TOKEN_SCOPED)
with open(os.path.join(CMSDIR, 'auth_token_revoked.pem')) as f:
self.REVOKED_TOKEN = cms.cms_to_token(f.read())
with open(os.path.join(CMSDIR, 'auth_token_scoped_expired.pem')) as f:

View File

@ -564,27 +564,29 @@ class CommonAuthTokenMiddlewareTest(object):
self.middleware.token_revocation_list = jsonutils.dumps(
{"revoked": [], "extra": "success"})
result = self.middleware.is_signed_token_revoked(
self.token_dict['revoked_token'])
self.token_dict['revoked_token_hash'])
self.assertFalse(result)
def test_is_signed_token_revoked_returns_true(self):
self.middleware.token_revocation_list = self.get_revocation_list_json()
result = self.middleware.is_signed_token_revoked(
self.token_dict['revoked_token'])
self.token_dict['revoked_token_hash'])
self.assertTrue(result)
def test_verify_signed_token_raises_exception_for_revoked_token(self):
self.middleware.token_revocation_list = self.get_revocation_list_json()
self.assertRaises(auth_token.InvalidUserToken,
self.middleware.verify_signed_token,
self.token_dict['revoked_token'])
self.token_dict['revoked_token'],
self.token_dict['revoked_token_hash'])
def test_verify_signed_token_raises_exception_for_revoked_pkiz_token(self):
self.middleware.token_revocation_list = (
self.examples.REVOKED_TOKEN_PKIZ_LIST_JSON)
self.assertRaises(auth_token.InvalidUserToken,
self.middleware.verify_pkiz_token,
self.token_dict['revoked_token_pkiz'])
self.token_dict['revoked_token_pkiz'],
self.token_dict['revoked_token_pkiz_hash'])
def assertIsValidJSON(self, text):
json.loads(text)
@ -592,13 +594,15 @@ class CommonAuthTokenMiddlewareTest(object):
def test_verify_signed_token_succeeds_for_unrevoked_token(self):
self.middleware.token_revocation_list = self.get_revocation_list_json()
text = self.middleware.verify_signed_token(
self.token_dict['signed_token_scoped'])
self.token_dict['signed_token_scoped'],
self.token_dict['signed_token_scoped_hash'])
self.assertIsValidJSON(text)
def test_verify_signed_compressed_token_succeeds_for_unrevoked_token(self):
self.middleware.token_revocation_list = self.get_revocation_list_json()
text = self.middleware.verify_pkiz_token(
self.token_dict['signed_token_scoped_pkiz'])
self.token_dict['signed_token_scoped_pkiz'],
self.token_dict['signed_token_scoped_hash'])
self.assertIsValidJSON(text)
def test_verify_signing_dir_create_while_missing(self):
@ -1200,7 +1204,8 @@ class V2CertDownloadMiddlewareTest(BaseAuthTokenMiddlewareTest,
status=404)
self.assertRaises(exceptions.CertificateConfigError,
self.middleware.verify_signed_token,
self.examples.SIGNED_TOKEN_SCOPED)
self.examples.SIGNED_TOKEN_SCOPED,
self.examples.SIGNED_TOKEN_SCOPED_HASH)
def test_fetch_signing_cert(self):
data = 'FAKE CERT'
@ -1326,11 +1331,14 @@ class v2AuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest,
'uuid_token_unknown_bind': self.examples.UUID_TOKEN_UNKNOWN_BIND,
'signed_token_scoped': self.examples.SIGNED_TOKEN_SCOPED,
'signed_token_scoped_pkiz': self.examples.SIGNED_TOKEN_SCOPED_PKIZ,
'signed_token_scoped_hash': self.examples.SIGNED_TOKEN_SCOPED_HASH,
'signed_token_scoped_expired':
self.examples.SIGNED_TOKEN_SCOPED_EXPIRED,
'revoked_token': self.examples.REVOKED_TOKEN,
'revoked_token_pkiz': self.examples.REVOKED_TOKEN_PKIZ,
'revoked_token_hash': self.examples.REVOKED_TOKEN_HASH
'revoked_token_pkiz_hash':
self.examples.REVOKED_TOKEN_PKIZ_HASH,
'revoked_token_hash': self.examples.REVOKED_TOKEN_HASH,
}
httpretty.reset()
@ -1511,11 +1519,15 @@ class v3AuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest,
'signed_token_scoped': self.examples.SIGNED_v3_TOKEN_SCOPED,
'signed_token_scoped_pkiz':
self.examples.SIGNED_v3_TOKEN_SCOPED_PKIZ,
'signed_token_scoped_hash':
self.examples.SIGNED_v3_TOKEN_SCOPED_HASH,
'signed_token_scoped_expired':
self.examples.SIGNED_TOKEN_SCOPED_EXPIRED,
'revoked_token': self.examples.REVOKED_v3_TOKEN,
'revoked_token_pkiz': self.examples.REVOKED_v3_TOKEN_PKIZ,
'revoked_token_hash': self.examples.REVOKED_v3_TOKEN_HASH
'revoked_token_hash': self.examples.REVOKED_v3_TOKEN_HASH,
'revoked_token_pkiz_hash':
self.examples.REVOKED_v3_PKIZ_TOKEN_HASH,
}
httpretty.reset()