Secure Arguments and Environment Variables
We show how to pass arguments and environment variables in a secure fashion to an application with the help of CAS.
SCONE CAS manages the keys of an application. The keys are unter complete control of the application: only services given explicit control by the application get access to the keys.
Prerequisites
We assume that you already
- started a CAS instance on the local host, as well as
- started a LAS instance on the local host,
We also assume that this example is executed in the context of Ubuntu. For other Linux variants, you might need to use a different cross-compiler image. Alternatively, you could execute this example in the crosscompiler container but you need to ensure that the container can establish https connections to CAS and LAS.
Simple Example
We create a simple C program to print the arguments as well as the environment variables:
cat > print-arg-env.c <<EOF
#include <stdio.h>
extern char **__environ;
int main (int argc, char **argv) {
printf("argv:");
for (int i = 0; i < argc; i++) {
printf(" %s", argv[i]);
}
printf("\n");
char** envp = __environ;
printf("environ:\n");
while (*envp != NULL) {
printf("%s\n", *envp);
envp++;
}
return 42;
}
EOF
We can compile this natively as follows:
gcc print-arg-env.c -g -O3 -o print-arg-env
And we can now run this with some some arguments and some environment variables:
ENV2=World ENV1=! ./print-arg-env Hello
This results in an output similar to this:
argv: ./print-arg-env Hello
environ:
ENV2=World
ENV1=!
...
Let's cross-compile this program to run inside of enclaves as follows. We determine which SGX device to mount with function determine_sgx_device.
determine_sgx_device
docker run $MOUNT_SGXDEVICE -it -v `pwd`:/work registry.scontain.com:5050/sconecuratedimages/crosscompilers scone-gcc /work/print-arg-env.c -g -O3 -o /work/scone-print-arg-env
We can now determine MRENCLAVE
as follows:
export MRENCLAVE=`SCONE_HASH=1 ./scone-print-arg-env`
echo MRENCLAVE of scone-print-arg-env is $MRENCLAVE
We can now run the program inside of an enclave but not under the control of CAS as follows:
ENV2=World ENV1=! ./scone-print-arg-env Hello
This will result in the same output as before:
argv: ./print-arg-env Hello
environ:
ENV2=World
ENV1=!
...
Without CAS: No Confidentiality and Integrity of Arguments and Environment Variables
Note that neither the integrity nor the confidentiality of these arguments are protected. To protect these and to ensure that the program is indeed executed inside an enclave, we need to run the program in the context of CAS.**
Secure Arguments and Environment Variables
In the next step, we control the environment variables and the arguments with the help of CAS.
When does the SCONE runtime use CAS?
When environment variable SCONE_CONFIG_ID
is not set, the SCONE runtime will not contact CAS.
If it is set, we will contact SCONE_CAS_ADDR
. If SCONE_CAS_ADDR
is not set, we contact by default
host „cas“. The SCONE runtime will also contact SCONE_LAS_ADDR
for local attestation. If SCONE_LAS_ADDR
is not set, we contact by default host „las“.
We assume that you already started a CAS in the background via docker-compose up -d cas
on the local machine:
export SCONE_CAS_ADDR=127.0.0.1
Alternatively, you can use a our public CAS instance at domain scone-cas.cf
:
export SCONE_CAS_ADDR=scone-cas.cf
We also assume that you already started a LAS in the background via docker-compose up -d las
on the local machine:
export SCONE_LAS_ADDR=127.0.0.1
We can now create a new session on cas as follows:
cat > session.yml <<EOF
name: secure-arguments-example
digest: somedigest
services:
- name: scone-print-arg-env
mrenclaves: [$MRENCLAVE]
tags: [thisissometag1]
command: ./scone-print-arg-env arg1 arg2 arg3
environment:
SCONE_MODE: hw
env1: running
env2: in
env3: enclave
pwd: /
EOF
Let's make sure that we have a client certificate to identify this client:
mkdir -p conf
if [[ ! -f conf/client.crt || ! -f conf/client-key.key ]] ; then
openssl req -x509 -newkey rsa:4096 -out conf/client.crt -keyout conf/client-key.key \
-days 31 -nodes -sha256 \
-subj "/C=US/ST=Dresden/L=Saxony/O=Scontain/OU=Org/CN=www.scontain.com" \
-reqexts SAN -extensions SAN \
-config <(cat /etc/ssl/openssl.cnf <(printf '[SAN]\nsubjectAltName=DNS:www.scontain.com'))
fi
Next, we will upload this session to CAS:
curl -k -s --cert conf/client.crt --key conf/client-key.key --data-binary @session.yml -X POST https://$SCONE_CAS_ADDR:8081/session
This results in an output similar to this:
Created Session[id=ce81e4cd-eed4-4f12-9bfc-c93e3dd4b454, name=secure-arguments, status=Pending]c
Note that if you try to upload to a session that already exists, you will get an error code like this:
Could not create successor session. Invalid previous session digest: Some("5de101e4980f312527e1c308dfe6c7bc465660c0fea6b98983efa5baf94bf362") != None
In other words, if you want to update a session, you need to define a predecessor
key in the session that specifies the current session. This is to ensure that a client does not overwrite a just updated session, i.e., it permits to detect write/write conflicts.
Executing Print-Arg-Env
Let us now execute scone-print-arg-env
in the context of session secure-arguments-example
. To do so, we need
to pass in environment variable SCONE_CONFIG_ID
which contains the name of the session and we need to set
SCONE_CAS_ADDR
as well as SCONE_LAS_ADDR
as we have shown above.
SCONE_CONFIG_ID=secure-arguments-example/scone-print-arg-env ./scone-print-arg-env
This will print the following output:
argv: ./scone-print-arg-env arg1 arg2 arg3
environ:
SCONE_MODE=hw
env2=in
env1=running
env3=enclave
Note that the environment variables - except those expected by the SCONE runtime to locate LAS, CAS and the session - are ignored. This means even if we pass additional arguments and environment variables, the output does not change. The execution of
IRGNORED_ENV=1 SCONE_CONFIG_ID=secure-arguments-example/scone-print-arg-env ./scone-print-arg-env IGNORED1 IGNORED2
results in the same output:
argv: ./scone-print-arg-env arg1 arg2 arg3
environ:
SCONE_MODE=hw
env2=in
env1=running
env3=enclave
The SCONE variables provided by the environment are not protected in any way and we designed SCONE assuming that an attacker could modify these environment variables. This could lead to denial of service attacks but not to the exposure of any secrets.
Integrity of SCONE environment variables
An adversary could change SCONE_CONFIG_ID
, SCONE_CAS_ADDR
and SCONE_LAS_ADDR
but in this
case, the application does not start (attestation fails) up or it does not get access to the secrets and configuration
variables to do its job.