-
Notifications
You must be signed in to change notification settings - Fork 91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generate TLS credentials for user space #749
base: oe_port
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,247 @@ | ||
#include "enclave/enclave_cert.h" | ||
#include <mbedtls/x509.h> | ||
#include <mbedtls/x509_crt.h> | ||
#include <openenclave/enclave.h> | ||
#include <openenclave/attestation/attester.h> | ||
#include <openenclave/attestation/sgx/eeid_plugin.h> | ||
#include "openenclave/corelibc/oemalloc.h" | ||
#include "openenclave/corelibc/oestring.h" | ||
|
||
oe_result_t oe_sgx_eeid_attester_initialize(void); | ||
|
||
static oe_result_t _generate_key_pair( | ||
uint8_t** public_key_out, | ||
size_t* public_key_size_out, | ||
uint8_t** private_key_out, | ||
size_t* private_key_size_out) | ||
{ | ||
oe_result_t result = OE_FAILURE; | ||
oe_result_t ret; | ||
oe_asymmetric_key_params_t params; | ||
char user_data[] = "__USER_DATA__"; | ||
size_t user_data_size = sizeof(user_data) - 1; | ||
uint8_t* public_key = NULL; | ||
size_t public_key_size = 0; | ||
uint8_t* private_key = NULL; | ||
size_t private_key_size = 0; | ||
|
||
*public_key_out = NULL; | ||
*public_key_size_out = 0; | ||
*private_key_out = NULL; | ||
*private_key_size_out = 0; | ||
|
||
memset(¶ms, 0, sizeof(params)); | ||
params.type = OE_ASYMMETRIC_KEY_EC_SECP256P1; | ||
params.format = OE_ASYMMETRIC_KEY_PEM; | ||
params.user_data = user_data; | ||
params.user_data_size = user_data_size; | ||
|
||
if ((ret = oe_get_public_key_by_policy( | ||
OE_SEAL_POLICY_UNIQUE, | ||
¶ms, | ||
&public_key, | ||
&public_key_size, | ||
NULL, | ||
NULL)) != OE_OK) | ||
{ | ||
result = ret; | ||
goto done; | ||
} | ||
|
||
if ((ret = oe_get_private_key_by_policy( | ||
OE_SEAL_POLICY_UNIQUE, | ||
¶ms, | ||
&private_key, | ||
&private_key_size, | ||
NULL, | ||
NULL)) != OE_OK) | ||
{ | ||
result = ret; | ||
goto done; | ||
} | ||
|
||
*private_key_out = private_key; | ||
*private_key_size_out = private_key_size; | ||
private_key = NULL; | ||
|
||
*public_key_out = public_key; | ||
*public_key_size_out = public_key_size; | ||
public_key = NULL; | ||
|
||
result = OE_OK; | ||
|
||
done: | ||
|
||
if (private_key) | ||
oe_free(private_key); | ||
|
||
if (public_key) | ||
oe_free(public_key); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same |
||
|
||
return result; | ||
} | ||
|
||
static oe_result_t _generate_cert_and_private_key( | ||
const char* common_name, | ||
uint8_t** cert_out, | ||
size_t* cert_size_out, | ||
uint8_t** private_key_out, | ||
size_t* private_key_size_out) | ||
{ | ||
oe_result_t result = OE_FAILURE; | ||
oe_result_t ret; | ||
uint8_t* cert = NULL; | ||
size_t cert_size; | ||
uint8_t* private_key = NULL; | ||
size_t private_key_size; | ||
uint8_t* public_key = NULL; | ||
size_t public_key_size; | ||
const oe_uuid_t format = {OE_FORMAT_UUID_SGX_EEID_ECDSA_P256}; | ||
|
||
*cert_out = NULL; | ||
*cert_size_out = 0; | ||
*private_key_out = NULL; | ||
*private_key_size_out = 0; | ||
|
||
if ((ret = _generate_key_pair( | ||
&public_key, &public_key_size, &private_key, &private_key_size)) != | ||
OE_OK) | ||
{ | ||
result = ret; | ||
goto done; | ||
} | ||
|
||
// Initialize built-in OE attesters and the eeid attester. | ||
oe_attester_initialize(); | ||
oe_sgx_eeid_attester_initialize(); | ||
|
||
if ((ret = oe_get_attestation_certificate_with_evidence( | ||
&format, | ||
(unsigned char*)common_name, | ||
private_key, | ||
private_key_size, | ||
public_key, | ||
public_key_size, | ||
&cert, | ||
&cert_size)) != OE_OK) | ||
{ | ||
result = ret; | ||
goto done; | ||
} | ||
|
||
*private_key_out = private_key; | ||
*private_key_size_out = private_key_size; | ||
private_key = NULL; | ||
|
||
*cert_out = cert; | ||
*cert_size_out = cert_size; | ||
cert = NULL; | ||
|
||
result = OE_OK; | ||
|
||
done: | ||
|
||
if (private_key) | ||
oe_free_key(private_key, private_key_size, NULL, 0); | ||
|
||
if (public_key) | ||
oe_free_key(public_key, public_key_size, NULL, 0); | ||
|
||
if (cert) | ||
oe_free_attestation_certificate(cert); | ||
|
||
return result; | ||
} | ||
|
||
int enclave_generate_tls_credentials( | ||
uint8_t** cert_out, | ||
size_t* cert_size_out, | ||
uint8_t** private_key_out, | ||
size_t* private_key_size_out) | ||
{ | ||
int ret = -1; | ||
uint8_t* cert = NULL; | ||
size_t cert_size; | ||
uint8_t* private_key = NULL; | ||
size_t private_key_size; | ||
const char* common_name = "CN=Open Enclave SDK,O=OESDK TLS,C=US"; | ||
|
||
if (cert_out) | ||
*cert_out = NULL; | ||
|
||
if (cert_size_out) | ||
*cert_size_out = 0; | ||
|
||
if (private_key_out) | ||
*private_key_out = NULL; | ||
|
||
if (private_key_size_out) | ||
*private_key_size_out = 0; | ||
|
||
if (!cert_out || !cert_size_out || !private_key_out || | ||
!private_key_size_out) | ||
{ | ||
goto done; | ||
} | ||
|
||
/* Generate the attested certificate and private key */ | ||
if (_generate_cert_and_private_key( | ||
common_name, &cert, &cert_size, &private_key, &private_key_size) != | ||
OE_OK) | ||
{ | ||
goto done; | ||
} | ||
|
||
#if DEBUG | ||
/* Verify that the certificate can be parsed as DER */ | ||
{ | ||
mbedtls_x509_crt crt; | ||
mbedtls_x509_crt_init(&crt); | ||
|
||
if (mbedtls_x509_crt_parse_der(&crt, cert, cert_size) != 0) | ||
{ | ||
mbedtls_x509_crt_free(&crt); | ||
goto done; | ||
} | ||
|
||
mbedtls_x509_crt_free(&crt); | ||
} | ||
|
||
/* Verify that the private key can be parsed as PEM */ | ||
{ | ||
mbedtls_pk_context pk; | ||
mbedtls_pk_init(&pk); | ||
|
||
if (mbedtls_pk_parse_key(&pk, private_key, private_key_size, NULL, 0) != | ||
0) | ||
{ | ||
mbedtls_pk_free(&pk); | ||
goto done; | ||
} | ||
|
||
mbedtls_pk_free(&pk); | ||
} | ||
#endif | ||
|
||
*cert_out = cert; | ||
cert = NULL; | ||
*cert_size_out = cert_size; | ||
*private_key_out = private_key; | ||
private_key = NULL; | ||
*private_key_size_out = private_key_size; | ||
|
||
ret = 0; | ||
|
||
done: | ||
|
||
if (cert) | ||
oe_free_key(cert, cert_size, NULL, 0); | ||
|
||
if (private_key) | ||
oe_free_key(private_key, private_key_size, NULL, 0); | ||
|
||
if (cert) | ||
oe_free_attestation_certificate(cert); | ||
|
||
return ret; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#include "enclave/enclave_cert_user.h" | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
// This function and its caller should be moved to | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's no need to wait, we can do this now, can't we? |
||
// user space once we have a clean separation. | ||
int sgxlkl_write_tls_credentials( | ||
uint8_t* cert, | ||
size_t cert_size, | ||
uint8_t* private_key, | ||
size_t private_key_size, | ||
const char* cert_path, | ||
const char* pkey_path) | ||
{ | ||
int ret = -1; | ||
|
||
FILE* os1 = NULL; | ||
FILE* os2 = NULL; | ||
|
||
if (!(os1 = fopen(cert_path, "wb"))) | ||
goto done; | ||
|
||
if (!(os2 = fopen(pkey_path, "wb"))) | ||
goto done; | ||
|
||
if (fwrite(cert, 1, cert_size, os1) != cert_size) | ||
goto done; | ||
|
||
if (fwrite(private_key, 1, private_key_size, os2) != private_key_size) | ||
goto done; | ||
|
||
ret = 0; | ||
|
||
done: | ||
if (os1) | ||
fclose(os1); | ||
|
||
if (os2) | ||
fclose(os2); | ||
|
||
return ret; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,8 @@ | |
#include "openenclave/corelibc/oemalloc.h" | ||
#include "openenclave/corelibc/oestring.h" | ||
|
||
#include "enclave/enclave_cert.h" | ||
#include "enclave/enclave_cert_user.h" | ||
#include "enclave/enclave_mem.h" | ||
#include "enclave/enclave_oe.h" | ||
#include "enclave/enclave_util.h" | ||
|
@@ -13,6 +15,9 @@ | |
#include "enclave/wireguard_util.h" | ||
#include "shared/env.h" | ||
|
||
#define SGXLKL_TLS_CERT_PATH "/run/sgxlkl_cert.der" | ||
#define SGXLKL_TLS_PRIVATE_KEY_PATH "/run/sgxlkl_private_key.pem" | ||
|
||
extern struct mpmcq __scheduler_queue; | ||
|
||
_Noreturn void __dls3(elf64_stack_t* conf, void* tos); | ||
|
@@ -90,6 +95,11 @@ static void init_wireguard() | |
|
||
static int startmain(void* args) | ||
{ | ||
uint8_t* cert; | ||
size_t cert_size; | ||
uint8_t* private_key; | ||
size_t private_key_size; | ||
|
||
__libc_start_init(); | ||
a_barrier(); | ||
|
||
|
@@ -107,6 +117,26 @@ static int startmain(void* args) | |
init_wireguard(); | ||
find_and_mount_disks(); | ||
|
||
/* Generate TLS certificate and private key and save them to files. | ||
* Once we have kernel/user separation, pass the cert and private | ||
* key to user space through the stack, and move | ||
* sgxlkl_write_tls_credentials to user space. | ||
*/ | ||
|
||
if (!sgxlkl_in_sw_debug_mode()) | ||
{ | ||
enclave_generate_tls_credentials( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there's a layering problem here; we cant call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, this routine is a part of the nominal userspace and will be refactored soon to make that distinction more explicit. We may not call OE APIs from here. More generally, given that we've had so many meetings discussing the design and the mechanism for passing this via the ELF aux vector, I'd like to understand why a different approach is being pursued here. |
||
&cert, &cert_size, &private_key, &private_key_size); | ||
|
||
sgxlkl_write_tls_credentials( | ||
cert, | ||
cert_size, | ||
private_key, | ||
private_key_size, | ||
SGXLKL_TLS_CERT_PATH, | ||
SGXLKL_TLS_PRIVATE_KEY_PATH); | ||
} | ||
|
||
/* Launch stage 3 dynamic linker, passing in top of stack to overwrite. | ||
* The dynamic linker will then load the application proper; here goes! */ | ||
__dls3(&sgxlkl_enclave_state.elf64_stack, __builtin_frame_address(0)); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#ifndef _ENCLAVE_CERT_H | ||
#define _ENCLAVE_CERT_H | ||
|
||
#include <stddef.h> | ||
#include <stdint.h> | ||
|
||
int enclave_generate_tls_credentials( | ||
uint8_t** cert_out, | ||
size_t* cert_size_out, | ||
uint8_t** private_key_out, | ||
size_t* private_key_size_out); | ||
|
||
#endif /* _ENCLAVE_CERT_H */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#ifndef _ENCLAVE_CERT_USER_H | ||
#define _ENCLAVE_CERT_USER_H | ||
|
||
#include <stddef.h> | ||
#include <stdint.h> | ||
|
||
int sgxlkl_write_tls_credentials( | ||
uint8_t* cert, | ||
size_t cert_size, | ||
uint8_t* private_key, | ||
size_t private_key_size, | ||
const char* cert_path, | ||
const char* pkey_path); | ||
|
||
#endif /* _ENCLAVE_CERT_USER_H */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should use oe_free_key instead