summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2012-08-16 20:51:43 +0200
committerLennart Poettering <lennart@poettering.net>2012-08-16 21:00:47 +0200
commitb7c9ae91d111b3e89d1ffc00e08f9ed97a8ff5db (patch)
tree4159b77fd7b977222afbfd0b7ff536fa35c33545
parent2dee23ebe09965308c67a661ed0a8d2cc0ae1d5f (diff)
journal: parse fsprg seed
-rw-r--r--src/journal/journal-authenticate.c54
-rw-r--r--src/journal/journal-file.c8
-rw-r--r--src/journal/journal-file.h13
-rw-r--r--src/journal/journal-verify.c66
4 files changed, 104 insertions, 37 deletions
diff --git a/src/journal/journal-authenticate.c b/src/journal/journal-authenticate.c
index 5a0314b4f6..809655e1ac 100644
--- a/src/journal/journal-authenticate.c
+++ b/src/journal/journal-authenticate.c
@@ -27,22 +27,6 @@
#include "journal-authenticate.h"
#include "fsprg.h"
-static void *fsprg_state(JournalFile *f) {
- uint64_t a, b;
- assert(f);
-
- if (!f->authenticate)
- return NULL;
-
- a = le64toh(f->fsprg_header->header_size);
- b = le64toh(f->fsprg_header->state_size);
-
- if (a + b > f->fsprg_size)
- return NULL;
-
- return (uint8_t*) f->fsprg_header + a;
-}
-
static uint64_t journal_file_tag_seqnum(JournalFile *f) {
uint64_t r;
@@ -67,7 +51,7 @@ int journal_file_append_tag(JournalFile *f) {
if (!f->hmac_running)
return 0;
- log_debug("Writing tag for epoch %llu\n", (unsigned long long) FSPRG_GetEpoch(fsprg_state(f)));
+ log_debug("Writing tag for epoch %llu\n", (unsigned long long) FSPRG_GetEpoch(f->fsprg_state));
assert(f->hmac);
@@ -103,7 +87,7 @@ static int journal_file_hmac_start(JournalFile *f) {
/* Prepare HMAC for next cycle */
gcry_md_reset(f->hmac);
- FSPRG_GetKey(fsprg_state(f), key, sizeof(key), 0);
+ FSPRG_GetKey(f->fsprg_state, key, sizeof(key), 0);
gcry_md_setkey(f->hmac, key, sizeof(key));
f->hmac_running = true;
@@ -118,15 +102,15 @@ static int journal_file_get_epoch(JournalFile *f, uint64_t realtime, uint64_t *e
assert(epoch);
assert(f->authenticate);
- if (le64toh(f->fsprg_header->fsprg_start_usec) == 0 ||
- le64toh(f->fsprg_header->fsprg_interval_usec) == 0)
+ if (f->fsprg_start_usec == 0 ||
+ f->fsprg_interval_usec == 0)
return -ENOTSUP;
- if (realtime < le64toh(f->fsprg_header->fsprg_start_usec))
+ if (realtime < f->fsprg_start_usec)
return -ESTALE;
- t = realtime - le64toh(f->fsprg_header->fsprg_start_usec);
- t = t / le64toh(f->fsprg_header->fsprg_interval_usec);
+ t = realtime - f->fsprg_start_usec;
+ t = t / f->fsprg_interval_usec;
*epoch = t;
return 0;
@@ -144,7 +128,7 @@ static int journal_file_need_evolve(JournalFile *f, uint64_t realtime) {
if (r < 0)
return r;
- epoch = FSPRG_GetEpoch(fsprg_state(f));
+ epoch = FSPRG_GetEpoch(f->fsprg_state);
if (epoch > goal)
return -ESTALE;
@@ -164,7 +148,7 @@ static int journal_file_evolve(JournalFile *f, uint64_t realtime) {
if (r < 0)
return r;
- epoch = FSPRG_GetEpoch(fsprg_state(f));
+ epoch = FSPRG_GetEpoch(f->fsprg_state);
if (epoch < goal)
log_debug("Evolving FSPRG key from epoch %llu to %llu.", (unsigned long long) epoch, (unsigned long long) goal);
@@ -174,8 +158,8 @@ static int journal_file_evolve(JournalFile *f, uint64_t realtime) {
if (epoch == goal)
return 0;
- FSPRG_Evolve(fsprg_state(f));
- epoch = FSPRG_GetEpoch(fsprg_state(f));
+ FSPRG_Evolve(f->fsprg_state);
+ epoch = FSPRG_GetEpoch(f->fsprg_state);
}
}
@@ -345,8 +329,8 @@ int journal_file_load_fsprg(JournalFile *f) {
goto finish;
}
- f->fsprg_size = le64toh(m->header_size) + le64toh(m->state_size);
- if ((uint64_t) st.st_size < f->fsprg_size) {
+ f->fsprg_file_size = le64toh(m->header_size) + le64toh(m->state_size);
+ if ((uint64_t) st.st_size < f->fsprg_file_size) {
r = -ENODATA;
goto finish;
}
@@ -362,13 +346,19 @@ int journal_file_load_fsprg(JournalFile *f) {
goto finish;
}
- f->fsprg_header = mmap(NULL, PAGE_ALIGN(f->fsprg_size), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- if (f->fsprg_header == MAP_FAILED) {
- f->fsprg_header = NULL;
+ f->fsprg_file = mmap(NULL, PAGE_ALIGN(f->fsprg_file_size), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if (f->fsprg_file == MAP_FAILED) {
+ f->fsprg_file = NULL;
r = -errno;
goto finish;
}
+ f->fsprg_start_usec = le64toh(f->fsprg_file->fsprg_start_usec);
+ f->fsprg_interval_usec = le64toh(f->fsprg_file->fsprg_interval_usec);
+
+ f->fsprg_state = (uint8_t*) f->fsprg_file + le64toh(f->fsprg_file->header_size);
+ f->fsprg_state_size = le64toh(f->fsprg_file->state_size);
+
r = 0;
finish:
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 81952a08ee..3bb1e90fb3 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -96,8 +96,12 @@ void journal_file_close(JournalFile *f) {
#endif
#ifdef HAVE_GCRYPT
- if (f->fsprg_header)
- munmap(f->fsprg_header, PAGE_ALIGN(f->fsprg_size));
+ if (f->fsprg_file)
+ munmap(f->fsprg_file, PAGE_ALIGN(f->fsprg_file_size));
+ else if (f->fsprg_state)
+ free(f->fsprg_state);
+
+ free(f->fsprg_seed);
if (f->hmac)
gcry_md_close(f->hmac);
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index 1da1d3b834..9d437ae791 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -73,8 +73,17 @@ typedef struct JournalFile {
gcry_md_hd_t hmac;
bool hmac_running;
- FSPRGHeader *fsprg_header;
- size_t fsprg_size;
+ FSPRGHeader *fsprg_file;
+ size_t fsprg_file_size;
+
+ void *fsprg_state;
+ size_t fsprg_state_size;
+
+ void *fsprg_seed;
+ size_t fsprg_seed_size;
+
+ uint64_t fsprg_start_usec;
+ uint64_t fsprg_interval_usec;
#endif
} JournalFile;
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
index b4e34d18a8..f6cec1eb52 100644
--- a/src/journal/journal-verify.c
+++ b/src/journal/journal-verify.c
@@ -31,6 +31,7 @@
#include "journal-verify.h"
#include "lookup3.h"
#include "compress.h"
+#include "fsprg.h"
/* FIXME:
*
@@ -591,7 +592,62 @@ static int verify_entry_array(
return 0;
}
-int journal_file_verify(JournalFile *f, const char *key) {
+static int journal_file_parse_seed(JournalFile *f, const char *s) {
+ uint8_t *seed;
+ size_t seed_size, c;
+ const char *k;
+ int r;
+ unsigned long long start, interval;
+
+ seed_size = FSPRG_RECOMMENDED_SEEDLEN;
+ seed = malloc(seed_size);
+ if (!seed)
+ return -ENOMEM;
+
+ k = s;
+ for (c = 0; c < seed_size; c++) {
+ int x, y;
+
+ while (*k == '-')
+ k++;
+
+ x = unhexchar(*k);
+ if (x < 0) {
+ free(seed);
+ return -EINVAL;
+ }
+ k++;
+ y = unhexchar(*k);
+ if (y < 0) {
+ free(seed);
+ return -EINVAL;
+ }
+ k++;
+
+ seed[c] = (uint8_t) (x * 16 + y);
+ }
+
+ if (*k != '/') {
+ free(seed);
+ return -EINVAL;
+ }
+ k++;
+
+ r = sscanf(k, "%llx-%llx", &start, &interval);
+ if (r != 2) {
+ free(seed);
+ return -EINVAL;
+ }
+
+ f->fsprg_seed = seed;
+ f->fsprg_seed_size = seed_size;
+ f->fsprg_start_usec = start;
+ f->fsprg_interval_usec = interval;
+
+ return 0;
+}
+
+int journal_file_verify(JournalFile *f, const char *seed) {
int r;
Object *o;
uint64_t p = 0;
@@ -607,6 +663,14 @@ int journal_file_verify(JournalFile *f, const char *key) {
assert(f);
+ if (seed) {
+ r = journal_file_parse_seed(f, seed);
+ if (r < 0) {
+ log_error("Failed to parse seed.");
+ goto fail;
+ }
+ }
+
data_fd = mkostemp(data_path, O_CLOEXEC);
if (data_fd < 0) {
log_error("Failed to create data file: %m");