From e8e5e8de1d38c4944ce3842a49381ebb4c692709 Mon Sep 17 00:00:00 2001 From: Sankaranarayanan Venkatasubramanian Date: Fri, 9 Dec 2022 13:02:52 +0530 Subject: [PATCH 1/3] Enable `--template` option to use with sign-image (for use with HSMs, for example) Signed-off-by: Sankaranarayanan Venkatasubramanian --- .gitignore | 1 + gsc.py | 34 +++++++++++++------ .../centos/Dockerfile.sign.user.template | 3 ++ .../debian/Dockerfile.sign.user.template | 3 ++ .../ubuntu/Dockerfile.sign.user.template | 2 ++ 5 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 templates/centos/Dockerfile.sign.user.template create mode 100644 templates/debian/Dockerfile.sign.user.template create mode 100644 templates/ubuntu/Dockerfile.sign.user.template diff --git a/.gitignore b/.gitignore index fedcef2c..b100fc42 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ __pycache__ *.manifest.sgx *.sig *.token +/templates/Dockerfile.sign.user.template diff --git a/gsc.py b/gsc.py index cfcefc93..b0827a94 100755 --- a/gsc.py +++ b/gsc.py @@ -350,26 +350,36 @@ def gsc_sign_image(args): distro, _ = distro.split(':') env.loader = jinja2.FileSystemLoader('templates/') - sign_template = env.get_template(f'{distro}/Dockerfile.sign.template') + sign_template = [] + build_args = [] os.makedirs(tmp_build_path, exist_ok=True) + + # Use default steps if user has not provided a Dockerfile/template for signing + if args.template is None: + # copy user-provided signing key and signing Bash script to our tmp build dir (to copy them + # later inside Docker image) + tmp_build_key_path = tmp_build_path / 'gsc-signer-key.pem' + tmp_build_sign_path = tmp_build_path / 'sign.sh' + shutil.copyfile(os.path.abspath(args.key), tmp_build_key_path) + shutil.copy(os.path.abspath('sign.sh'), tmp_build_sign_path) + sign_template = env.get_template(f'{distro}/Dockerfile.sign.template') + build_args = {"passphrase": args.passphrase} + else: + shutil.copy(args.template, 'templates/Dockerfile.sign.user.template') + sign_template = env.get_template(f'{distro}/Dockerfile.sign.user.template') + with open(tmp_build_path / 'Dockerfile.sign', 'w') as dockerfile: dockerfile.write(sign_template.render(image=unsigned_image_name)) - # copy user-provided signing key and signing Bash script to our tmp build dir (to copy them - # later inside Docker image) - tmp_build_key_path = tmp_build_path / 'gsc-signer-key.pem' - tmp_build_sign_path = tmp_build_path / 'sign.sh' - shutil.copyfile(os.path.abspath(args.key), tmp_build_key_path) - shutil.copy(os.path.abspath('sign.sh'), tmp_build_sign_path) - try: # `forcerm` parameter forces removal of intermediate Docker images even after unsuccessful # builds, to not leave the signing key lingering in any Docker containers build_docker_image(docker_socket.api, tmp_build_path, signed_image_name, 'Dockerfile.sign', - forcerm=True, buildargs={"passphrase": args.passphrase}) + forcerm=True, buildargs=build_args) finally: - os.remove(tmp_build_key_path) + if args.template is None: + os.remove(tmp_build_key_path) if get_docker_image(docker_socket, signed_image_name) is None: print(f'Failed to build a signed graminized Docker image `{signed_image_name}`.') @@ -501,7 +511,9 @@ def gsc_info_image(args): sub_sign.add_argument('-c', '--config_file', type=argparse.FileType('r', encoding='UTF-8'), default='config.yaml', help='Specify configuration file.') sub_sign.add_argument('image', help='Name of the application (base) Docker image.') -sub_sign.add_argument('key', help='Key to sign the Intel SGX enclaves inside the Docker image.') +sub_sign.add_argument('-k', '--key', help='Key to sign the Intel SGX enclaves inside the Docker image.') +sub_sign.add_argument('-t', '--template', + help='Custom Dockerfile/template to use for signing, say, with a HSM.') sub_sign.add_argument('-p', '--passphrase', help='Passphrase for the signing key.') sub_info = subcommands.add_parser('info-image', help='Retrieve information about a graminized ' diff --git a/templates/centos/Dockerfile.sign.user.template b/templates/centos/Dockerfile.sign.user.template new file mode 100644 index 00000000..9bff29bc --- /dev/null +++ b/templates/centos/Dockerfile.sign.user.template @@ -0,0 +1,3 @@ +{% extends "Dockerfile.sign.user.template" %} + +{% block path %}export PYTHONPATH="${PYTHONPATH}:$(find /gramine/meson_build_output/lib64 -type d -path '*/site-packages')" &&{% endblock %} diff --git a/templates/debian/Dockerfile.sign.user.template b/templates/debian/Dockerfile.sign.user.template new file mode 100644 index 00000000..a80809e3 --- /dev/null +++ b/templates/debian/Dockerfile.sign.user.template @@ -0,0 +1,3 @@ +{% extends "Dockerfile.sign.user.template" %} + +{% block path %}export PYTHONPATH="${PYTHONPATH}:$(find /gramine/meson_build_output/lib -type d -path '*/site-packages')" &&{% endblock %} diff --git a/templates/ubuntu/Dockerfile.sign.user.template b/templates/ubuntu/Dockerfile.sign.user.template new file mode 100644 index 00000000..34ca5804 --- /dev/null +++ b/templates/ubuntu/Dockerfile.sign.user.template @@ -0,0 +1,2 @@ +{% extends "debian/Dockerfile.sign.user.template" %} + From 59faf7b0b54e352f444bf2dfb93b611588b799de Mon Sep 17 00:00:00 2001 From: Sankaranarayanan Venkatasubramanian Date: Wed, 4 Jan 2023 16:36:14 +0530 Subject: [PATCH 2/3] fixup! Enable `--template` option to use with sign-image (for use with HSMs, for example) --- .gitignore | 1 - Documentation/index.rst | 21 +++++++++++++-------- gsc.py | 16 +++++++++------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index b100fc42..fedcef2c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,3 @@ __pycache__ *.manifest.sgx *.sig *.token -/templates/Dockerfile.sign.user.template diff --git a/Documentation/index.rst b/Documentation/index.rst index 3c740bf1..f91a27e5 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -139,23 +139,27 @@ Docker image called ``gsc-``. :command:`gsc sign-image` always removes intermediate Docker images, if successful or not, to ensure the removal of the signing key in them. -:command:`gsc sign-image` [*OPTIONS*] <*IMAGE-NAME*> <*KEY-FILE*> +:command:`gsc sign-image` [*OPTIONS*] <*IMAGE-NAME*> .. option:: -c Specify configuration file. Default: :file:`config.yaml` +.. option:: -k KEY-FILE + + Provide key to sign the Intel SGX enclave. + .. option:: -p Provide passphrase for the enclave signing key (if applicable) -.. option:: IMAGE-NAME +.. option:: -t - Name of the application Docker image + Provide Dockerfile to use for signing the enclave (e.g., with an HSM) -.. option:: KEY-FILE +.. option:: IMAGE-NAME - Used to sign the Intel SGX enclave + Name of the application Docker image .. program:: gsc-build-gramine @@ -275,9 +279,10 @@ follows three main stages and produces an image named ``gsc-``. tool to generate SIGSTRUCT files for SGX enclave initialization. This tool also generates an SGX-specific manifest file. The required signing key is provided by the user via the :command:`gsc sign-image` command and copied - into this Docker build stage. The generated image is called - ``gsc-`` and includes all necessary files to start an Intel SGX - enclave. + into this Docker build stage. The users can also supply their own Dockerfile + templates using `--template` option of this command to sign (e.g. with HSM). + The generated image is called ``gsc-`` and includes all necessary + files to start an Intel SGX enclave. In the future we plan to provide prebuilt Gramine images for popular cloud-provider offerings. diff --git a/gsc.py b/gsc.py index b0827a94..e8abd917 100755 --- a/gsc.py +++ b/gsc.py @@ -349,9 +349,8 @@ def gsc_sign_image(args): distro = env.globals['Distro'] distro, _ = distro.split(':') - env.loader = jinja2.FileSystemLoader('templates/') - sign_template = [] - build_args = [] + sign_template = None + build_args = {} os.makedirs(tmp_build_path, exist_ok=True) @@ -363,11 +362,13 @@ def gsc_sign_image(args): tmp_build_sign_path = tmp_build_path / 'sign.sh' shutil.copyfile(os.path.abspath(args.key), tmp_build_key_path) shutil.copy(os.path.abspath('sign.sh'), tmp_build_sign_path) + env.loader = jinja2.FileSystemLoader('templates/') sign_template = env.get_template(f'{distro}/Dockerfile.sign.template') build_args = {"passphrase": args.passphrase} else: - shutil.copy(args.template, 'templates/Dockerfile.sign.user.template') - sign_template = env.get_template(f'{distro}/Dockerfile.sign.user.template') + extract_user_from_image_config(unsigned_image.attrs['Config'], env) + env.loader = jinja2.FileSystemLoader(os.path.dirname(args.template)) + sign_template = env.get_template(os.path.basename(args.template)) with open(tmp_build_path / 'Dockerfile.sign', 'w') as dockerfile: dockerfile.write(sign_template.render(image=unsigned_image_name)) @@ -511,9 +512,10 @@ def gsc_info_image(args): sub_sign.add_argument('-c', '--config_file', type=argparse.FileType('r', encoding='UTF-8'), default='config.yaml', help='Specify configuration file.') sub_sign.add_argument('image', help='Name of the application (base) Docker image.') -sub_sign.add_argument('-k', '--key', help='Key to sign the Intel SGX enclaves inside the Docker image.') +sub_sign.add_argument('-k', '--key', + help='Key to sign the Intel SGX enclaves inside the Docker image.') sub_sign.add_argument('-t', '--template', - help='Custom Dockerfile/template to use for signing, say, with a HSM.') + help='Custom Dockerfile/template to use for signing, say, with an HSM.') sub_sign.add_argument('-p', '--passphrase', help='Passphrase for the signing key.') sub_info = subcommands.add_parser('info-image', help='Retrieve information about a graminized ' From 5c830ffc079d3e0ea3eacb1c652b5b60babc598b Mon Sep 17 00:00:00 2001 From: Sankaranarayanan Venkatasubramanian Date: Wed, 4 Jan 2023 16:51:01 +0530 Subject: [PATCH 3/3] fixup! Enable `--template` option to use with sign-image (for use with HSMs, for example) --- templates/centos/Dockerfile.sign.user.template | 3 --- templates/debian/Dockerfile.sign.user.template | 3 --- templates/ubuntu/Dockerfile.sign.user.template | 2 -- 3 files changed, 8 deletions(-) delete mode 100644 templates/centos/Dockerfile.sign.user.template delete mode 100644 templates/debian/Dockerfile.sign.user.template delete mode 100644 templates/ubuntu/Dockerfile.sign.user.template diff --git a/templates/centos/Dockerfile.sign.user.template b/templates/centos/Dockerfile.sign.user.template deleted file mode 100644 index 9bff29bc..00000000 --- a/templates/centos/Dockerfile.sign.user.template +++ /dev/null @@ -1,3 +0,0 @@ -{% extends "Dockerfile.sign.user.template" %} - -{% block path %}export PYTHONPATH="${PYTHONPATH}:$(find /gramine/meson_build_output/lib64 -type d -path '*/site-packages')" &&{% endblock %} diff --git a/templates/debian/Dockerfile.sign.user.template b/templates/debian/Dockerfile.sign.user.template deleted file mode 100644 index a80809e3..00000000 --- a/templates/debian/Dockerfile.sign.user.template +++ /dev/null @@ -1,3 +0,0 @@ -{% extends "Dockerfile.sign.user.template" %} - -{% block path %}export PYTHONPATH="${PYTHONPATH}:$(find /gramine/meson_build_output/lib -type d -path '*/site-packages')" &&{% endblock %} diff --git a/templates/ubuntu/Dockerfile.sign.user.template b/templates/ubuntu/Dockerfile.sign.user.template deleted file mode 100644 index 34ca5804..00000000 --- a/templates/ubuntu/Dockerfile.sign.user.template +++ /dev/null @@ -1,2 +0,0 @@ -{% extends "debian/Dockerfile.sign.user.template" %} -