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