Example #1
0
def _submit_to_all_logs(log_list, certs_chain):
    """Submits the chain to all logs in log_list and validates SCTs."""
    log_id_to_verifier = _map_log_id_to_verifier(log_list)

    chain_der = [c.to_der() for c in certs_chain]
    raw_scts_for_cert = []
    for log_url in log_list.keys():
        res = _submit_to_single_log(log_url, chain_der)
        if res:
            raw_scts_for_cert.append(res)
        else:
            logging.info("No SCT from log %s", log_url)

    validated_scts = []
    for raw_sct in raw_scts_for_cert:
        key_id = raw_sct.id.key_id
        try:
            log_id_to_verifier[key_id].verify_sct(raw_sct, certs_chain)
            validated_scts.append(raw_sct)
        except error.SignatureError as err:
            logging.warning(
                    'Discarding SCT from log_id %s which does not validate: %s',
                    key_id.encode('hex'), err)
        except KeyError as err:
            logging.warning('Could not find CT log validator for log_id %s. '
                    'The log key for this log is probably misconfigured.',
                    key_id.encode('hex'))

    scts_for_cert = [tls_message.encode(proto_sct)
            for proto_sct in validated_scts
            if proto_sct]
    sct_list = client_pb2.SignedCertificateTimestampList()
    sct_list.sct_list.extend(scts_for_cert)
    return tls_message.encode(sct_list)
 def test_correctly_encodes_sct_list_one_sct(self):
     # Taken from the C++ serializer test, to ensure this encoder
     # produces results compatible with the C++ one.
     single_sct = ("0069616d617075626c69636b657973686174776f6669766573697864"
                   "696765737400000000000004d20000040300097369676e6174757265"
                   ).decode("hex")
     sct_list = client_pb2.SignedCertificateTimestampList()
     sct_list.sct_list.append(single_sct)
     encoded_sct_list = tls_message.encode(sct_list)
     self.assertEqual(encoded_sct_list[:4],
                      "003a0038".decode("hex"))
     self.assertEqual(encoded_sct_list[4:], single_sct)
def dump_sctlist(sct_list):
    """Prints the proto representation of the SCTs contained in sct_list.
       Arguments:
       sct_list the packed SignedCertificateTransparencyList structure.
    """
    tr = tls_message.TLSReader(sct_list)
    sctlist = client_pb2.SignedCertificateTimestampList()
    tr.read(sctlist)
    for s in sctlist.sct_list:
        sct = client_pb2.SignedCertificateTimestamp()
        tls_message.decode(s, sct)
        print(sct)
    def verify_embedded_scts(self, chain):
        """Extract and verify SCTs embedded in an X.509 certificate.

        Args:
            chain: list of cert.Certificate instances.

        Returns:
            List of (SignedCertificateTimestamp, bool) pairs, one for each SCT
                present in the certificate. The boolean is True if the
                corresponding SCT is valid, False otherwise.

        Raises:
            ct.crypto.error.EncodingError: failed to encode signature input,
                or decode the signature.
            ct.crypto.error.IncompleteChainError: the chain is empty.
        """

        try:
            leaf_cert = chain[0]
        except IndexError:
            raise error.IncompleteChainError(
                "Chain must contain leaf certificate.")

        scts_blob = leaf_cert.embedded_sct_list()
        if scts_blob is None:
            return []

        scts = client_pb2.SignedCertificateTimestampList()
        tls_message.decode(scts_blob, scts)

        result = []
        for sct_blob in scts.sct_list:
            sct = client_pb2.SignedCertificateTimestamp()
            tls_message.decode(sct_blob, sct)

            try:
                self.verify_sct(sct, chain)
                result.append((sct, True))
            except error.VerifyError:
                result.append((sct, False))

        return result
Example #5
0
    def test_correctly_encodes_sct_list_multiple_scts(self):
        first_sct = tls_message.encode(self._sct_proto)
        sct_proto_2 = client_pb2.SignedCertificateTimestamp()
        sct_proto_2.CopyFrom(self._sct_proto)
        sct_proto_2.timestamp = 1365427530000
        second_sct = tls_message.encode(sct_proto_2)

        sct_list = client_pb2.SignedCertificateTimestampList()
        sct_list.sct_list.extend([first_sct, second_sct])
        encoded_sct_list = tls_message.encode(sct_list)
        # First 2 bytes are list length prefix - 240 bytes in total
        # Next 2 bytes are the length of the first SCT: 118
        self.assertEqual(encoded_sct_list[:4], "00f00076".decode("hex"))
        first_sct_end = len(first_sct) + 4
        # The actual SCT
        self.assertEqual(encoded_sct_list[4:first_sct_end], first_sct)
        # Next 2 bytes are the length of the second SCT (118 again)
        self.assertEqual(encoded_sct_list[first_sct_end:first_sct_end + 2],
                         "0076".decode("hex"))
        # The 2nd SCT
        self.assertEqual(encoded_sct_list[first_sct_end + 2:], second_sct)