#!/usr/bin/python # -*- coding: utf-8 -*- import sys import time import datetime import os import json from precerttools import cleanprecert from monitor_conf import * from josef_lib import * def print_reply(rep, entry): t = datetime.datetime.fromtimestamp(rep['timestamp'] / 1000, UTC()).strftime("%Y-%m-%d %H:%M:%S") log_id = rep["id"] for log in CTLOGS: if str(log_id) == log["id"]: l = log break else: l = {"name" : "Log not found" + log_id} s = "Time:", t if is_new_timestamp(rep["timestamp"]): print s, "(NEW)" else: print s, "(OLD)" if entry[2]: print "Type: Precert" signed_entry = pack_precert(cleanprecert(entry[0][0]), entry[2]) else: print "Type: Cert" signed_entry = pack_cert(entry[0][0]) key = base64.b64decode(log["key"]) try: check_sct_signature(log["url"], signed_entry, rep, entry[2], key) print "Signature: OK" except: print "Could not verify signature!" print "" def is_new_timestamp(ts): MAX_TIMEDIFF = 300 # 5 min, allows for some clock skew ts_time = datetime.datetime.fromtimestamp(ts / 1000, UTC()).strftime('%Y-%m-%d %H:%M:%S') start_time = datetime.datetime.utcnow().strftime('2015-10-19 00:00:00') # delta_time = datetime.datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S') - datetime.datetime.strptime(ts_time, '%Y-%m-%d %H:%M:%S') # print delta_time.seconds if ts_time < start_time: return False else: return True def check_inclusion_all(first, last, source, dest): for s_log in source: url = s_log["url"] entries = [] while len(entries) + first != last + 1: entries += get_entries(url, str(first + len(entries)), last)["entries"] # print "Got " + str(len(entries)) + " entries..." for e in entries: inclusions = [] print base64.b64decode(e["leaf_input"]) h = get_leaf_hash(base64.b64decode(e["leaf_input"])) for log in dest: url = log["url"] if verify_inclusion_by_hash(url, h): inclusions.append(log["name"]) print "Entry found in " + str(len(inclusions)) + " logs: ", inclusions # success = False # if success: # print time.strftime("%H:%M:%S") + " Verifying inclusion for " + str(len(entries)) + " new entries in " + url + " ...OK" # else: # print time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url # errors.append(time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url) # except: # print time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url def move_entry(first, last, source, dest): # print entries for s_log in source: entries = get_entries(s_log["url"], first, last)["entries"] print "\n\nSource: " + s_log["name"] + "\n" for i in range(len(entries)): # for item in entries: item = entries[i] inclusions = [] for d_log in dests: print "Log: " + d_log["name"] try: entry = extract_original_entry(item) if entry[2]: precert = True else: precert = False submission = [] for e in entry[0]: submission.append(base64.b64encode(e)) if entry[2]: res = add_prechain(d_log["url"], {"chain" : submission}) else: res = add_chain(d_log["url"], {"chain" : submission}) print_reply(res, entry) if not is_new_timestamp(res["timestamp"]): inclusions.append(d_log["name"]) # time.sleep(5) except KeyboardInterrupt: sys.exit() except: print "FAILED!\n" print s_log["name"] + "[" + str(first + i) + "] found in " + str(len(inclusions)) + " logs: ", inclusions def check_inclusion_by_submission(first, last, source, dest): # print entries for s_log in source: try: entries = [] while len(entries) < last - first: print "Getting " + str(first + len(entries)) + " to " + str(last) entries += get_entries(s_log["url"], first + len(entries), last)["entries"] # print "Fetched entries up to " + str(len(first + len(entries))) except: print "Failed to get entries from " + s_log["name"] # print "\n\nSource: " + s_log["name"] + "\n" for i in range(len(entries)): # for item in entries: item = entries[i] inclusions = [] for d_log in dests: # print "Log: " + d_log["name"] try: entry = extract_original_entry(item) if entry[2]: precert = True else: precert = False submission = [] for e in entry[0]: submission.append(base64.b64encode(e)) if entry[2]: res = add_prechain(d_log["url"], {"chain" : submission}) else: res = add_chain(d_log["url"], {"chain" : submission}) # print_reply(res, entry) if not is_new_timestamp(res["timestamp"]): inclusions.append(d_log["name"]) # time.sleep(5) except KeyboardInterrupt: sys.exit() except: # print "FAILED!\n" pass s = s_log["name"] + "[" + str(first + i) + "] found in " + str(len(inclusions)) + " logs: " + str(inclusions) print s logfile = OUTPUT_DIR + s_log["name"] + "_overlap.log" log(logfile, s) def log(fn, string): logfile = fn s = time_str() + " " + string with open(logfile, 'a') as f: f.write(s + "\n") f.close() if __name__ == "__main__": source = [CTLOGS[7]] dests = CTLOGS # source = ctlogs # dests = ctlogs for tmp_log in source: sth = get_sth(tmp_log["url"]) first = 1654 last = int(sth["tree_size"]) - 1 # print last check_inclusion_by_submission(first, last, [tmp_log], dests) # check_inclusion_all(first,last,source, dests)