libsecurity_codesigning-55037.15.tar.gz
[apple/libsecurity_codesigning.git] / gke / gkgenerate
CommitLineData
62e4ed3d
A
1#!/usr/bin/python
2#
3# gkgenerate - produce Gatekeeper explicit allow data
4#
5# gkgenerate [--output name] files...
6# will collect GKE data from all files and write two output files (name.auth and name.sigs)
7# that are ready to drop into a /var/db for pickup.
8#
9import sys
10import os
11import signal
12import errno
13import subprocess
14import argparse
15import plistlib
16import uuid
17
18
19#
20# Parameters and constants
21#
22authfile = "gke.auth"
23sigfile = "gke.dsig"
24
25
26#
27# Usage and fail
28#
29def usage():
30 print >>sys.stderr, "Usage: %s sourcedir" % sys.argv[0]
31 sys.exit(2)
32
33def fail(whatever):
34 print >>sys.stderr, "%s: %s" % (sys.argv[0], whatever)
35 sys.exit(1)
36
37
38#
39# Argument processing
40#
41parser = argparse.ArgumentParser()
42parser.add_argument("--output", default="./gke", help="name of output files")
43parser.add_argument("--uuid", default=uuid.uuid4(), help="explicitly specify the uuid stamp")
44parser.add_argument("--empty", action='store_true', help="allow empty output sets")
45parser.add_argument('source', nargs='+', help='files generated by the gkrecord command')
46args = parser.parse_args()
47
48authfile = args.output + ".auth"
49sigsfile = args.output + ".sigs"
50
51
52#
53# Start by collecting authority evidence from the authority records
54#
55auth = { }
56sigs = { }
57for source in args.source:
58 if source[0] == '+':
59 data = plistlib.readPlist(source[1:])
60 auth.update(data["authority"])
61 sigs.update(data["signatures"])
62 else:
63 data = plistlib.readPlist(source)
64 auth.update(data["authority"])
65
66if not auth and not args.empty:
67 fail("No authority records (nothing to do)")
68
69
70#
71# Scrub the authority records to remove incriminating evidence
72#
73new_auth = { }
74for rec in auth.values():
75 u = uuid.uuid4()
76 rec["path"] = "(gke)"
77 del rec["status"]
78 new_auth[str(u)] = rec
79auth = new_auth
80
81
82#
83# The authority file is written as-is, as a plist
84#
85wrap = dict(
86 authority=auth,
87 uuid=str(args.uuid)
88)
89plistlib.writePlist(wrap, authfile)
90print "Wrote %d authority record(s) to %s" % (len(auth), authfile)
91
92
93#
94# The signatures are written as tightly packed signature blobs
95#
96sigblobs = open(sigsfile, "w")
97for sig in sigs:
98 sigdata = sigs[sig]
99 sigblobs.write(sigdata["signature"].data)
100sigblobs.close()
101print "Wrote %d signature record(s) to %s" % (len(sigs), sigsfile)