Esempio n. 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 verify_sct(self, sct, chain):
        """Verify the SCT over the X.509 certificate provided

        Args:
            sct: client_pb2.SignedCertificateTimestamp proto. Must have
                all fields present.
            chain: list of cert.Certificate instances. Begins with the
                certificate to be checked.

        Returns:
            True. The return value is enforced by a decorator and need not be
                checked by the caller.

        Raises:
            ct.crypto.error.EncodingError: failed to encode signature input,
                or decode the signature.
            ct.crypto.error.SignatureError: invalid signature.
            ct.crypto.error.IncompleteChainError: a certificate is missing
                from the chain.
        """

        if sct.version != ct_pb2.V1:
            raise error.UnsupportedVersionError("Cannot handle version: %s" %
                                                sct.version)
        entry = _create_dst_entry(sct, chain)
        signature_input = tls_message.encode(entry)

        self._assert_correct_signature_algorithms(sct.signature.hash_algorithm,
                                                  sct.signature.sig_algorithm)

        return self.__sig_verifier.verify(signature_input,
                                          sct.signature.signature)
Esempio n. 3
0
    def verify_sct(self, sct, chain):
        """Verify the SCT over the X.509 certificate provided

        Args:
            sct: client_pb2.SignedCertificateTimestamp proto. Must have
                all fields present.
            chain: list of cert.Certificate instances. Begins with the
                certificate to be checked.

        Returns:
            True. The return value is enforced by a decorator and need not be
                checked by the caller.

        Raises:
            ct.crypto.error.EncodingError: failed to encode signature input,
                or decode the signature.
            ct.crypto.error.SignatureError: invalid signature.
            ct.crypto.error.IncompleteChainError: a certificate is missing
                from the chain.
        """

        if sct.version != ct_pb2.V1:
            raise error.UnsupportedVersionError("Cannot handle version: %s" %
                                                sct.version)
        entry = _create_dst_entry(sct, chain)
        signature_input = tls_message.encode(entry)

        return self._verify(signature_input, sct.signature.signature)
Esempio n. 4
0
    def verify_sct(self, sct, certificate):
        """Verify the SCT over the X.509 certificate provided

        Not suitable for Precertificates.

        Args:
            sct: client_pb2.SignedCertificateTimestamp proto. Must have
                all fields present.
            certificate: cert.Certificate instance.

        Returns:
            True. The return value is enforced by a decorator and need not be
                checked by the caller.

        Raises:
            ct.crypto.error.EncodingError: failed to encode signature input,
                or decode the signature.
            ct.crypto.error.SignatureError: invalid signature.
        """

        if sct.version != ct_pb2.V1:
            raise error.UnsupportedVersionError("Cannot handle version: %s" %
                                                sct.version)
        dsentry = client_pb2.DigitallySignedTimestampedEntry()
        dsentry.sct_version = ct_pb2.V1
        dsentry.signature_type = client_pb2.CERTIFICATE_TIMESTAMP
        dsentry.timestamp = sct.timestamp
        dsentry.entry_type = client_pb2.X509_ENTRY
        dsentry.asn1_cert = certificate.to_der()
        dsentry.ct_extensions = sct.extensions

        signature_input = tls_message.encode(dsentry)

        return self._verify(signature_input, sct.signature.signature)
    def verify_sct(self, sct, certificate):
        """Verify the SCT over the X.509 certificate provided

        Not suitable for Precertificates.

        Args:
            sct: client_pb2.SignedCertificateTimestamp proto. Must have
                all fields present.
            certificate: cert.Certificate instance.

        Returns:
            True. The return value is enforced by a decorator and need not be
                checked by the caller.

        Raises:
            ct.crypto.error.EncodingError: failed to encode signature input,
                or decode the signature.
            ct.crypto.error.SignatureError: invalid signature.
        """

        if sct.version != ct_pb2.V1:
            raise error.UnsupportedVersionError("Cannot handle version: %s" %
                                                sct.version)
        dsentry = client_pb2.DigitallySignedTimestampedEntry()
        dsentry.sct_version = ct_pb2.V1
        dsentry.signature_type = client_pb2.CERTIFICATE_TIMESTAMP
        dsentry.timestamp = sct.timestamp
        dsentry.entry_type = client_pb2.X509_ENTRY
        dsentry.asn1_cert = certificate.to_der()
        dsentry.ct_extensions = sct.extensions

        signature_input = tls_message.encode(dsentry)

        return self._verify(signature_input, sct.signature.signature)
 def test_correctly_encodes_sct(self):
     sct = tls_message.encode(self._sct_proto)
     expected_sct = ("00a4b90990b418581487bb13a2cc67700a3c359804f91bdfb8e377"
                     "cd0ec80ddc100000013de9d2b29b000004030047304502210089de"
                     "897f603e590b1aa0d7c4236c2f697e90602795f7a469215fda5e46"
                     "0123fc022065ab501ce3dbaf49bd563d1c9ff0ac76120bc11f65a4"
                     "4122b3cd8b89fc77a48c").decode("hex")
     self.assertEqual(sct, expected_sct)
 def test_correctly_encodes_sct(self):
     sct = tls_message.encode(self._sct_proto)
     expected_sct = ("00a4b90990b418581487bb13a2cc67700a3c359804f91bdfb8e377"
                     "cd0ec80ddc100000013de9d2b29b000004030047304502210089de"
                     "897f603e590b1aa0d7c4236c2f697e90602795f7a469215fda5e46"
                     "0123fc022065ab501ce3dbaf49bd563d1c9ff0ac76120bc11f65a4"
                     "4122b3cd8b89fc77a48c").decode("hex")
     self.assertEqual(sct, expected_sct)
def create_leaf(timestamp, x509_cert_bytes):
    """Creates a MerkleTreeLeaf for the given X509 certificate."""
    leaf = client_pb2.MerkleTreeLeaf()
    leaf.version = client_pb2.V1
    leaf.leaf_type = client_pb2.TIMESTAMPED_ENTRY
    leaf.timestamped_entry.timestamp = timestamp
    leaf.timestamped_entry.entry_type = client_pb2.X509_ENTRY
    leaf.timestamped_entry.asn1_cert = x509_cert_bytes
    return tls_message.encode(leaf)
def create_leaf(timestamp, x509_cert_bytes):
    """Creates a MerkleTreeLeaf for the given X509 certificate."""
    leaf = client_pb2.MerkleTreeLeaf()
    leaf.version = client_pb2.V1
    leaf.leaf_type = client_pb2.TIMESTAMPED_ENTRY
    leaf.timestamped_entry.timestamp = timestamp
    leaf.timestamped_entry.entry_type = client_pb2.X509_ENTRY
    leaf.timestamped_entry.asn1_cert = x509_cert_bytes
    return tls_message.encode(leaf)
 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)
Esempio n. 11
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)
 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 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)
 def verify_encode(self, test_message, test_vector):
     serialized = tls_message.encode(test_message)
     self.assertEqual("".join(test_vector), serialized.encode("hex"))
 def verify_encode(self, test_message, test_vector):
     serialized = tls_message.encode(test_message)
     self.assertEqual("".join(test_vector), serialized.encode("hex"))