]> git.saurik.com Git - apple/security.git/blob - libsecurity_codesigning/gke/gkgenerate
Security-55163.44.tar.gz
[apple/security.git] / libsecurity_codesigning / gke / gkgenerate
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 #
9 import sys
10 import os
11 import signal
12 import errno
13 import subprocess
14 import argparse
15 import plistlib
16 import uuid
17
18
19 #
20 # Parameters and constants
21 #
22 authfile = "gke.auth"
23 sigfile = "gke.dsig"
24
25
26 #
27 # Usage and fail
28 #
29 def usage():
30 print >>sys.stderr, "Usage: %s sourcedir" % sys.argv[0]
31 sys.exit(2)
32
33 def fail(whatever):
34 print >>sys.stderr, "%s: %s" % (sys.argv[0], whatever)
35 sys.exit(1)
36
37
38 #
39 # Argument processing
40 #
41 parser = argparse.ArgumentParser()
42 parser.add_argument("--output", default="./gke", help="name of output files")
43 parser.add_argument("--uuid", default=uuid.uuid4(), help="explicitly specify the uuid stamp")
44 parser.add_argument("--empty", action='store_true', help="allow empty output sets")
45 parser.add_argument('source', nargs='+', help='files generated by the gkrecord command')
46 args = parser.parse_args()
47
48 authfile = args.output + ".auth"
49 sigsfile = args.output + ".sigs"
50
51
52 #
53 # Start by collecting authority evidence from the authority records
54 #
55 auth = { }
56 sigs = { }
57 for 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
66 if 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 #
73 new_auth = { }
74 for rec in auth.values():
75 u = uuid.uuid4()
76 rec["path"] = "(gke)"
77 del rec["status"]
78 new_auth[str(u)] = rec
79 auth = new_auth
80
81
82 #
83 # The authority file is written as-is, as a plist
84 #
85 wrap = dict(
86 authority=auth,
87 uuid=str(args.uuid)
88 )
89 plistlib.writePlist(wrap, authfile)
90 print "Wrote %d authority record(s) to %s" % (len(auth), authfile)
91
92
93 #
94 # The signatures are written as tightly packed signature blobs
95 #
96 sigblobs = open(sigsfile, "w")
97 for sig in sigs:
98 sigdata = sigs[sig]
99 sigblobs.write(sigdata["signature"].data)
100 sigblobs.close()
101 print "Wrote %d signature record(s) to %s" % (len(sigs), sigsfile)