Revision 615aaaba
b/lib/serializer.py | ||
---|---|---|
31 | 31 |
|
32 | 32 |
import simplejson |
33 | 33 |
import re |
34 |
import hmac |
|
35 | 34 |
|
36 | 35 |
from ganeti import errors |
37 |
|
|
38 |
try: |
|
39 |
from hashlib import sha1 |
|
40 |
except ImportError: |
|
41 |
import sha as sha1 |
|
36 |
from ganeti import utils |
|
42 | 37 |
|
43 | 38 |
|
44 | 39 |
_JSON_INDENT = 2 |
... | ... | |
123 | 118 |
message = salt + key_selector + txt |
124 | 119 |
else: |
125 | 120 |
message = salt + txt |
126 |
signed_dict["hmac"] = hmac.new(key, message, |
|
127 |
sha1).hexdigest() |
|
121 |
signed_dict["hmac"] = utils.Sha1Hmac(key, message) |
|
128 | 122 |
|
129 | 123 |
return DumpJson(signed_dict, indent=False) |
130 | 124 |
|
... | ... | |
162 | 156 |
key_selector = "" |
163 | 157 |
hmac_key = key |
164 | 158 |
|
165 |
if hmac.new(hmac_key, salt + key_selector + msg, |
|
166 |
sha1).hexdigest() != hmac_sign: |
|
159 |
if not utils.VerifySha1Hmac(hmac_key, salt + key_selector + msg, hmac_sign): |
|
167 | 160 |
raise errors.SignatureError('Invalid Signature') |
168 | 161 |
|
169 | 162 |
return LoadJson(msg), salt |
b/lib/utils.py | ||
---|---|---|
2608 | 2608 |
|
2609 | 2609 |
return ("%s: %s/%s\n\n%s" % |
2610 | 2610 |
(constants.X509_CERT_SIGNATURE_HEADER, salt, |
2611 |
hmac.new(key, salt + cert_pem, sha1).hexdigest(),
|
|
2611 |
Sha1Hmac(key, salt + cert_pem),
|
|
2612 | 2612 |
cert_pem)) |
2613 | 2613 |
|
2614 | 2614 |
|
... | ... | |
2647 | 2647 |
# Dump again to ensure it's in a sane format |
2648 | 2648 |
sane_pem = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert) |
2649 | 2649 |
|
2650 |
if signature != hmac.new(key, salt + sane_pem, sha1).hexdigest():
|
|
2650 |
if not VerifySha1Hmac(key, salt + sane_pem, signature):
|
|
2651 | 2651 |
raise errors.GenericError("X509 certificate signature is invalid") |
2652 | 2652 |
|
2653 | 2653 |
return (cert, salt) |
2654 | 2654 |
|
2655 | 2655 |
|
2656 |
def Sha1Hmac(key, text): |
|
2657 |
"""Calculates the HMAC-SHA1 digest of a text. |
|
2658 |
|
|
2659 |
HMAC is defined in RFC2104. |
|
2660 |
|
|
2661 |
@type key: string |
|
2662 |
@param key: Secret key |
|
2663 |
@type text: string |
|
2664 |
|
|
2665 |
""" |
|
2666 |
return hmac.new(key, text, sha1).hexdigest() |
|
2667 |
|
|
2668 |
|
|
2669 |
def VerifySha1Hmac(key, text, digest): |
|
2670 |
"""Verifies the HMAC-SHA1 digest of a text. |
|
2671 |
|
|
2672 |
HMAC is defined in RFC2104. |
|
2673 |
|
|
2674 |
@type key: string |
|
2675 |
@param key: Secret key |
|
2676 |
@type text: string |
|
2677 |
@type digest: string |
|
2678 |
@param digest: Expected digest |
|
2679 |
@rtype: bool |
|
2680 |
@return: Whether HMAC-SHA1 digest matches |
|
2681 |
|
|
2682 |
""" |
|
2683 |
return digest.lower() == Sha1Hmac(key, text).lower() |
|
2684 |
|
|
2685 |
|
|
2656 | 2686 |
def SafeEncode(text): |
2657 | 2687 |
"""Return a 'safe' version of a source string. |
2658 | 2688 |
|
b/test/ganeti.utils_unittest.py | ||
---|---|---|
1999 | 1999 |
self.assertEqual(errcode, utils.CERT_ERROR) |
2000 | 2000 |
|
2001 | 2001 |
|
2002 |
class TestHmacFunctions(unittest.TestCase): |
|
2003 |
# Digests can be checked with "openssl sha1 -hmac $key" |
|
2004 |
def testSha1Hmac(self): |
|
2005 |
self.assertEqual(utils.Sha1Hmac("", ""), |
|
2006 |
"fbdb1d1b18aa6c08324b7d64b71fb76370690e1d") |
|
2007 |
self.assertEqual(utils.Sha1Hmac("3YzMxZWE", "Hello World"), |
|
2008 |
"ef4f3bda82212ecb2f7ce868888a19092481f1fd") |
|
2009 |
self.assertEqual(utils.Sha1Hmac("TguMTA2K", ""), |
|
2010 |
"f904c2476527c6d3e6609ab683c66fa0652cb1dc") |
|
2011 |
|
|
2012 |
longtext = 1500 * "The quick brown fox jumps over the lazy dog\n" |
|
2013 |
self.assertEqual(utils.Sha1Hmac("3YzMxZWE", longtext), |
|
2014 |
"35901b9a3001a7cdcf8e0e9d7c2e79df2223af54") |
|
2015 |
|
|
2016 |
def testVerifySha1Hmac(self): |
|
2017 |
self.assert_(utils.VerifySha1Hmac("", "", ("fbdb1d1b18aa6c08324b" |
|
2018 |
"7d64b71fb76370690e1d"))) |
|
2019 |
self.assert_(utils.VerifySha1Hmac("TguMTA2K", "", |
|
2020 |
("f904c2476527c6d3e660" |
|
2021 |
"9ab683c66fa0652cb1dc"))) |
|
2022 |
|
|
2023 |
digest = "ef4f3bda82212ecb2f7ce868888a19092481f1fd" |
|
2024 |
self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World", digest)) |
|
2025 |
self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World", |
|
2026 |
digest.lower())) |
|
2027 |
self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World", |
|
2028 |
digest.upper())) |
|
2029 |
self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World", |
|
2030 |
digest.title())) |
|
2031 |
|
|
2032 |
|
|
2002 | 2033 |
if __name__ == '__main__': |
2003 | 2034 |
testutils.GanetiTestProgram() |
Also available in: Unified diff