-
Notifications
You must be signed in to change notification settings - Fork 203
/
Copy pathgramine-sgx-sign
executable file
·118 lines (100 loc) · 4.1 KB
/
gramine-sgx-sign
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/python3
# SPDX-License-Identifier: LGPL-3.0-or-later
# Copyright (C) 2021 Intel Corporation
# Borys Popławski <[email protected]>
import datetime
import sys
import click
from graminelibos import (
Manifest, get_tbssigstruct, SGX_LIBPAL,
)
# TODO: after python (>= 3.10) simplify this
# NOTE: we can't `try: importlib.metadata`, because the API has changed between 3.9 and 3.10
# (in 3.9 and in backported importlib_metadata entry_points() doesn't accept group argument)
if sys.version_info >= (3, 10):
from importlib.metadata import entry_points # pylint: disable=import-error,no-name-in-module
else:
from pkg_resources import iter_entry_points as entry_points
def list_sgx_sign_plugins():
return [ep.name for ep in entry_points(group='gramine.sgx_sign')]
def get_sgx_sign_plugin(name):
for ep in entry_points(group='gramine.sgx_sign'):
if ep.name == name:
return ep.load()
raise KeyError(name)
@click.command(
context_settings={'ignore_unknown_options': True},
help='Use --with=PLUGIN --help-PLUGIN to get help about particular plugin.',
)
@click.option('--with', 'with_', metavar='PLUGIN',
type=click.Choice(list_sgx_sign_plugins()),
default='file',
help='Choose plugin with which to sign the enclave (default: file)')
@click.option('--output', '-o',
type=click.Path(),
required=True,
help='Output .manifest.sgx file (manifest augmented with autogenerated fields)')
@click.option('--libpal', '-l',
type=click.Path(exists=True, dir_okay=False),
default=SGX_LIBPAL,
help='Input libpal file')
@click.option('--manifest', '-m', 'manifest_file',
type=click.File('r', encoding='utf-8'),
required=True,
help='Input .manifest file')
@click.option('--sigfile', '-s',
help='Output .sig file')
@click.option('--depfile',
type=click.File('w'),
help='Generate dependencies for .manifest.sgx and .sig files')
@click.option('--verbose/--quiet', '-v/-q',
default=True,
help='Display details (on by default)')
@click.argument('plugin_args',
nargs=-1,
type=click.UNPROCESSED)
def main(with_, output, libpal, manifest_file, sigfile, depfile, verbose, plugin_args):
# pylint: disable=too-many-arguments, too-many-locals
sign_func = get_sgx_sign_plugin(with_)(args=plugin_args, standalone_mode=False)
try:
it = iter(sign_func)
# no TypeError, therefore we've got tuple or list, or sth else iterable
sign_func, extra_deps = it
except TypeError:
# sign_func is probably just a callable (no need to check, will break later if it isn't)
# and extra dependencies were not provided
extra_deps = ()
manifest = Manifest.load(manifest_file)
expanded = manifest.expand_all_trusted_files()
with open(output, 'wb') as f:
manifest.dump(f)
if not sigfile:
if manifest_file.name.endswith('.manifest'):
sigfile = manifest_file.name[:-len('.manifest')]
else:
sigfile = manifest_file.name
sigfile += '.sig'
today = datetime.date.today()
sigstruct = get_tbssigstruct(output, today, libpal, verbose=verbose)
sigstruct.sign(sign_func)
with open(sigfile, 'wb') as f:
f.write(sigstruct.to_bytes())
if depfile:
# Dependencies:
#
# - `.manifest.sgx` depends on all files we just expanded
# - `.sig` additionally depends on libpal and key
#
# TODO (Ninja 1.10): We print all these as dependencies for `.manifest.sgx`. This will still
# cause `.sig` to be rebuilt when necessary: we build both these files together, so it's not
# possible to rebuild one without the other.
#
# This is a workaround for the fact that Ninja prior to version 1.10 does not
# support depfiles with multiple outputs (and parses such depfiles incorrectly).
deps = [*expanded, libpal, *extra_deps]
depfile.write(f'{output}:')
for filename in deps:
depfile.write(f' \\\n\t{filename}')
depfile.write('\n')
if __name__ == '__main__':
main() # pylint: disable=no-value-for-parameter