Skip to content
This repository was archived by the owner on Sep 19, 2024. It is now read-only.

retrieve signed x509 cert from agent #59

Merged
merged 7 commits into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ wasm-objs := third-party/wasm3/source/m3_api_libc.o \
proxywasm.o \
socket.o \
task_context.o \
commands.o
commands.o \
string.o

# Set the path to the Kernel build utils.
KBUILD=/lib/modules/$(shell uname -r)/build/
Expand Down
81 changes: 79 additions & 2 deletions commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

#include "commands.h"
#include "json.h"
#include "base64.h"
#include "string.h"

// create a function to add a command to the list (called from the VM), locked with a spinlock
command_answer *send_command(char *name, char *data, task_context *context)
Expand All @@ -31,7 +33,7 @@ command_answer *send_command(char *name, char *data, task_context *context)
DEFINE_WAIT(wait);

// wait until the command is processed
printk("wasm: waiting for command to be processed");
printk("wasm: waiting for command [%s] to be processed", name);

// wait for the command to be processed
prepare_to_wait(&cmd->wait_queue, &wait, TASK_INTERRUPTIBLE);
Expand All @@ -43,7 +45,7 @@ command_answer *send_command(char *name, char *data, task_context *context)

if (cmd->answer == NULL)
{
printk(KERN_ERR "wasm: command answer timeout");
printk(KERN_ERR "wasm: command [%s] answer timeout", name);

cmd->answer = kmalloc(sizeof(struct command_answer), GFP_KERNEL);
cmd->answer->error = kmalloc(strlen("timeout") + 1, GFP_KERNEL);
Expand Down Expand Up @@ -88,6 +90,81 @@ command_answer *send_connect_command(u16 port)
return answer;
}

csr_sign_answer *send_csrsign_command(unsigned char *csr)
{
JSON_Value *root_value = json_value_init_object();
JSON_Object *root_object = json_value_get_object(root_value);

json_object_set_string(root_object, "csr", csr);

command_answer *answer = send_command("csr_sign", json_serialize_to_string(root_value), get_task_context());

csr_sign_answer *csr_sign_answer = kmalloc(sizeof(struct csr_sign_answer), GFP_KERNEL);

if (answer->error)
{
csr_sign_answer->error = strdup(answer->error);
}

if (answer->answer)
{
JSON_Value *json = NULL;
json = json_parse_string(answer->answer);
JSON_Object *root = json_value_get_object(json);

JSON_Array *trust_anchors = json_object_get_array(root, "trust_anchors");
csr_sign_answer->trust_anchors_len = json_array_get_count(trust_anchors);
csr_sign_answer->trust_anchors = kmalloc(csr_sign_answer->trust_anchors_len * sizeof *csr_sign_answer->trust_anchors, GFP_KERNEL);

size_t destlen;
size_t srclen;

size_t u;
for (u = 0; u < csr_sign_answer->trust_anchors_len; u++)
{
JSON_Object *ta = json_array_get_object(trust_anchors, u);

csr_sign_answer->trust_anchors[u].flags = BR_X509_TA_CA;
csr_sign_answer->trust_anchors[u].pkey.key_type = BR_KEYTYPE_RSA;

// RAW (DN)
char *raw_subject = json_object_get_string(ta, "rawSubject");
srclen = strlen(raw_subject);
csr_sign_answer->trust_anchors[u].dn.data = kmalloc(srclen, GFP_KERNEL);
csr_sign_answer->trust_anchors[u].dn.len = base64_decode(csr_sign_answer->trust_anchors[u].dn.data, srclen, raw_subject, srclen);

// RSA_N
char *rsa_n = json_object_dotget_string(ta, "publicKey.RSA_N");
srclen = strlen(rsa_n);
csr_sign_answer->trust_anchors[u].pkey.key.rsa.n = kmalloc(srclen, GFP_KERNEL);
csr_sign_answer->trust_anchors[u].pkey.key.rsa.nlen = base64_decode(csr_sign_answer->trust_anchors[u].pkey.key.rsa.n, srclen, rsa_n, srclen);

// RSA_E
char *rsa_e = json_object_dotget_string(ta, "publicKey.RSA_E");
srclen = strlen(rsa_e);
csr_sign_answer->trust_anchors[u].pkey.key.rsa.e = kmalloc(srclen, GFP_KERNEL);
csr_sign_answer->trust_anchors[u].pkey.key.rsa.elen = base64_decode(csr_sign_answer->trust_anchors[u].pkey.key.rsa.e, srclen, rsa_e, srclen);
}

csr_sign_answer->chain = kmalloc(1 * sizeof *csr_sign_answer->chain, GFP_KERNEL);
csr_sign_answer->chain_len = 1;

char *raw = json_object_dotget_string(root, "certificate.raw");
srclen = strlen(raw);
csr_sign_answer->chain[0].data = kmalloc(srclen, GFP_KERNEL);
csr_sign_answer->chain[0].data_len = base64_decode(csr_sign_answer->chain[0].data, srclen, raw, srclen);

if (json)
{
json_value_free(json);
}
}

free_command_answer(answer);

return csr_sign_answer;
}

struct command *lookup_in_flight_command(char *id)
{
spin_lock_irqsave(&command_list_lock, command_list_lock_flags);
Expand Down
11 changes: 11 additions & 0 deletions commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#define commands_h

#include "task_context.h"
#include "bearssl.h"

#define COMMAND_TIMEOUT_SECONDS 1

Expand All @@ -21,12 +22,22 @@ typedef struct command_answer
char *answer;
} command_answer;

typedef struct csr_sign_answer
{
char *error;
br_x509_certificate *chain;
size_t chain_len;
br_x509_trust_anchor *trust_anchors;
size_t trust_anchors_len;
} csr_sign_answer;

void free_command_answer(command_answer *cmd_answer);

command_answer *send_command(char *name, char *data, task_context *context);

command_answer *send_accept_command(u16 port);
command_answer *send_connect_command(u16 port);
csr_sign_answer *send_csrsign_command(unsigned char *csr);

// create a linked list for outgoing commands
typedef struct command
Expand Down
57 changes: 29 additions & 28 deletions csr.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,23 +90,23 @@ static i32 alloc_and_copy_parameter(char *str, i32 str_length, csr_module *csr)
goto bail;
}
addr = malloc_result.data->i32;
strcpy(wasm_vm_memory(get_csr_module(csr)) + addr, str);
bail:
return addr;
strncpy(wasm_vm_memory(get_csr_module(csr)) + addr, str, str_length);
bail:
return addr;
}

wasm_vm_result csr_gen(csr_module *csr, i32 priv_key_buff_ptr, i32 priv_key_buff_len, csr_parameters *parameters)
{
wasm_vm_result result;

#define ALLOCATE_AND_CHECK(field) \
i32 field##_len = strlen(parameters->field) + 1; \
i32 field##_ptr; \
field##_ptr = alloc_and_copy_parameter(parameters->field, field##_len, csr); \
if (field##_ptr == -1 ) \
{ \
#define ALLOCATE_AND_CHECK(field) \
i32 field##_len = strlen(parameters->field); \
i32 field##_ptr; \
field##_ptr = alloc_and_copy_parameter(parameters->field, field##_len, csr); \
if (field##_ptr == -1) \
{ \
result.err = "wasm: error during allocating ptr with length for " #field; \
goto bail; \
goto bail; \
}

ALLOCATE_AND_CHECK(subject);
Expand All @@ -115,29 +115,30 @@ wasm_vm_result csr_gen(csr_module *csr, i32 priv_key_buff_ptr, i32 priv_key_buff
ALLOCATE_AND_CHECK(email);
ALLOCATE_AND_CHECK(ip);

result = wasm_vm_call_direct(csr->vm, csr->generate_csr,
priv_key_buff_ptr, priv_key_buff_len,
subject_ptr, subject_len,
dns_ptr, dns_len,
uri_ptr, uri_len,
email_ptr, email_len,
ip_ptr, ip_len);
result = wasm_vm_call_direct(csr->vm, csr->generate_csr,
priv_key_buff_ptr, priv_key_buff_len,
subject_ptr, subject_len,
dns_ptr, dns_len,
uri_ptr, uri_len,
email_ptr, email_len,
ip_ptr, ip_len);
if (result.err != NULL)
{
pr_err("wasm: calling csr_gen errored %s\n", result.err);
goto bail;
}
printk("wasm: result of calling csr_gen %d\n", result.data->i64);
bail:
i32 pointers[] = {subject_ptr, dns_ptr, uri_ptr, email_ptr, ip_ptr};

int i;
for(i = 0; i < (sizeof(pointers) / sizeof(pointers[0])); i++) {
wasm_vm_result free_result = csr_free(csr, subject_ptr);
if (free_result.err)
{
result = free_result;
}
bail:
i32 pointers[] = {subject_ptr, dns_ptr, uri_ptr, email_ptr, ip_ptr};

int i;
for (i = 0; i < (sizeof(pointers) / sizeof(pointers[0])); i++)
{
wasm_vm_result free_result = csr_free(csr, pointers[i]);
if (free_result.err)
{
result = free_result;
}
return result;
}
return result;
}
2 changes: 1 addition & 1 deletion device_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ static ssize_t device_read(struct file *file, /* see include/linux/fs.h */
// wait until command is available
while (c == NULL)
{
if (msleep_interruptible(1000) > 0)
if (msleep_interruptible(25) > 0)
{
return -EINTR;
}
Expand Down
11 changes: 6 additions & 5 deletions rsa_tools.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,27 @@ uint32_t generate_rsa_keys(br_rsa_private_key *rsa_priv, br_rsa_public_key *rsa_
{
br_rsa_keygen rsa_keygen = br_rsa_keygen_get_default();

unsigned char *raw_priv_key = kmalloc(BR_RSA_KBUF_PRIV_SIZE(RSA_BIT_LENGHT), GFP_KERNEL);
unsigned char *raw_pub_key = kmalloc(BR_RSA_KBUF_PUB_SIZE(RSA_BIT_LENGHT), GFP_KERNEL);
unsigned char *raw_priv_key = kmalloc(BR_RSA_KBUF_PRIV_SIZE(RSA_BIT_LENGHT), GFP_KERNEL);
unsigned char *raw_pub_key = kmalloc(BR_RSA_KBUF_PUB_SIZE(RSA_BIT_LENGHT), GFP_KERNEL);

return rsa_keygen(&hmac_drbg_ctx.vtable, rsa_priv, raw_priv_key, rsa_pub, raw_pub_key, RSA_BIT_LENGHT, RSA_PUB_EXP);
}

// BearSSL RSA Keygen related functions
// Encodes rsa private key to pkcs8 der format and returns it's lenght.
// If the der parameter is set to NULL then it computes only the length
size_t encode_rsa_priv_key_to_der(unsigned char *der, br_rsa_private_key *rsa_priv, br_rsa_public_key *rsa_pub)
int encode_rsa_priv_key_to_der(unsigned char *der, br_rsa_private_key *rsa_priv, br_rsa_public_key *rsa_pub)
{
br_rsa_compute_privexp rsa_priv_exp_comp = br_rsa_compute_privexp_get_default();
size_t priv_exponent_size = rsa_priv_exp_comp(NULL, rsa_priv, RSA_PUB_EXP);
if (priv_exponent_size == 0)
{
pr_err("rsa_tools:error happened during priv_exponent lenght calculation");
pr_err("rsa_tools: error happened during priv_exponent lenght calculation");
return -1;
}
unsigned char priv_exponent[priv_exponent_size];
if (rsa_priv_exp_comp(priv_exponent, rsa_priv, RSA_PUB_EXP) != priv_exponent_size)
size_t pexp = rsa_priv_exp_comp(priv_exponent, rsa_priv, RSA_PUB_EXP);
if (pexp != priv_exponent_size)
{
pr_err("rsa_tools: error happened during priv_exponent generation");
return -1;
Expand Down
2 changes: 1 addition & 1 deletion rsa_tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@

int init_rnd_gen(void);
uint32_t generate_rsa_keys(br_rsa_private_key *rsa_priv, br_rsa_public_key *rsa_pub);
size_t encode_rsa_priv_key_to_der(unsigned char *der, br_rsa_private_key *rsa_priv, br_rsa_public_key *rsa_pub);
int encode_rsa_priv_key_to_der(unsigned char *der, br_rsa_private_key *rsa_priv, br_rsa_public_key *rsa_pub);
Loading