nova.auth.signer.Signer now honors the SignatureMethod parameter for
SHA1 when creating signatures

Change-Id: I4050407d374d18427f9a955ea98242f7325a5d54
This commit is contained in:
Brendan Maguire 2011-09-28 13:10:41 +01:00
parent ef22c0054c
commit 6183586fab
2 changed files with 49 additions and 18 deletions

View File

@ -53,8 +53,8 @@ import boto
# NOTE(vish): for old boto # NOTE(vish): for old boto
import boto.utils import boto.utils
from nova import exception
from nova import log as logging from nova import log as logging
from nova.exception import Error
LOG = logging.getLogger('nova.signer') LOG = logging.getLogger('nova.signer')
@ -81,8 +81,7 @@ class Signer(object):
def generate(self, params, verb, server_string, path): def generate(self, params, verb, server_string, path):
"""Generate auth string according to what SignatureVersion is given. """Generate auth string according to what SignatureVersion is given.
The signature method defaults to SHA256 if available, or falls back to The signature method must be SHA1 or SHA256.
SHA1 if not.
""" """
if params['SignatureVersion'] == '0': if params['SignatureVersion'] == '0':
@ -91,7 +90,7 @@ class Signer(object):
return self._calc_signature_1(params) return self._calc_signature_1(params)
if params['SignatureVersion'] == '2': if params['SignatureVersion'] == '2':
return self._calc_signature_2(params, verb, server_string, path) return self._calc_signature_2(params, verb, server_string, path)
raise Error('Unknown Signature Version: %s' % raise exception.Error('Unknown Signature Version: %s' %
params['SignatureVersion']) params['SignatureVersion'])
@staticmethod @staticmethod
@ -132,12 +131,20 @@ class Signer(object):
"""Generate AWS signature version 2 string.""" """Generate AWS signature version 2 string."""
LOG.debug('using _calc_signature_2') LOG.debug('using _calc_signature_2')
string_to_sign = '%s\n%s\n%s\n' % (verb, server_string, path) string_to_sign = '%s\n%s\n%s\n' % (verb, server_string, path)
if self.hmac_256:
if 'SignatureMethod' not in params:
raise exception.Error('No SignatureMethod specified')
if params['SignatureMethod'] == 'HmacSHA256':
if not self.hmac_256:
raise exception.Error('SHA256 not supported on this server')
current_hmac = self.hmac_256 current_hmac = self.hmac_256
params['SignatureMethod'] = 'HmacSHA256' elif params['SignatureMethod'] == 'HmacSHA1':
else:
current_hmac = self.hmac current_hmac = self.hmac
params['SignatureMethod'] = 'HmacSHA1' else:
raise exception.Error('SignatureMethod %s not supported'
% params['SignatureMethod'])
keys = params.keys() keys = params.keys()
keys.sort() keys.sort()
pairs = [] pairs = []
@ -157,5 +164,6 @@ class Signer(object):
if __name__ == '__main__': if __name__ == '__main__':
print Signer('foo').generate({'SignatureVersion': '2'}, 'get', 'server', print Signer('foo').generate({'SignatureVersion': '2',
'/foo') 'SignatureMethod': 'HmacSHA256'},
'get', 'server', '/foo')

View File

@ -54,14 +54,33 @@ class SignerTestCase(test.TestCase):
'PUT', 'PUT',
'/johnsmith/photos/puppy.jpg')) '/johnsmith/photos/puppy.jpg'))
def test_generate_using_version_2(self): def test_generate_HmacSHA256(self):
self.assertEquals('clXalhbLZXxEuI32OoX+OeXsN6Mr2q4jzGyIDAr4RZg=', self.assertEquals('clXalhbLZXxEuI32OoX+OeXsN6Mr2q4jzGyIDAr4RZg=',
self.signer.generate( self.signer.generate(
{'SignatureMethod': 'HmacSHA256', {'SignatureMethod': 'HmacSHA256',
'SignatureVersion': '2'}, 'SignatureVersion': '2'},
'GET', 'server', '/foo')) 'GET', 'server', '/foo'))
def test_generate_force_HmacSHA1(self): def test_generate_HmacSHA1(self):
self.assertEquals('uJTByiDIcgB65STrS5i2egQgd+U=',
self.signer.generate({'SignatureVersion': '2',
'SignatureMethod': 'HmacSHA1'},
'GET', 'server', '/foo'))
def test_generate_invalid_signature_method_defined(self):
self.assertRaises(exception.Error,
self.signer.generate,
{'SignatureVersion': '2',
'SignatureMethod': 'invalid_method'},
'GET', 'server', '/foo')
def test_generate_no_signature_method_defined(self):
self.assertRaises(exception.Error,
self.signer.generate,
{'SignatureVersion': '2'},
'GET', 'server', '/foo')
def test_generate_HmacSHA256_missing_hashlib_sha256(self):
# Stub out haslib.sha256 # Stub out haslib.sha256
import hashlib import hashlib
self.stubs.Set(hashlib, 'sha256', None) self.stubs.Set(hashlib, 'sha256', None)
@ -69,20 +88,24 @@ class SignerTestCase(test.TestCase):
# Create Signer again now that hashlib.sha256 is None # Create Signer again now that hashlib.sha256 is None
self.signer = signer.Signer( self.signer = signer.Signer(
'uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o') 'uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o')
self.assertEquals('uJTByiDIcgB65STrS5i2egQgd+U=', self.assertRaises(exception.Error,
self.signer.generate({'SignatureVersion': '2'}, self.signer.generate,
'GET', 'server', '/foo')) {'SignatureVersion': '2',
'SignatureMethod': 'HmacSHA256'},
'GET', 'server', '/foo')
def test_generate_with_unicode_param(self): def test_generate_with_unicode_param(self):
self.assertEquals('clXalhbLZXxEuI32OoX+OeXsN6Mr2q4jzGyIDAr4RZg=', self.assertEquals('clXalhbLZXxEuI32OoX+OeXsN6Mr2q4jzGyIDAr4RZg=',
self.signer.generate({'SignatureVersion': u'2'}, self.signer.generate({'SignatureVersion': u'2',
'GET', 'server', '/foo')) 'SignatureMethod': 'HmacSHA256'},
'GET', 'server', '/foo'))
def test_generate_with_non_string_or_unicode_param(self): def test_generate_with_non_string_or_unicode_param(self):
self.assertEquals('99IAgCkhTR2aMTgRobnzKGuNxVFSdb7vlQRvnj3Urqk=', self.assertEquals('99IAgCkhTR2aMTgRobnzKGuNxVFSdb7vlQRvnj3Urqk=',
self.signer.generate( self.signer.generate(
{'AnotherParam': ClassWithStrRepr(), {'AnotherParam': ClassWithStrRepr(),
'SignatureVersion': '2'}, 'SignatureVersion': '2',
'SignatureMethod': 'HmacSHA256'},
'GET', 'server', '/foo')) 'GET', 'server', '/foo'))
def test_generate_unknown_version(self): def test_generate_unknown_version(self):