def run():
    """Fetch the proof for the supplied certificate."""
    #TODO(eranm): Attempt fetching the SCT for this chain if none was given.
    if FLAGS.sct:
        cert_sct = client_pb2.SignedCertificateTimestamp()
        sct_data = open(FLAGS.sct, 'rb').read()
        if FLAGS.binary_sct:
            tls_message.decode(sct_data, cert_sct)
        else:
            cert_sct.ParseFromString(sct_data)
        sct_timestamp = cert_sct.timestamp
        print 'SCT for cert:', cert_sct
    else:
        sct_timestamp = FLAGS.timestamp

    constructed_leaf = construct_leaf_from_file(FLAGS.cert, sct_timestamp)
    leaf_hash = merkle.TreeHasher().hash_leaf(constructed_leaf)
    if FLAGS.verbose:
        print "Leaf hash: %s" % (leaf_hash.encode("hex"))

    (sth, proof) = fetch_single_proof(leaf_hash, FLAGS.log_url)
    if FLAGS.verbose:
        print "Leaf index in tree is %d, proof has %d hashes" % (
            proof.leaf_index, len(proof.audit_path))
        print "Audit path: %s" % ([t.encode('hex') for t in proof.audit_path])

    verifier = merkle.MerkleVerifier()
    if verifier.verify_leaf_inclusion(constructed_leaf, proof.leaf_index,
                                      proof.audit_path, sth):
        print 'Proof verifies OK.'
 def test_hash_full_tree(self):
     hasher = merkle.TreeHasher()
     self.assertEqual(hasher.hash_full_tree([]), hasher.hash_empty())
     l = iter(hasher.hash_leaf(c) for c in "abcde").next
     h = hasher.hash_children
     root_hash = h(h(h(l(), l()), h(l(), l())), l())
     self.assertEqual(hasher.hash_full_tree("abcde"), root_hash)
    def test_get_proof_by_hash(self):
        client = self.default_client()
        entry = test_util.make_entry(1)
        hasher = merkle.TreeHasher()
        leaf_hash = hasher.hash_leaf(entry.leaf_input)

        proof_by_hash = client.get_proof_by_hash(leaf_hash, 2)
        self.assertEqual(proof_by_hash.audit_path, test_util.DEFAULT_FAKE_PROOF)
        self.assertEqual(proof_by_hash.leaf_index, 1)
Example #4
0
def dummy_compute_projected_sth(old_sth):
    sth = client_pb2.SthResponse()
    sth.timestamp = old_sth.timestamp
    sth.tree_size = size = old_sth.tree_size
    tree = merkle.CompactMerkleTree(merkle.TreeHasher(), size,
                                    ["a"] * merkle.count_bits_set(size))
    f = mock.Mock(return_value=(sth, tree))
    f.dummy_sth = sth
    f.dummy_tree = tree
    old_sth.sha256_root_hash = tree.root_hash()
    return f
    def test_tree_snapshot_root_hash(self):
        """Test root hash calculation.

        Test that root hash is calculated correctly when all leaves are added
        at once.
        """
        tree = in_memory_merkle_tree.InMemoryMerkleTree(TEST_VECTOR_DATA)
        hasher = merkle.TreeHasher()
        for i in range(len(TEST_VECTOR_DATA)):
            self.assertEqual(
                    tree.get_root_hash(i),
                    hasher.hash_full_tree(TEST_VECTOR_DATA[0:i]))
    def test_tree_incremental_root_hash(self):
        """Test root hash calculation.

        Test that root hash is calculated correctly when leaves are added
        incrementally.
        """
        tree = in_memory_merkle_tree.InMemoryMerkleTree([])
        hasher = merkle.TreeHasher()
        for i in range(len(TEST_VECTOR_DATA)):
            tree.add_leaf(TEST_VECTOR_DATA[i])
            self.assertEqual(
                    tree.get_root_hash(),
                    hasher.hash_full_tree(TEST_VECTOR_DATA[0:i+1]))
    def get_proof_by_hash(self, leaf_hash, tree_size):
        """If the hash is known, return a (fake) audit proof."""
        if (not leaf_hash or tree_size <= 0
                or tree_size > self._sth.tree_size):
            return self.make_response(400, "Bad Request")

        hasher = merkle.TreeHasher()
        for i in range(self._sth.tree_size):
            entry = make_entry(i)
            if hasher.hash_leaf(entry.leaf_input) == leaf_hash:
                return self.make_response(200,
                                          "OK",
                                          json_content=proof_and_index_to_json(
                                              DEFAULT_FAKE_PROOF, i))

        # Not found
        return self.make_response(400, "Bad Request")
Example #8
0
    def __init__(self,
                 ct_logs,
                 db,
                 cert_db,
                 temp_db_factory,
                 monitor_state_dir,
                 agent=None,
                 state_keeper_class=None):
        """Initialize from a CtLogs proto."""
        threading.Thread.__init__(self)

        self.__monitors = []
        self.__db = db
        if not agent:
            agent = twisted_client.Agent(reactor)
        if not state_keeper_class:
            state_keeper_class = state.StateKeeper

        for log in ct_logs.ctlog:
            if not log.log_server or not log.log_id or not log.public_key_info:
                raise RuntimeError("Cannot start monitor: log proto has "
                                   "missing or empty fields: %s" % log)

            try:
                temp_db = temp_db_factory.create_storage(log.log_server)
                client = async_log_client.AsyncLogClient(
                    agent, log.log_server, temp_db)
                hasher = merkle.TreeHasher()
                verifier = verify.LogVerifier(log.public_key_info,
                                              merkle.MerkleVerifier(hasher))
                # Convert from standard Base64 to URL-safe Base64 so that the
                # log ID can be used as part of a file path.
                log_id_urlsafe = log.log_id.replace('/', '_').replace('+', '-')
                state_keeper = state_keeper_class(monitor_state_dir + "/" +
                                                  log_id_urlsafe)
                log_key = db.get_log_id(log.log_server)
                self.__monitors.append(
                    monitor.Monitor(client, verifier, hasher, db, cert_db,
                                    log_key, state_keeper))
            except:
                logging.error("Error starting monitor for log: %s" % log)
                raise

        self.__last_update_start_time = 0
        self.__stopped = False
        self.__called_later = None
    def setUp(self):
        if not FLAGS.verbose_tests:
            logging.disable(logging.CRITICAL)
        self.db = sqlite_log_db.SQLiteLogDB(
            sqlitecon.SQLiteConnectionManager(":memory:", keepalive=True))
        self.temp_db = sqlite_temp_db.SQLiteTempDB(
            sqlitecon.SQLiteConnectionManager(":memory:", keepalive=True))

        default_state = client_pb2.MonitorState()
        default_state.verified_sth.CopyFrom(self._DEFAULT_STH)
        self.state_keeper = InMemoryStateKeeper(default_state)
        self.verifier = mock.Mock()
        self.hasher = merkle.TreeHasher()

        # Make sure the DB knows about the default log server.
        log = client_pb2.CtLogMetadata()
        log.log_server = "log_server"
        self.db.add_log(log)
Example #10
0
    def setUp(self):
        if not FLAGS.verbose_tests:
            logging.disable(logging.CRITICAL)
        self.db = sqlite_log_db.SQLiteLogDB(
            sqlitecon.SQLiteConnectionManager(":memory:", keepalive=True))
        # We can't simply use DB in memory with keepalive True, because different
        # thread is writing to the database which results in an sqlite exception.
        self.cert_db = mock.MagicMock()

        self.state_keeper = InMemoryStateKeeper(
            copy.deepcopy(self._DEFAULT_STATE))
        self.verifier = mock.Mock()
        self.hasher = merkle.TreeHasher()

        # Make sure the DB knows about the default log server.
        log = client_pb2.CtLogMetadata()
        log.log_server = "log_server"
        self.db.add_log(log)
    def test_tree_inclusion_proof_generated(self):
        """Test inclusion proof generation.

        Test inclusion proof generation correctness for generated proofs.
        """
        leaves = []
        leaf_hashes = []
        hasher = merkle.TreeHasher()
        for i in range(128):
            leaves.append(chr(i) * 32)
            leaf_hashes.append(hasher.hash_leaf(leaves[-1]))

        tree = in_memory_merkle_tree.InMemoryMerkleTree(leaves)
        verifier = merkle.MerkleVerifier()

        for i in range(1, tree.tree_size()):
            for j in range(i):
                audit_path = tree.get_inclusion_proof(j, i)
                dummy_sth = DummySTH(i, tree.get_root_hash(i))
                verifier.verify_leaf_hash_inclusion(
                        leaf_hashes[j], j, audit_path, dummy_sth)
    def test_tree_inclusion_proof_precomputed(self):
        """Test inclusion proof generation.

        Test inclusion proof generation correctness test for known-good
        proofs.
        """
        tree = in_memory_merkle_tree.InMemoryMerkleTree(TEST_VECTOR_DATA)
        verifier = merkle.MerkleVerifier()
        for v in PRECOMPUTED_PATH_TEST_VECTORS:
            audit_path = tree.get_inclusion_proof(v.leaf, v.tree_size_snapshot)
            self.assertEqual(len(audit_path), v.path_length)
            self.assertEqual(audit_path, v.path)

            leaf_data = TEST_VECTOR_DATA[v.leaf]
            leaf_hash = merkle.TreeHasher().hash_leaf(leaf_data)
            dummy_sth = DummySTH(v.tree_size_snapshot,
                tree.get_root_hash(v.tree_size_snapshot))

            if v.tree_size_snapshot > 0:
                verifier.verify_leaf_hash_inclusion(
                        leaf_hash, v.leaf, audit_path, dummy_sth)
Example #13
0
    def __init__(self, ct_logs, db, temp_db_factory, monitor_state_dir):
        """Initialize from a CtLogs proto."""
        threading.Thread.__init__(self)

        self.__monitors = []
        self.__db = db
        for log in ct_logs.ctlog:
            if not log.log_server or not log.log_id or not log.public_key_info:
                raise RuntimeError("Cannot start monitor: log proto has "
                                   "missing or empty fields: %s" % log)
            client = log_client.LogClient(log.log_server)
            hasher = merkle.TreeHasher()
            verifier = verify.LogVerifier(log.public_key_info,
                                          merkle.MerkleVerifier(hasher))
            state_keeper = state.StateKeeper(FLAGS.monitor_state_dir + "/" +
                                             log.log_id)
            temp_db = temp_db_factory.create_storage(log.log_server)
            self.__monitors.append(
                monitor.Monitor(client, verifier, hasher, db, temp_db,
                                state_keeper))

        self.__last_update_start_time = 0
        self.__stopped = False
Example #14
0
 def __init__(self, leaves):
     """Start with the array of |leaves| provided."""
     self.__leaves = list(leaves)
     self.__hasher = merkle.TreeHasher()
 def __init__(self, hashfunc=hashlib.sha256):
     self.hasher = merkle.TreeHasher(hashfunc)
 def test_hash_full_tree_test_vector(self):
     hasher = merkle.TreeHasher()
     for i in xrange(len(TreeHasherTest.test_vector_leaves)):
         test_vector = TreeHasherTest.test_vector_leaves[:i+1]
         expected_hash = TreeHasherTest.test_vector_hashes[i].decode("hex")
         self.assertEqual(hasher.hash_full_tree(test_vector), expected_hash)
 def test_hash_full_empty(self):
     hasher = merkle.TreeHasher()
     for i in xrange(0, 5):
         self.assertEqual(hasher._hash_full("abcd", i, i)[0].encode("hex"),
                           TreeHasherTest.sha256_empty_hash)
 def test_hash_full_invalid_index(self):
     hasher = merkle.TreeHasher()
     self.assertRaises(IndexError, hasher._hash_full, "abcd", -5, -1)
     self.assertRaises(IndexError, hasher._hash_full, "abcd", -1, 1)
     self.assertRaises(IndexError, hasher._hash_full, "abcd", 1, 5)
     self.assertRaises(IndexError, hasher._hash_full, "abcd", 2, 1)
 def test_hash_children(self):
     hasher = merkle.TreeHasher()
     for left, right, val in  TreeHasherTest.sha256_nodes:
         self.assertEqual(hasher.hash_children(
             left.decode("hex"), right.decode("hex")).encode("hex"), val)
 def test_hash_leaves(self):
     hasher = merkle.TreeHasher()
     for leaf, val in TreeHasherTest.sha256_leaves:
         self.assertEqual(hasher.hash_leaf(leaf.decode("hex")).encode("hex"),
                          val)
 def test_empty_hash(self):
     hasher = merkle.TreeHasher()
     self.assertEqual(hasher.hash_empty().encode("hex"),
                      TreeHasherTest.sha256_empty_hash)