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