summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2013-03-17 15:46:24 +0100
committerRainer Gerhards <rgerhards@adiscon.com>2013-03-17 15:46:24 +0100
commitb09d37063fc155ff5ec38430c679da5be5de0dcc (patch)
tree0ac345aa1f8a74d29b51f40eb5aa5051cbb09942
parent03901766c7f452c637ac57ec526b98895da510d5 (diff)
downloadrsyslog-b09d37063fc155ff5ec38430c679da5be5de0dcc.tar.gz
rsyslog-b09d37063fc155ff5ec38430c679da5be5de0dcc.tar.bz2
rsyslog-b09d37063fc155ff5ec38430c679da5be5de0dcc.zip
logsig: milestone/verfier: block timestamp verification almost complete
unfortunately, there seems to be a problem with the GuardTime API, so that I need their support before being able to carry on. Once I receive it, it should be fairly quick to complete the function. I am commiting this work as I do not know how long it will take to receive an answer.
-rw-r--r--runtime/librsgt.h3
-rw-r--r--runtime/librsgt_read.c109
-rw-r--r--tools/rsgtutil.c2
3 files changed, 112 insertions, 2 deletions
diff --git a/runtime/librsgt.h b/runtime/librsgt.h
index 35ee96b5..26eaf8ee 100644
--- a/runtime/librsgt.h
+++ b/runtime/librsgt.h
@@ -126,6 +126,8 @@ struct rsgtstatefile {
#define RSGTE_INVLD_TREE_HASH 13 /* invalid tree hash (failed verification) */
#define RSGTE_INVLD_REC_HASHID 14 /* invalid record hash ID (failed verification) */
#define RSGTE_INVLD_TREE_HASHID 15 /* invalid tree hash ID (failed verification) */
+#define RSGTE_MISS_BLOCKSIG 16 /* block signature record missing when expected */
+#define RSGTE_INVLD_TIMESTAMP 17 /* RFC3161 timestamp is invalid */
static inline uint16_t
@@ -262,6 +264,7 @@ int rsgt_chkFileHdr(FILE *fp, char *expect);
gtfile rsgt_vrfyConstruct_gf(void);
void rsgt_vrfyBlkInit(gtfile gf, block_sig_t *bs, uint8_t bHasRecHashes, uint8_t bHasIntermedHashes);
int rsgt_vrfy_nextRec(block_sig_t *bs, gtfile gf, FILE *sigfp, unsigned char *rec, size_t lenRec);
+int verifyBLOCK_SIG(block_sig_t *bs, gtfile gf, FILE *sigfp, uint64_t nRecs);
/* TODO: replace these? */
void hash_m(gtfile gf, GTDataHash **m);
diff --git a/runtime/librsgt_read.c b/runtime/librsgt_read.c
index 8dc6f811..0cc5f492 100644
--- a/runtime/librsgt_read.c
+++ b/runtime/librsgt_read.c
@@ -311,6 +311,24 @@ printf("read tlvtype %4.4x\n", tlvtype);
done: return r;
}
+/* read BLOCK_SIG during verification phase */
+static int
+rsgt_tlvrdVrfyBlockSig(FILE *fp, block_sig_t **bs)
+{
+ int r;
+ uint16_t tlvtype, tlvlen;
+
+ if((r = rsgt_tlvrdTL(fp, &tlvtype, &tlvlen)) != 0) goto done;
+printf("read tlvtype %4.4x\n", tlvtype);
+ if(tlvtype != 0x0902) {
+ r = RSGTE_MISS_BLOCKSIG;
+ goto done;
+ }
+ if((r = rsgt_tlvrdBLOCK_SIG(fp, bs, tlvlen)) != 0) goto done;
+ r = 0;
+done: return r;
+}
+
/**;
* Read the next "object" from file. This usually is
* a single TLV, but may be something larger, for
@@ -649,7 +667,6 @@ rsgt_vrfy_nextRec(block_sig_t *bs, gtfile gf, FILE *sigfp, unsigned char *rec,
GTDataHash *m, *recHash, *t;
uint8_t j;
-printf("hasRecHash %d, verify: %s", gf->bKeepRecordHashes, rec);
hash_m(gf, &m);
hash_r(gf, &recHash, rec, len);
if(gf->bKeepRecordHashes) {
@@ -700,3 +717,93 @@ printf("hasRecHash %d, verify: %s", gf->bKeepRecordHashes, rec);
done:
return r;
}
+
+
+static int
+verifyTimestamp(gtfile gf, GTDataHash *root)
+{
+ int r = 0;
+ printf("in verifyTimestamp\n");
+ return r;
+}
+
+
+/* TODO: think about merging this with the writer. The
+ * same applies to the other computation algos.
+ */
+static int
+verifySigblkFinish(gtfile gf)
+{
+ GTDataHash *root, *rootDel;
+ int8_t j;
+ int r;
+
+ if(gf->nRecords == 0)
+ goto done;
+
+ root = NULL;
+ for(j = 0 ; j < gf->nRoots ; ++j) {
+ if(root == NULL) {
+ root = gf->roots_hash[j];
+ gf->roots_valid[j] = 0; /* guess this is redundant with init, maybe del */
+ } else if(gf->roots_valid[j]) {
+ rootDel = root;
+ hash_node(gf, &root, gf->roots_hash[j], root, j+2);
+ gf->roots_valid[j] = 0; /* guess this is redundant with init, maybe del */
+ GTDataHash_free(rootDel);
+ }
+ }
+ r = verifyTimestamp(gf, root);
+
+ free(gf->blkStrtHash);
+ gf->blkStrtHash = NULL;
+ // We do not need the following as we take this from the block params
+ // (but I leave it in in order to aid getting to common code)
+ //gf->lenBlkStrtHash = gf->x_prev->digest_length;
+ //gf->blkStrtHash = malloc(gf->lenBlkStrtHash);
+ //memcpy(gf->blkStrtHash, gf->x_prev->digest, gf->lenBlkStrtHash);
+done:
+ gf->bInBlk = 0;
+ return r;
+}
+
+/* verify the root hash. This also means we need to compute the
+ * Merkle tree root for the current block.
+ */
+int
+verifyBLOCK_SIG(block_sig_t *bs, gtfile gf, FILE *sigfp, uint64_t nRecs)
+{
+ int r;
+ int gtstate;
+ block_sig_t *file_bs;
+ GTTimestamp *timestamp = NULL;
+ GTVerificationInfo *vrfyInf;
+
+ if((r = verifySigblkFinish(gf)) != 0)
+ goto done;
+ if((r = rsgt_tlvrdVrfyBlockSig(sigfp, &file_bs)) != 0)
+ goto done;
+printf("got sig block, now doing checks \n");
+ if(nRecs != bs->recCount) {
+ r = RSGTE_INVLD_RECCNT;
+ goto done;
+ }
+
+printf("len DER timestamp: %d, data %p\n", (int) file_bs->sig.der.len, file_bs->sig.der.data);
+ gtstate = GTTimestamp_DERDecode(file_bs->sig.der.data,
+ file_bs->sig.der.len, &timestamp);
+printf("result of GTTimestamp_DERDecode: %d\n", gtstate);
+ gtstate = GTTimestamp_verify(timestamp, 1, &vrfyInf);
+printf("result of GTTimestamp_verify: %d, verf_err %d\n", gtstate, vrfyInf->verification_errors );
+ if(! (gtstate == GT_OK
+ && vrfyInf->verification_errors == GT_NO_FAILURES) ) {
+ r = RSGTE_INVLD_TIMESTAMP; goto done;
+ }
+
+printf("root timestamp OK\n");
+ r = 0;
+done:
+ if(timestamp != NULL)
+ GTTimestamp_free(timestamp);
+ return r;
+}
diff --git a/tools/rsgtutil.c b/tools/rsgtutil.c
index d4c58d2d..cc045f8c 100644
--- a/tools/rsgtutil.c
+++ b/tools/rsgtutil.c
@@ -216,7 +216,7 @@ verify(char *name)
if((r = doVerifyRec(logfp, sigfp, bs, gf)) != 0)
goto err;
if(nRecs == bs->recCount) {
- // verifyBLOCK_SIG(bs, gf);
+ verifyBLOCK_SIG(bs, gf, sigfp, nRecs);
bInBlock = 0;
}
}