diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2013-03-17 13:06:02 +0100 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2013-03-17 13:06:02 +0100 |
commit | d2467c38d42f590deecd807741324fc0e5522a8a (patch) | |
tree | c9d56cee1e0119ba9bd5f516a68bd7e1269712fe /runtime/librsgt_read.c | |
parent | 44b4922825df794f678cd4ad18d940ff114b943f (diff) | |
download | rsyslog-d2467c38d42f590deecd807741324fc0e5522a8a.tar.gz rsyslog-d2467c38d42f590deecd807741324fc0e5522a8a.tar.bz2 rsyslog-d2467c38d42f590deecd807741324fc0e5522a8a.zip |
logsig: milestone/verfier: record hashes are verified
Diffstat (limited to 'runtime/librsgt_read.c')
-rw-r--r-- | runtime/librsgt_read.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/runtime/librsgt_read.c b/runtime/librsgt_read.c index 961e50c5..ca52cb93 100644 --- a/runtime/librsgt_read.c +++ b/runtime/librsgt_read.c @@ -277,6 +277,22 @@ rsgt_tlvrdIMPRINT(FILE *fp, imprint_t **imprint, uint16_t tlvlen) done: return r; } +static int +rsgt_tlvrdRecHash(FILE *fp, imprint_t **imp) +{ + 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 != 0x0900) { + r = RSGTE_MISS_REC_HASH; + goto done; + } + if((r = rsgt_tlvrdIMPRINT(fp, imp, tlvlen)) != 0) goto done; + r = 0; +done: return r; +} /**; * Read the next "object" from file. This usually is @@ -528,3 +544,113 @@ rsgt_chkFileHdr(FILE *fp, char *expect) done: return r; } + +gtfile +rsgt_vrfyConstruct_gf(void) +{ + gtfile gf; + if((gf = calloc(1, sizeof(struct gtfile_s))) == NULL) + goto done; + gf->x_prev = NULL; + +done: return gf; +} + +void +rsgt_vrfyBlkInit(gtfile gf, block_sig_t *bs, uint8_t bHasRecHashes, uint8_t bHasIntermedHashes) +{ +printf("bs->hashID %d\n", bs->hashID); + gf->hashAlg = hashID2Alg(bs->hashID); + gf->bKeepRecordHashes = bHasRecHashes; + gf->bKeepTreeHashes = bHasIntermedHashes; + free(gf->IV); + gf->IV = malloc(getIVLen(bs)); + memcpy(gf->IV, bs->iv, getIVLen(bs)); +} + +static int +rsgt_vrfy_chkRecHash(gtfile gf, FILE *sigfp, GTDataHash *recHash) +{ + int r = 0; + imprint_t *imp; + + if(!gf->bKeepRecordHashes) + goto done; + if((r = rsgt_tlvrdRecHash(sigfp, &imp)) != 0) + goto done; + if(imp->hashID != hashIdentifier(gf->hashAlg)) { + r = RSGTE_INVLD_REC_HASHID; + goto done; + } +printf("imp hash:"); +outputHexBlob(stdout, imp->data, hashOutputLengthOctets(imp->hashID), 1); +printf("\nrec hash:"); +outputHexBlob(stdout, recHash->digest, hashOutputLengthOctets(imp->hashID), 1); +printf("\n"); + if(memcmp(imp->data, recHash->digest, + hashOutputLengthOctets(imp->hashID))) { + r = RSGTE_INVLD_REC_HASH; + goto done; + } +printf("record hash is OK\n"); + r = 0; +done: + return r; +} + +int +rsgt_vrfy_nextRec(block_sig_t *bs, gtfile gf, FILE *sigfp, unsigned char *rec, + size_t len) +{ + int r = 0; + GTDataHash *x; /* current hash */ + 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) { + r = rsgt_vrfy_chkRecHash(gf, sigfp, recHash); + if(r != 0) goto done; + } + hash_node(gf, &x, m, recHash, 1); /* hash leaf */ + /* persists x here if Merkle tree needs to be persisted! */ + //if(gf->bKeepTreeHashes) + //tlvWriteHash(gf, 0x0901, x); + /* add x to the forest as new leaf, update roots list */ + t = x; + for(j = 0 ; j < gf->nRoots ; ++j) { + if(gf->roots_valid[j] == 0) { + gf->roots_hash[j] = t; + gf->roots_valid[j] = 1; + t = NULL; + break; + } else if(t != NULL) { + /* hash interim node */ + hash_node(gf, &t, gf->roots_hash[j], t, j+2); + gf->roots_valid[j] = 0; + GTDataHash_free(gf->roots_hash[j]); + // TODO: check if this is correct location (paper!) + //if(gf->bKeepTreeHashes) + //tlvWriteHash(gf, 0x0901, t); + } + } + if(t != NULL) { + /* new level, append "at the top" */ + gf->roots_hash[gf->nRoots] = t; + gf->roots_valid[gf->nRoots] = 1; + ++gf->nRoots; + assert(gf->nRoots < MAX_ROOTS); + t = NULL; + } + gf->x_prev = x; /* single var may be sufficient */ + ++gf->nRecords; + + /* cleanup */ + /* note: x is freed later as part of roots cleanup */ + GTDataHash_free(m); + GTDataHash_free(recHash); +done: + return r; +} |