diff options
-rwxr-xr-x | siglog-witness.py | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/siglog-witness.py b/siglog-witness.py index 2c9862e..c1152ef 100755 --- a/siglog-witness.py +++ b/siglog-witness.py @@ -416,22 +416,52 @@ def main(args): if not cur_tree_head.signature_valid(log_verification_key): return ERR_TREEHEAD_SIGNATURE_INVALID, "ERROR: signature of current tree head invalid" + # TODO: move to TreeHead.validate_history() ts_sec = new_tree_head.timestamp() ts_asc = time.ctime(ts_sec) if ts_sec < now - 12 * 3600: return (ERR_OK, - "WARNING: timestamp too old: {} ({})".format(ts_sec, ts_asc)) + "WARNING: Tree head timestamp too old: {} ({})".format(ts_sec, ts_asc)) if ts_sec > now + 12 * 3600: return (ERR_OK, - "WARNING: timestamp too new: {} ({})".format(ts_sec, ts_asc)) + "WARNING: Tree head timestamp too new: {} ({})".format(ts_sec, ts_asc)) - # TODO: Needs more thought: size, hash, timestamp -- what may change and what may not? - if new_tree_head.tree_size() <= cur_tree_head.tree_size(): - return 0, "INFO: Fetched head of tree of size {} already seen".format(cur_tree_head.tree_size()) + if new_tree_head.tree_size() < cur_tree_head.tree_size(): + return (ERR_TREEHEAD_INVALID, + "ERROR: Log is shrinking: {} < {} ".format(new_tree_head.tree_size(), + cur_tree_head.tree_size())) + + if new_tree_head.timestamp() < cur_tree_head.timestamp(): + return (ERR_TREEHEAD_INVALID, + "ERROR: Log is time traveling: {} < {} ".format(time.ctime(new_tree_head.timestamp()), + time.ctime(cur_tree_head.timestamp()))) + + if new_tree_head.timestamp() == cur_tree_head.timestamp() and \ + new_tree_head.root_hash() == cur_tree_head.root_hash() and \ + new_tree_head.tree_size() == cur_tree_head.tree_size(): + return (ERR_OK, + "INFO: Fetched head of tree of size {} already seen".format(cur_tree_head.tree_size())) + + if new_tree_head.root_hash() == cur_tree_head.root_hash() and \ + new_tree_head.tree_size() != cur_tree_head.tree_size(): + return (ERR_TREEHEAD_INVALID, + "ERROR: Tree size has changed but hash has not: " + "{}: {} != {}".format(new_tree_head.root_hash(), + new_tree_head.tree_size(), + cur_tree_head.tree_size())) + + if new_tree_head.root_hash() != cur_tree_head.root_hash() and \ + new_tree_head.tree_size() == cur_tree_head.tree_size(): + return (ERR_TREEHEAD_INVALID, + "ERROR: Hash has changed but tree size has not: " + "{}: {} != {}".format(new_tree_head.tree_size(), + new_tree_head.root_hash(), + cur_tree_head.root_hash())) + + # Same hash and size, new timestamp is ok. proof, err = fetch_consistency_proof(cur_tree_head.tree_size(), new_tree_head.tree_size()) if err: return err - if not consistency_proof_valid(cur_tree_head, new_tree_head, proof): errmsg = "ERROR: failing consistency proof check for {}->{}\n".format(cur_tree_head.tree_size(), new_tree_head.tree_size()) @@ -441,6 +471,7 @@ def main(args): new_tree_head.root_hash(), proof.path()) return ERR_CONSISTENCYPROOF_INVALID, errmsg + # TODO: end move err = sign_send_store_tree_head(signing_key, new_tree_head) if err: return err |