diff options
-rw-r--r-- | runtime/librsgt.c | 82 | ||||
-rw-r--r-- | runtime/librsgt.h | 14 | ||||
-rw-r--r-- | tools/rsgttlvdump.c | 12 |
3 files changed, 93 insertions, 15 deletions
diff --git a/runtime/librsgt.c b/runtime/librsgt.c index e5187c42..4e457005 100644 --- a/runtime/librsgt.c +++ b/runtime/librsgt.c @@ -233,11 +233,68 @@ printf("TTTT: tlvlen %u, lenDer %u\n", tlvlen, lenDer); tlvbufAddOctetString(ctx, der, lenDer); } +/* read rsyslog log state file; if we cannot access it or the + * contents looks invalid, we flag it as non-present (and thus + * begin a new hash chain). + * The context is initialized accordingly. + */ +static void +readStateFile(gtctx ctx) +{ + int fd; + struct rsgtstatefile sf; + int rr; + + fd = open((char*)ctx->statefilename, O_RDONLY|O_NOCTTY|O_CLOEXEC, 0600); + if(fd == -1) goto err; + + if(read(fd, &sf, sizeof(sf)) != sizeof(sf)) goto err; + if(strncmp(sf.hdr, "GTSTAT10", 8)) goto err; + + ctx->lenBlkStrtHash = hashOutputLengthOctets(sf.lenHash); + ctx->blkStrtHash = calloc(1, ctx->lenBlkStrtHash); + if((rr=read(fd, ctx->blkStrtHash, ctx->lenBlkStrtHash)) + != ctx->lenBlkStrtHash) { + free(ctx->blkStrtHash); + goto err; + } +return; + +err: + ctx->lenBlkStrtHash = hashOutputLengthOctets(ctx->hashAlg); + ctx->blkStrtHash = calloc(1, ctx->lenBlkStrtHash); +} + +/* persist all information that we need to re-open and append + * to a log signature file. + */ +static void +writeStateFile(gtctx ctx) +{ + int fd; + struct rsgtstatefile sf; + + fd = open((char*)ctx->statefilename, + O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY|O_CLOEXEC, 0600); + if(fd == -1) + goto done; + + memcpy(sf.hdr, "GTSTAT10", 8); + sf.hashID = hashIdentifier(ctx->hashAlg); + sf.lenHash = ctx->x_prev->digest_length; + write(fd, &sf, sizeof(sf)); + write(fd, ctx->x_prev->digest, ctx->x_prev->digest_length); + close(fd); +done: return; +} + + void tlvClose(gtctx ctx) { tlvFlush(ctx); close(ctx->fd); ctx->fd = -1; + writeStateFile(ctx); } @@ -247,19 +304,21 @@ void tlvClose(gtctx ctx) void tlvOpen(gtctx ctx, char *hdr, unsigned lenHdr) { ctx->fd = open((char*)ctx->sigfilename, - O_WRONLY/*|O_APPEND*/|O_CREAT|O_NOCTTY|O_CLOEXEC, 0600); - // FIXME: check fd == -1 - memcpy(ctx->tlvBuf, hdr, lenHdr); - ctx->tlvIdx = lenHdr; + O_WRONLY|O_APPEND|O_NOCTTY|O_CLOEXEC, 0600); + if(ctx->fd == -1) { + /* looks like we need to create a new file */ + ctx->fd = open((char*)ctx->sigfilename, + O_WRONLY|O_CREAT|O_NOCTTY|O_CLOEXEC, 0600); + // FIXME: check fd == -1 + memcpy(ctx->tlvBuf, hdr, lenHdr); + ctx->tlvIdx = lenHdr; + } else { + ctx->tlvIdx = 0; /* header already present! */ + } /* we now need to obtain the last previous hash, so that * we can continue the hash chain. */ - // ... - /* in case we did not have a previous hash (or could not - * obtain it), we start with zero. - */ - ctx->lenBlkStrtHash = hashOutputLengthOctets(ctx->hashAlg); - ctx->blkStrtHash = calloc(1, ctx->lenBlkStrtHash); + readStateFile(ctx); } /* @@ -303,6 +362,9 @@ rsgtCtxNew(unsigned char *logfn, enum GTHashAlgorithm hashAlg) snprintf(fn, sizeof(fn), "%s.gtsig", logfn); fn[MAXFNAME] = '\0'; /* be on save side */ ctx->sigfilename = (uchar*) strdup(fn); + snprintf(fn, sizeof(fn), "%s.gtstate", logfn); + fn[MAXFNAME] = '\0'; /* be on save side */ + ctx->statefilename = (uchar*) strdup(fn); tlvOpen(ctx, LOGSIGHDR, sizeof(LOGSIGHDR)-1); return ctx; } diff --git a/runtime/librsgt.h b/runtime/librsgt.h index 4ce0be30..ff35d19b 100644 --- a/runtime/librsgt.h +++ b/runtime/librsgt.h @@ -39,6 +39,7 @@ struct gtctx_s { GTDataHash *x_prev; /* last leaf hash (maybe of previous block) --> preserve on term */ char *timestamper; unsigned char *sigfilename; + unsigned char *statefilename; int fd; unsigned char *blkStrtHash; /* last hash from previous block */ uint16_t lenBlkStrtHash; @@ -70,8 +71,6 @@ struct block_sig_s { uint8_t hashID; uint8_t sigID; /* what type of *signature*? */ uint8_t *iv; - // TODO: think about the situation where the last hash is - // different from the current one (e.g. config change!) imprint_t lastHash; uint64_t recCount; struct { @@ -82,6 +81,17 @@ struct block_sig_s { } sig; }; + +/* the following defines the gtstate file record. Currently, this record + * is fixed, we may change that over time. + */ +struct rsgtstatefile { + char hdr[8]; /* must be "GTSTAT10" */ + uint8_t hashID; + uint8_t lenHash; + /* after that, the hash value is contained within the file */ +}; + /* error states */ #define RSGTE_IO 1 /* any kind of io error, including EOF */ #define RSGTE_FMT 2 /* data fromat error */ diff --git a/tools/rsgttlvdump.c b/tools/rsgttlvdump.c index af5b1a03..256a85b5 100644 --- a/tools/rsgttlvdump.c +++ b/tools/rsgttlvdump.c @@ -52,8 +52,15 @@ processFile(char *name) } if(rsgt_tlvrdHeader(fp, hdr) != 0) goto err; printf("File Header: '%s'\n", hdr); - if(rsgt_tlvrd(fp, &tlvtype, &tlvlen, &obj) != 0) goto err; - rsgt_tlvprint(stdout, tlvtype, obj, 0); + while(1) { /* we will err out on EOF */ + if(rsgt_tlvrd(fp, &tlvtype, &tlvlen, &obj) != 0) { + if(feof(fp)) + break; + else + goto err; + } + rsgt_tlvprint(stdout, tlvtype, obj, 0); + } if(fp != stdin) fclose(fp); @@ -61,7 +68,6 @@ processFile(char *name) err: fprintf(stderr, "error processing file %s\n", name); } - int main(int argc, char *argv[]) { |