aboutsummaryrefslogtreecommitdiff
path: root/service_provider.c
diff options
context:
space:
mode:
authorFranklin Wei <me@fwei.tk>2018-06-15 12:26:45 -0400
committerFranklin Wei <me@fwei.tk>2018-06-15 12:26:45 -0400
commit62b6943d450944b7d461e8fc20049aa672c4e201 (patch)
treede52319f16ef6a56fb112347d545feca31f17bea /service_provider.c
parentfba7a547b3626e5ce3980623cd111dc84b854762 (diff)
downloadcsaa-62b6943d450944b7d461e8fc20049aa672c4e201.zip
csaa-62b6943d450944b7d461e8fc20049aa672c4e201.tar.gz
csaa-62b6943d450944b7d461e8fc20049aa672c4e201.tar.bz2
csaa-62b6943d450944b7d461e8fc20049aa672c4e201.tar.xz
Working on service provider's request handling; some cleanup too
Diffstat (limited to 'service_provider.c')
-rw-r--r--service_provider.c88
1 files changed, 74 insertions, 14 deletions
diff --git a/service_provider.c b/service_provider.c
index 8469d1a..7f87b72 100644
--- a/service_provider.c
+++ b/service_provider.c
@@ -12,12 +12,12 @@
#include "trusted_module.h"
struct file_version {
- hash_t kf; /* h(key, file_idx) */
- hash_t l; /* h(h(file contents), kf) */
- hash_t enc_key; /* XOR'd with h(kf, module secret) */
+ hash_t kf; /* HMAC(key, file_idx) */
+ hash_t l; /* HMAC(h(encrypted contents), kf) */
+ hash_t encrypted_secret; /* XOR'd with HMAC(kf, module secret) */
- struct tm_cert cert; /* VR certificate */
- hash_t cert_hmac;
+ struct tm_cert vr_cert; /* VR certificate */
+ hash_t vr_hmac;
void *contents;
size_t len;
@@ -35,7 +35,7 @@ struct file_record {
hash_t fr_hmac;
struct file_version *versions;
- int n_versions;
+ int nversions;
};
struct service_provider {
@@ -292,19 +292,39 @@ static struct file_record *lookup_record(struct service_provider *sp, int idx)
/* We do not check to ensure that there are no duplicate file indices;
* this is up to the caller */
-static void insert_record(struct service_provider *sp, struct file_record *rec)
+static void append_record(struct service_provider *sp, const struct file_record *rec)
{
sp->records = realloc(sp->records, sizeof(struct file_record) * ++sp->nrecords);
sp->records[sp->nrecords - 1] = *rec;
}
-/* this does the majority of the work that actually modifies or
- * creates a file */
+static void append_version(struct file_record *rec, const struct file_version *ver)
+{
+ rec->versions = realloc(rec->versions, sizeof(struct file_version) * ++rec->nversions);
+ rec->versions[rec->nversions - 1] = *ver;
+}
+
+/* This does the majority of the work that actually modifies or
+ * creates a file. It expects a filled and signed user_request
+ * structure, req, and will return the resulting FR certificate and
+ * its signature in *hmac_out. Additionally, the module's
+ * authenticated acknowledgement (equal to HMAC(req | 0), where |
+ * indicates concatenation) is output in *ack_hmac_out.
+ *
+ * If the request is to modify the file, the parameters
+ * encrypted_secret, kf, encrypted_contents, and contents_len are used
+ * (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).
+ */
struct tm_cert sp_request(struct service_provider *sp,
const struct user_request *req, hash_t req_hmac,
hash_t *hmac_out,
struct tm_cert *vr_out, hash_t *vr_hmac_out,
- hash_t *ack_hmac_out)
+ hash_t *ack_hmac_out,
+ hash_t encrypted_secret, hash_t kf,
+ const void *encrypted_contents,
+ size_t contents_len)
{
struct tm_cert vr = cert_null;
hash_t vr_hmac, ack_hmac, fr_hmac;
@@ -325,13 +345,51 @@ struct tm_cert sp_request(struct service_provider *sp,
need_insert = true;
}
- rec->version = fr.fr.version;
rec->counter = fr.fr.counter;
rec->fr_cert = fr;
rec->fr_hmac = fr_hmac;
+ if(rec->version != fr.fr.version)
+ {
+ rec->version = fr.fr.version;
+
+ struct file_version ver;
+ hash_t gamma = sha256(encrypted_contents, contents_len);
+ ver.l = hmac_sha256(&gamma, sizeof(gamma),
+ &kf, sizeof(kf));
+
+ if(!is_zero(encrypted_secret) && !is_zero(kf))
+ {
+ /* File is encrypted */
+ ver.encrypted_secret = tm_verify_and_encrypt_secret(sp->tm,
+ rec->idx, rec->counter,
+ req->user_id,
+ encrypted_secret, kf);
+ assert(!is_zero(ver.encrypted_secret));
+
+ /* We have no way of verifying that kf=HMAC(encryption
+ * secret, file index) ourselves; instead we rely on the
+ * module to do so for us. */
+ ver.kf = kf;
+ }
+ else
+ {
+ ver.encrypted_secret = hash_null;
+ }
+
+ ver.vr_cert = vr;
+ ver.vr_hmac = vr_hmac;
+
+ append_version(rec, &ver);
+ }
+
if(need_insert)
- insert_record(sp, rec);
+ {
+ append_record(sp, rec);
+
+ /* append_record will make a copy */
+ free(rec);
+ }
/* update our tree */
sp->mt_leaves[req->idx - 1].val = u64_to_hash(fr.fr.counter);
@@ -371,7 +429,8 @@ void sp_test(void)
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);
+ struct tm_cert fr_cert = sp_request(sp, &req, req_hmac, &fr_hmac, NULL, NULL, &ack_hmac,
+ hash_null, hash_null, NULL, 0);
check(fr_cert.type == FR &&
fr_cert.fr.counter == 1 &&
@@ -394,7 +453,8 @@ void sp_test(void)
struct tm_cert vr;
hash_t vr_hmac;
- struct tm_cert new_fr = sp_request(sp, &mod, req_hmac, &fr_hmac, &vr, &vr_hmac, &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);