def process_entries(entry_queue, output_queue, match_callback):
    stopped = False
    total_processed = 0
    while not stopped:
        count, entry = entry_queue.get()
        if entry == _STOP_WORKER:
            stopped = True
            # Each worker signals when they've picked up their
            # "STOP_WORKER" message.
            output_queue.put(QueueMessage(
                _WORKER_STOPPED,
                certificates_scanned=total_processed))
        else:
            entry_response = client_pb2.EntryResponse()
            entry_response.ParseFromString(entry)
            parsed_entry = entry_decoder.decode_entry(entry_response)
            ts_entry = parsed_entry.merkle_leaf.timestamped_entry
            total_processed += 1
            c = None
            if ts_entry.entry_type == client_pb2.X509_ENTRY:
                der_cert = ts_entry.asn1_cert
            else:
                # The original, signed precertificate.
                der_cert = (parsed_entry.extra_data.precert_chain_entry.pre_certificate)
            try:
                c = cert.Certificate(der_cert)
            except error.Error as e:
                try:
                    c = cert.Certificate(der_cert, strict_der=False)
                except error.Error as e:
                    output_queue.put(QueueMessage(
                        _ERROR_PARSING_ENTRY,
                        "Error parsing entry %d:\n%s" %
                        (count, e)))
                else:
                    output_queue.put(QueueMessage(
                        _ERROR_PARSING_ENTRY,
                        "Entry %d failed strict parsing:\n%s" %
                        (count, c)))
            except Exception as e:
                print "Unknown parsing failure for entry %d:\n%s" % (
                    count, e)
                traceback.print_exc()
                output_queue.put(QueueMessage(
                    _ERROR_PARSING_ENTRY,
                    "Entry %d failed parsing with an unknown error:\n%s" %
                    (count, e)))
            if c:
                match_result = match_callback(
                        c, ts_entry.entry_type, parsed_entry.extra_data, count)
                if match_result:
                    output_queue.put(QueueMessage(
                            _ENTRY_MATCHING,
                            "Entry %d:\n%s" % (count, c),
                            matcher_output=match_result))
            if not total_processed % _BATCH_SIZE:
                output_queue.put(QueueMessage(
                    _PROGRESS_REPORT,
                    "Scanned %d entries" % total_processed,
                    certificates_scanned=_BATCH_SIZE))
def _scan_der_cert(der_certs, checks):
    current = -1
    try:
        result = []
        for log_index, der_cert, der_chain in der_certs:
            current = log_index
            partial_result = []
            strict_failure = False
            try:
                certificate = cert.Certificate(der_cert)
            except error.Error as e:
                try:
                    certificate = cert.Certificate(der_cert, strict_der=False)
                except error.Error as e:
                    partial_result.append(asn1.All())
                    strict_failure = True
                else:
                    if isinstance(e, error.ASN1IllegalCharacter):
                        partial_result.append(
                            asn1.Strict(reason=e.args[0],
                                        details=(e.string, e.index)))
                    else:
                        partial_result.append(asn1.Strict(reason=str(e)))
            if not strict_failure:
                for check in checks:
                    partial_result += check.check(certificate) or []
                desc = cert_desc.from_cert(certificate, partial_result)
            else:
                desc = certificate_pb2.X509Description()
                desc.der = der_cert
                desc.sha256_hash = hashlib.sha256(der_cert).digest()
            try:
                root = cert.Certificate(der_chain[-1], strict_der=False)
            except error.Error:
                pass
            else:
                for iss in [
                    (type_.short_name,
                     cert_desc.to_unicode('.'.join(
                         cert_desc.process_name(value.human_readable()))))
                        for type_, value in root.issuer()
                ]:
                    proto_iss = desc.root_issuer.add()
                    proto_iss.type, proto_iss.value = iss
            result.append((desc, log_index, partial_result))
        return result
    except Exception:
        _, exception, exception_traceback = sys.exc_info()
        exception_traceback = traceback.format_exc(exception_traceback)
        raise PoolException((exception, exception_traceback, der_certs[0][0],
                             der_certs[-1][0], current))
示例#3
0
    def test_issuer_and_root_issuer_populated_from_chain(self):
        self.assertEqual(3, len(CHAIN_DERS))

        report = self.CertificateReportBase()
        report.scan_der_certs([(0, CHAIN_DERS[0], CHAIN_DERS[1:],
                                client_pb2.X509_ENTRY)])
        results = report.report()
        self.assertEqual(len(results), 1)

        issuer_cert = cert_desc.from_cert(cert.Certificate(CHAIN_DERS[1]))
        root_cert = cert_desc.from_cert(cert.Certificate(CHAIN_DERS[2]))

        self.assertEqual(readable_dn(results[0].issuer),
                         'C=US,O=Google Inc,CN=Google Internet Authority')
        self.assertEqual(
            readable_dn(results[0].root_issuer),
            'C=US,O=Equifax,OU=Equifax Secure Certificate Authority')
示例#4
0
    def test_issuer_public_key_populated_from_chain(self):
        # Verify the test data is what is expected for this unit test.
        self.assertEqual(3, len(CHAIN_DERS))
        self.assertEqual(
            cert.Certificate(CHAIN_DERS[1]).key_hash(hashfunc="sha256").encode('hex'),
            'b6b95432abae57fe020cb2b74f4f9f9173c8c708afc9e732ace23279047c6d05')

        report = self.CertificateReportBase([])
        report.scan_der_certs([(0, CHAIN_DERS[0], CHAIN_DERS[1:],
                                client_pb2.X509_ENTRY)])
        result = report.report()
        self.assertEqual(len(sum(result.values(), [])), 0)

        certs = report.certs()
        self.assertEqual(len(certs), 1)
        self.assertEqual(certs[0].issuer_pk_sha256_hash.encode('hex'),
            'b6b95432abae57fe020cb2b74f4f9f9173c8c708afc9e732ace23279047c6d05')
 def test_to_der(self):
     with open(self.get_file(self._DER_FILE), "rb") as f:
         der_string = f.read()
     c = cert.Certificate(der_string)
     self.assertEqual(der_string, c.to_der())
示例#6
0
def _scan_der_cert(der_certs):
    current = -1
    result = []
    for log_index, der_cert, der_chain, entry_type in der_certs:
        try:
            current = log_index
            certificate = None
            strict_failure = False
            try:
                certificate = cert.Certificate(der_cert)
            except error.Error as e:
                try:
                    certificate = cert.Certificate(der_cert, strict_der=False)
                except error.Error as e:
                    strict_failure = True
            if not strict_failure:
                desc = cert_desc.from_cert(certificate)
            else:
                desc = certificate_pb2.X509Description()
                desc.der = der_cert
                desc.sha256_hash = hashlib.sha256(der_cert).digest()

            desc.entry_type = entry_type
            root = None

            if der_chain:
                try:
                    issuer = cert.Certificate(der_chain[0], strict_der=False)
                except error.Error:
                    pass
                else:
                    desc.issuer_pk_sha256_hash = issuer.key_hash(
                        hashfunc="sha256")

                try:
                    root = cert.Certificate(der_chain[-1], strict_der=False)
                except error.Error:
                    pass
            else:
                # No chain implies this is a root certificate.
                # Note that certificate may be None.
                root = certificate

            if root:
                for iss in [
                    (type_.short_name,
                     cert_desc.to_unicode('.'.join(
                         cert_desc.process_name(value.human_readable()))))
                        for type_, value in root.issuer()
                ]:
                    proto_iss = desc.root_issuer.add()
                    proto_iss.type, proto_iss.value = iss

            result.append((desc, log_index))
        except:
            batch_start_index, batch_end_index = (der_certs[0][0],
                                                  der_certs[-1][0])
            logging.exception(
                "Error scanning certificate %d in batch <%d, %d> - it will "
                "be excluded from the scan results", current,
                batch_start_index, batch_end_index)

    return result