hsm.py 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. """
  2. This module is used to delegate signature generation to HSM(Hardware Security Module)
  3. If public key is given for signing instead of private key, we'll know that
  4. we're trying to delegate signature to HSM. Then we look up key table created
  5. here to find HSM parameters. Here public key is used only as id for HSM
  6. parameters and won't act as a public key.
  7. """
  8. import filecmp
  9. import os
  10. import lib.cert
  11. class HsmParam(object):
  12. """
  13. Parameter for HSM
  14. """
  15. def __init__(self):
  16. # you can add parameter required by your HSM here
  17. self.m_prvk = None
  18. def create_key_table():
  19. """
  20. create key table for public key to private key mapping
  21. """
  22. prvk_list = []
  23. pubk_list = []
  24. key_database_path = os.path.join(os.path.dirname(__file__), 'hsm_test_keys')
  25. keys = os.listdir(key_database_path)
  26. key_table = {}
  27. for key in keys:
  28. key_path = os.path.join(key_database_path, key)
  29. if lib.cert.is_prvk(key_path):
  30. prvk_list.append(key_path)
  31. elif lib.cert.is_pubk(key_path):
  32. pubk_list.append(key_path)
  33. for pubk in pubk_list:
  34. for prvk in prvk_list:
  35. tmp_pubk = os.path.join(os.path.dirname(__file__), 'tmp_pubk.pem')
  36. lib.cert.prvk_to_pubk(prvk, tmp_pubk)
  37. if filecmp.cmp(pubk, tmp_pubk, False) is True:
  38. key_table[pubk] = os.path.join(key_database_path, prvk)
  39. os.remove(tmp_pubk)
  40. break
  41. os.remove(tmp_pubk)
  42. return key_table
  43. def query_key_table(key_table, key):
  44. """
  45. get private key from public key.
  46. In your implementation, you should convert input public
  47. key to parameter passed to HSM, so HSM knows how to sign
  48. message. Here as an example, we search public keys in a folder
  49. as public key data base, and use corresponding private key
  50. to sign message.
  51. """
  52. for pubk in key_table.keys():
  53. if filecmp.cmp(key, pubk, False) is True:
  54. return key_table[pubk]
  55. return None
  56. def hsm_rsa_sign(data, key, padding, sig):
  57. """
  58. sign data with HSM
  59. """
  60. # note that key is pubk actually, use it as index for
  61. # HSM parameters such as key selection
  62. hsm_param_obj = HsmParam()
  63. key_table = create_key_table()
  64. hsm_param_obj.m_prvk = query_key_table(key_table, key)
  65. if hsm_param_obj.m_prvk is None:
  66. print 'not valid HSM parameter'
  67. return -1
  68. print "========================"
  69. print "HSM parameter:"
  70. print " m_prvk = " + hsm_param_obj.m_prvk
  71. print "========================"
  72. # place hsm request here -- start
  73. # we re-direct it to signing with private key to mimic HSM
  74. # data is not hashed here, you can hash data here to reduce
  75. # network usage
  76. lib.cert.sig_gen(data, hsm_param_obj.m_prvk, padding, sig)
  77. # place hsm request here -- end
  78. return 0