4 # SFA Certificate Signing and management
9 from optparse import OptionParser
10 from sfa.trust.certificate import Keypair, Certificate
11 from sfa.trust.gid import GID, create_uuid
12 from sfa.trust.hierarchy import Hierarchy
13 from sfa.util.config import Config
14 from collections import defaultdict
19 parser = OptionParser(usage="%(script_name)s [options]" % locals())
20 parser.add_option("-d", "--display", dest="display", default=None,
21 help="print contents of specified gid")
22 parser.add_option("-s", "--sign", dest="sign", default=None,
24 parser.add_option("-k", "--key", dest="key", default=None,
25 help="keyfile to use for signing")
26 parser.add_option("-a", "--authority", dest="authority", default=None,
27 help="sign the gid using the specified authority ")
28 parser.add_option("-i", "--import", dest="importgid", default=None,
29 help="gid file to import into the registry")
30 parser.add_option("-e", "--export", dest="export",
31 help="name of gid to export from registry")
32 parser.add_option("-o", "--outfile", dest="outfile",
33 help="where to write the exprted gid")
34 parser.add_option("-v", "--verbose", dest="verbose", default=False,
35 action="store_true", help="be verbose")
37 (options, args) = parser.parse_args()
44 elif options.importgid:
55 Display the sepcified GID
57 gidfile = os.path.abspath(options.display)
58 if not gidfile or not os.path.isfile(gidfile):
59 print "No such gid: %s" % gidfile
61 gid = GID(filename=gidfile)
62 gid.dump(dump_parents=True)
64 def sign_gid(gid, parent_key, parent_gid):
65 gid.set_issuer(parent_key, parent_gid.get_hrn())
66 gid.set_parent(parent_gid)
72 Sign the specified gid
74 hierarchy = Hierarchy()
76 default_authority = config.SFA_INTERFACE_HRN
77 auth_info = hierarchy.get_auth_info(default_authority)
80 gidfile = os.path.abspath(options.sign)
81 if not os.path.isfile(gidfile):
82 print "no such gid: %s" % gidfile
84 gid = GID(filename=gidfile)
86 # remove previous parent
87 gid = GID(string=gid.save_to_string(save_parents=False))
89 # load the parent private info
90 authority = options.authority
91 # if no pkey was specified, then use the this authority's key
93 authority = default_authority
95 if not hierarchy.auth_exists(authority):
96 print "no such authority: %s" % authority
98 # load the parent gid and key
99 auth_info = hierarchy.get_auth_info(authority)
100 pkeyfile = auth_info.privkey_filename
101 parent_key = Keypair(filename=pkeyfile)
102 parent_gid = auth_info.gid_object
105 outfile = options.outfile
107 outfile = os.path.abspath('./signed-%s.gid' % gid.get_hrn())
109 # check if gid already has a parent
113 print "Signing %s gid with parent %s" % \
114 (gid.get_hrn(), parent_gid.get_hrn())
115 gid = sign_gid(gid, parent_key, parent_gid)
116 # save the signed gid
118 print "Writing signed gid %s" % outfile
119 gid.save_to_file(outfile, save_parents=True)
122 def export_gid(options):
123 from sfa.util.table import SfaTable
124 # lookup the record for the specified hrn
127 # check sfa table first
129 records = table.find({'hrn': hrn, type: 'authority'})
131 # check the authorities hierarchy
132 hierarchy = Hierarchy()
134 auth_info = hierarchy.get_auth_info()
135 gid = auth_info.gid_object
137 print "Record: %s not found" % hrn
141 gid = GID(string=record['gid'])
144 outfile = options.outfile
146 outfile = os.path.abspath('./%s.gid' % gid.get_hrn())
150 print "Writing %s gid to %s" % (gid.get_hrn(), outfile)
151 gid.save_to_file(outfile, save_parents=True)
153 def import_gid(options):
155 Import the specified gid into the registry (db and authorities
156 hierarchy) overwriting any previous gid.
158 from sfa.util.table import SfaTable
159 from sfa.util.record import SfaRecord
161 gidfile = os.path.abspath(options.importgid)
162 if not gidfile or not os.path.isfile(gidfile):
163 print "No such gid: %s" % gidfile
165 gid = GID(filename=gidfile)
167 # check if it exists within the hierarchy
168 hierarchy = Hierarchy()
169 if not hierarchy.auth_exists(gid.get_hrn()):
170 print "%s not found in hierarchy" % gid.get_hrn()
173 # check if record exists in db
175 records = table.find({'hrn': gid.get_hrn(), 'type': 'authority'})
177 print "%s not found in record database" % get.get_hrn()
180 # update the database record
182 record['gid'] = gid.save_to_string(save_parents=True)
185 print "Imported %s gid into db" % record['hrn']
187 # update the hierarchy
188 auth_info = hierarchy.get_auth_info(gid.get_hrn())
189 filename = auth_info.gid_filename
190 gid.save_to_file(filename, save_parents=True)
192 print "Writing %s gid to %s" % (gid.get_hrn(), filename)
194 # re-sign all existing gids signed by this authority
195 # create a dictionary of records keyed on the record's authority
196 record_dict = defaultdict(list)
197 # only get regords that belong to this authority
198 # or any of its sub authorities
199 child_records = table.find({'hrn': '%s*' % gid.get_hrn()})
200 if not child_records:
203 for record in child_records:
204 record_dict[record['authority']].append(record)
206 # start with the authority we just imported
207 authorities = [gid.get_hrn()]
209 next_authorities = []
210 for authority in authorities:
211 # create a new signed gid for each record at this authority
212 # and update the registry
213 auth_info = hierarchy.get_auth_info(authority)
214 records = record_dict[authority]
215 for record in records:
216 record_gid = GID(string=record['gid'])
217 parent_pkey = Keypair(filename=auth_info.privkey_filename)
218 parent_gid = GID(filename=auth_info.gid_filename)
220 print "re-signing %s gid with parent %s" % \
221 (record['hrn'], parent_gid.get_hrn())
222 signed_gid = sign_gid(record_gid, parent_pkey, parent_gid)
223 record['gid'] = signed_gid.save_to_string(save_parents=True)
226 # if this is an authority then update the hierarchy
227 if record['type'] == 'authority':
228 record_info = hierarchy.get_auth_info(record['hrn'])
230 print "Writing %s gid to %s" % (record['hrn'], record_info.gid_filename)
231 signed_gid.save_to_file(filename=record_info.gid_filename, save_parents=True)
233 # update list of next authorities
234 tmp_authorities = set([record['hrn'] for record in records \
235 if record['type'] == 'authority'])
236 next_authorities.extend(tmp_authorities)
238 # move on to next set of authorities
239 authorities = next_authorities
241 if __name__ == '__main__':