]> git.saurik.com Git - apple/security.git/blame - Security/libsecurity_codesigning/gke/gkgenerate
Security-57031.40.6.tar.gz
[apple/security.git] / Security / libsecurity_codesigning / gke / gkgenerate
CommitLineData
b1ab9ed8
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
b1ab9ed8
A
25#
26# Usage and fail
27#
28def usage():
29 print >>sys.stderr, "Usage: %s sourcedir" % sys.argv[0]
30 sys.exit(2)
31
32def fail(whatever):
33 print >>sys.stderr, "%s: %s" % (sys.argv[0], whatever)
34 sys.exit(1)
35
36
37#
38# Argument processing
39#
40parser = argparse.ArgumentParser()
41parser.add_argument("--output", default="./gke", help="name of output files")
42parser.add_argument("--uuid", default=uuid.uuid4(), help="explicitly specify the uuid stamp")
43parser.add_argument("--empty", action='store_true', help="allow empty output sets")
44parser.add_argument('source', nargs='+', help='files generated by the gkrecord command')
45args = parser.parse_args()
46
47authfile = args.output + ".auth"
48sigsfile = args.output + ".sigs"
49
50
313fa17b
A
51#
52# Augment a snippet record
53#
54def augment(data):
55 for auth in data.authority.values():
56 if auth.path in data.signatures:
57 signature = data.signatures[auth.path].signature.data
58 unpack = subprocess.Popen(["/usr/local/bin/gkunpack"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
59 (stdout, stderr) = unpack.communicate(input=signature)
60 if stderr:
61 fail("signature unpack failed for %s" % auth.path)
62 auth.screen = stdout.rstrip();
63
64
b1ab9ed8
A
65#
66# Start by collecting authority evidence from the authority records
67#
68auth = { }
69sigs = { }
70for source in args.source:
71 if source[0] == '+':
72 data = plistlib.readPlist(source[1:])
313fa17b 73 augment(data)
b1ab9ed8
A
74 auth.update(data["authority"])
75 sigs.update(data["signatures"])
76 else:
77 data = plistlib.readPlist(source)
313fa17b 78 augment(data)
b1ab9ed8
A
79 auth.update(data["authority"])
80
81if not auth and not args.empty:
82 fail("No authority records (nothing to do)")
83
84
85#
86# Scrub the authority records to remove incriminating evidence
87#
88new_auth = { }
89for rec in auth.values():
90 u = uuid.uuid4()
91 rec["path"] = "(gke)"
92 del rec["status"]
93 new_auth[str(u)] = rec
94auth = new_auth
95
96
97#
98# The authority file is written as-is, as a plist
99#
100wrap = dict(
101 authority=auth,
102 uuid=str(args.uuid)
103)
104plistlib.writePlist(wrap, authfile)
105print "Wrote %d authority record(s) to %s" % (len(auth), authfile)
106
107
108#
109# The signatures are written as tightly packed signature blobs
110#
111sigblobs = open(sigsfile, "w")
112for sig in sigs:
113 sigdata = sigs[sig]
114 sigblobs.write(sigdata["signature"].data)
115sigblobs.close()
116print "Wrote %d signature record(s) to %s" % (len(sigs), sigsfile)