X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fjournal%2Fjournal-authenticate.c;h=586daf34cd879d62bd0d4d93a7aa439d5b018f65;hp=ddcf856aec1131bcb3cff4fc26d3f6e04236d860;hb=671e021c92c835c6c701dc61463149d05b6f31af;hpb=8088cbd3cfcf539c984d8042cd2b92ebbfda6d82 diff --git a/src/journal/journal-authenticate.c b/src/journal/journal-authenticate.c index ddcf856ae..586daf34c 100644 --- a/src/journal/journal-authenticate.c +++ b/src/journal/journal-authenticate.c @@ -211,6 +211,9 @@ int journal_file_maybe_append_tag(JournalFile *f, uint64_t realtime) { if (!f->seal) return 0; + if (realtime <= 0) + realtime = now(CLOCK_REALTIME); + r = journal_file_fsprg_need_evolve(f, realtime); if (r <= 0) return 0; @@ -362,7 +365,7 @@ int journal_file_fss_load(JournalFile *f) { goto finish; } - if (le64toh(m->fsprg_state_size) != FSPRG_stateinbytes(m->fsprg_secpar)) { + if (le64toh(m->fsprg_state_size) != FSPRG_stateinbytes(le16toh(m->fsprg_secpar))) { r = -EBADMSG; goto finish; } @@ -410,12 +413,26 @@ finish: return r; } +static void initialize_libgcrypt(void) { + const char *p; + + if (gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P)) + return; + + p = gcry_check_version("1.4.5"); + assert(p); + + gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); +} + int journal_file_hmac_setup(JournalFile *f) { gcry_error_t e; if (!f->seal) return 0; + initialize_libgcrypt(); + e = gcry_md_open(&f->hmac, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); if (e != 0) return -ENOTSUP; @@ -461,8 +478,75 @@ int journal_file_append_first_tag(JournalFile *f) { return 0; } -bool journal_file_fss_enabled(JournalFile *f) { + +int journal_file_parse_verification_key(JournalFile *f, const char *key) { + 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 = key; + 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->fss_start_usec = start * interval; + f->fss_interval_usec = interval; + + return 0; +} + +bool journal_file_next_evolve_usec(JournalFile *f, usec_t *u) { + uint64_t epoch; + assert(f); + assert(u); + + if (!f->seal) + return false; + + epoch = FSPRG_GetEpoch(f->fsprg_state); + + *u = (usec_t) (f->fss_start_usec + f->fss_interval_usec * epoch + f->fss_interval_usec); - return JOURNAL_HEADER_SEALED(f->header); + return true; }