diff options
author | Franklin Wei <me@fwei.tk> | 2018-06-15 17:56:29 -0400 |
---|---|---|
committer | Franklin Wei <me@fwei.tk> | 2018-06-15 17:56:29 -0400 |
commit | 30a65725a518dfeebe2f4e16f914fc2c712188fa (patch) | |
tree | 0645e962b97916d6ef3ab130b09ca4196fa242b5 /service_provider.c | |
parent | a0df949870f5c18b6af29bbfe70276fc6b1596dc (diff) | |
download | csaa-30a65725a518dfeebe2f4e16f914fc2c712188fa.zip csaa-30a65725a518dfeebe2f4e16f914fc2c712188fa.tar.gz csaa-30a65725a518dfeebe2f4e16f914fc2c712188fa.tar.bz2 csaa-30a65725a518dfeebe2f4e16f914fc2c712188fa.tar.xz |
Further refactoring and clean-up; more work on service provider
Diffstat (limited to 'service_provider.c')
-rw-r--r-- | service_provider.c | 179 |
1 files changed, 125 insertions, 54 deletions
diff --git a/service_provider.c b/service_provider.c index f211309..32d4fe2 100644 --- a/service_provider.c +++ b/service_provider.c @@ -9,8 +9,11 @@ #include "crypto.h" #include "helper.h" #include "service_provider.h" +#include "test.h" #include "trusted_module.h" +#define ACL_LOGLEAVES 4 + struct file_version { hash_t kf; /* HMAC(key, file_idx) */ hash_t l; /* HMAC(h(encrypted contents), kf) */ @@ -28,8 +31,7 @@ struct file_record { uint64_t version; uint64_t counter; - struct iomt_node *acl_leaves; - int acl_nleaves; + struct iomt *acl; struct tm_cert fr_cert; /* issued by module */ hash_t fr_hmac; @@ -113,9 +115,6 @@ struct tm_cert cert_eq(struct service_provider *sp, return tm_cert_equiv(sp->tm, &nu1, nu1_hmac, &nu2, nu2_hmac, encloser, placeholder_nodeidx, hmac_out); } -/* in trusted_module.c */ -void check(int condition); - /* leaf count will be 2^logleaves */ struct service_provider *sp_new(const void *key, size_t keylen, int logleaves) { @@ -177,7 +176,6 @@ static struct file_record *lookup_record(struct service_provider *sp, int idx) /* Should we insert sorted (for O(logn) lookup), or just at the end to * avoid copying (O(n) lookup, O(1) insertion)? Probably better to use a hash * table. */ - /* We do not check to ensure that there are no duplicate file indices; * this is up to the caller */ static void append_record(struct service_provider *sp, const struct file_record *rec) @@ -204,6 +202,10 @@ static void append_version(struct file_record *rec, const struct file_version *v * (otherwise they are ignored). `encrypted_secret' should be the file * encryption key XOR'd with HMAC(file index | file counter, * user_key). kf should be HMAC(encryption secret, file index). + * + * If the request is to either modify the ACL or create a file (which + * is essentially an ACL update), the ACL will be set to + * new_acl. `new_acl' must be in persistent storage. */ struct tm_cert sp_request(struct service_provider *sp, const struct user_request *req, hash_t req_hmac, @@ -211,8 +213,8 @@ struct tm_cert sp_request(struct service_provider *sp, struct tm_cert *vr_out, hash_t *vr_hmac_out, hash_t *ack_hmac_out, hash_t encrypted_secret, hash_t kf, - const void *encrypted_contents, - size_t contents_len) + const void *encrypted_contents, size_t contents_len, + struct iomt *new_acl) { struct tm_cert vr = cert_null; hash_t vr_hmac, ack_hmac, fr_hmac; @@ -233,10 +235,21 @@ struct tm_cert sp_request(struct service_provider *sp, need_insert = true; } + rec->idx = fr.fr.idx; rec->counter = fr.fr.counter; rec->fr_cert = fr; rec->fr_hmac = fr_hmac; + if(req->type == ACL_UPDATE) + { + /* update our ACL */ + iomt_free(rec->acl); + rec->acl = new_acl; + + /* check that the passed value matches the calculated root */ + assert(hash_equals(req->val, new_acl->mt_nodes[0])); + } + if(rec->version != fr.fr.version) { rec->version = fr.fr.version; @@ -298,76 +311,134 @@ struct tm_cert sp_request(struct service_provider *sp, return fr; } -void sp_test(void) +struct user_request sp_createfile(struct service_provider *sp, + uint64_t user_id, const void *key, size_t keylen, + hash_t *ack_hmac) { - /* 2^10 = 1024 leaves ought to be enough for anybody */ - int logleaves = 4; - struct service_provider *sp = sp_new("a", 1, logleaves); + int i; + for(i = 0; i < sp->iomt->mt_leafcount; ++i) + { + if(is_zero(sp->iomt->mt_leaves[i].val)) + break; + } + + /* fail */ + if(i == sp->iomt->mt_leafcount) + { + return req_null; + } - /* construct a request to create a file */ - printf("File creation: "); int *file_compidx, *file_orders; - file_compidx = merkle_complement(0, sp->iomt->mt_logleaves, &file_orders); + file_compidx = merkle_complement(i, sp->iomt->mt_logleaves, &file_orders); hash_t *file_comp = lookup_nodes(sp->iomt->mt_nodes, file_compidx, sp->iomt->mt_logleaves); - struct user_request req = req_filecreate(sp->tm, 1, - sp->iomt->mt_leaves + 0, - file_comp, file_orders, sp->iomt->mt_logleaves); + struct iomt *acl = iomt_new(ACL_LOGLEAVES); + acl->mt_leaves[0] = (struct iomt_node) { user_id, user_id, u64_to_hash(3) }; + merkle_update(acl, 0, hash_node(acl->mt_leaves + 0), NULL); - hash_t req_hmac = hmac_sha256(&req, sizeof(req), "a", 1); + struct user_request req = req_filecreate(sp->tm, + i + 1, + sp->iomt->mt_leaves + i, + file_comp, file_orders, sp->iomt->mt_logleaves); + hash_t req_hmac = hmac_sha256(&req, sizeof(req), key, keylen); hash_t fr_hmac; - hash_t ack_hmac; - struct tm_cert fr_cert = sp_request(sp, &req, req_hmac, &fr_hmac, NULL, NULL, &ack_hmac, - hash_null, hash_null, NULL, 0); + struct tm_cert fr_cert = sp_request(sp, + &req, req_hmac, + &fr_hmac, + NULL, NULL, + ack_hmac, + hash_null, hash_null, NULL, 0, + acl); + if(fr_cert.type == FR) + return req; + return req_null; +} + +struct user_request sp_modifyfile(struct service_provider *sp, + uint64_t user_id, const void *key, size_t keylen, + uint64_t file_idx, + hash_t encrypted_secret, + const void *encrypted_file, size_t filelen, + hash_t *ack_hmac) +{ + /* modification */ + struct file_record *rec = lookup_record(sp, file_idx); + if(!rec) + return req_null; - check(fr_cert.type == FR && - fr_cert.fr.counter == 1 && - fr_cert.fr.version == 0); + struct iomt_node *file_node = lookup_leaf(sp->iomt, file_idx); - struct iomt_node acl_node = (struct iomt_node) { 1, 1, u64_to_hash(3) }; + /* hack */ + int leaf_idx = file_node - sp->iomt->mt_leaves; + + int *file_compidx, *file_orders; + file_compidx = merkle_complement(leaf_idx, sp->iomt->mt_logleaves, &file_orders); + + hash_t *file_comp = lookup_nodes(sp->iomt->mt_nodes, file_compidx, sp->iomt->mt_logleaves); + + /* get ACL node and its complement */ + struct iomt_node *acl_node = lookup_leaf(rec->acl, user_id); + int aclnode_idx = acl_node - rec->acl->mt_leaves; + int *acl_orders; + int *acl_compidx = merkle_complement(aclnode_idx, rec->acl->mt_logleaves, &acl_orders); + + hash_t *acl_comp = lookup_nodes(rec->acl->mt_nodes, acl_compidx, rec->acl->mt_logleaves); - /* modification */ struct user_request mod = req_filemodify(sp->tm, - &fr_cert, fr_hmac, - sp->iomt->mt_leaves + 0, + &rec->fr_cert, rec->fr_hmac, + file_node, file_comp, file_orders, sp->iomt->mt_logleaves, - &acl_node, - NULL, NULL, 0, + acl_node, + acl_comp, acl_orders, rec->acl->mt_logleaves, hash_null); - req_hmac = hmac_sha256(&mod, sizeof(mod), "a", 1); + hash_t req_hmac = hmac_sha256(&mod, sizeof(mod), key, keylen); struct tm_cert vr; - hash_t vr_hmac; + hash_t vr_hmac, fr_hmac; + + struct tm_cert new_fr = sp_request(sp, &mod, req_hmac, &fr_hmac, &vr, &vr_hmac, ack_hmac, + hash_null, hash_null, "contents", 8, NULL); + if(new_fr.type == FR) + return mod; + return req_null; +} + +static bool ack_verify(const struct user_request *req, + const void *secret, size_t secret_len, + hash_t hmac) +{ + hash_t correct = ack_sign(req, secret, secret_len); + return hash_equals(hmac, correct); +} + +void sp_test(void) +{ + /* 2^10 = 1024 leaves ought to be enough for anybody */ + int logleaves = 2; + struct service_provider *sp = sp_new("a", 1, logleaves); + + check("Tree initialization", sp != NULL); + + hash_t ack_hmac; + struct user_request req = sp_createfile(sp, 1, "a", 1, &ack_hmac); + + check("File creation", ack_verify(&req, "a", 1, ack_hmac)); + + req = sp_modifyfile(sp, 1, "a", 1, 1, hash_null, NULL, 0, &ack_hmac); + + check("File modification", ack_verify(&req, "a", 1, ack_hmac)); - struct tm_cert new_fr = sp_request(sp, &mod, req_hmac, &fr_hmac, &vr, &vr_hmac, &ack_hmac, - hash_null, hash_null, "contents", 8); - printf("File modification: "); - check(new_fr.type == FR); - - printf("Complement calculation: "); - int *orders; - int *comp = merkle_complement(6, 4, &orders); - int correct[] = { 22, 9, 3, 2 }; - int correct_orders[] = { 1, 0, 0, 1 }; - check(!memcmp(comp, correct, 4 * sizeof(int)) && !memcmp(orders, correct_orders, 4 * sizeof(int))); - free(orders); - free(comp); - - printf("Dependency calculation: "); - int *dep = merkle_dependents(6, 4); - int correct_dep[] = { 10, 4, 1, 0 }; - check(!memcmp(dep, correct_dep, 4 * sizeof(int))); - free(dep); + printf("CDI-IOMT contents: "); + iomt_dump(sp->iomt); /* test tree initilization (only simple case) */ if(logleaves == 1) { struct iomt_node a = { 1, 2, hash_null }; struct iomt_node b = { 2, 1, hash_null }; - printf("Merkle tree initialization: "); - check(hash_equals(sp->iomt->mt_nodes[0], merkle_parent(hash_node(&a), hash_node(&b), 0))); + check("Merkle tree initialization", hash_equals(sp->iomt->mt_nodes[0], merkle_parent(hash_node(&a), hash_node(&b), 0))); } } |