Beispiel #1
0
def check_revoked():
    """
    Function attempts to update Lemur's internal cache with revoked
    certificates. This is called periodically by Lemur. It checks both
    CRLs and OCSP to see if a certificate is revoked. If Lemur is unable
    encounters an issue with verification it marks the certificate status
    as `unknown`.
    """

    log_data = {
        "function": f"{__name__}.{sys._getframe().f_code.co_name}",
        "message": "Checking for revoked Certificates"
    }

    certs = get_all_valid_certs(
        current_app.config.get("SUPPORTED_REVOCATION_AUTHORITY_PLUGINS", []))
    for cert in certs:
        try:
            if cert.chain:
                status = verify_string(cert.body, cert.chain)
            elif cert.issuer == '<selfsigned>':
                status = True
            else:
                status = verify_string(cert.body, "")

            cert.status = "valid" if status else "revoked"

            if cert.status == "revoked":
                log_data["valid"] = cert.status
                log_data["certificate_name"] = cert.name
                log_data["certificate_id"] = cert.id
                metrics.send(
                    "certificate_revoked",
                    "counter",
                    1,
                    metric_tags={
                        "status": log_data["valid"],
                        "certificate_name": log_data["certificate_name"],
                        "certificate_id": log_data["certificate_id"]
                    },
                )
                current_app.logger.info(log_data)

        except Exception as e:
            sentry.captureException()
            current_app.logger.exception(e)
            cert.status = "unknown"

        database.update(cert)
Beispiel #2
0
def create_certificate_check_destination_tasks():
    """
    This celery task fetches all (certificate, destination) pairs
    from Lemur and creates subtasks to verify that the certificate has
    been uploaded.
    :return:
    """
    function = f"{__name__}.{sys._getframe().f_code.co_name}"
    logger = logging.getLogger(function)
    task_id = None
    if celery.current_task:
        task_id = celery.current_task.request.id

    log_data = {
        "task_id": task_id,
    }

    if task_id and is_task_active(function, task_id, None):
        logger.debug("Skipping task: Task is already active", extra=log_data)
        return log_data

    certs = certificate_service.get_all_valid_certs([])
    num_subtasks_created = 0
    for cert in certs:
        if cert.replaced or len(cert.destinations) == 0:
            continue

        for dest in cert.destinations:
            logger.debug(
                "creating sub task to check certificate/destination pair",
                extra={
                    "certificate": cert.name,
                    "destination": str(dest),
                },
            )
            certificate_check_destination.delay(cert.id, dest.id)
            num_subtasks_created += 1

    logger.debug(
        "task creation completed",
        extra={
            **log_data, "num_subtasks_created": num_subtasks_created
        },
    )
    return log_data
Beispiel #3
0
def deactivate_entrust_certificates():
    """
    Attempt to deactivate test certificates issued by Entrust
    """

    log_data = {
        "function": f"{__name__}.{sys._getframe().f_code.co_name}",
        "message": "Deactivating Entrust certificates"
    }

    certificates = get_all_valid_certs(['entrust-issuer'])
    entrust_plugin = plugins.get('entrust-issuer')
    for index, cert in enumerate(certificates):
        if (index % 10) == 0:
            # Entrust enforces a 10 request per 30s rate limit
            sleep(30)
        try:
            response = entrust_plugin.deactivate_certificate(cert)
            if response == 200:
                cert.status = "revoked"
            else:
                cert.status = "unknown"

            log_data["valid"] = cert.status
            log_data["certificate_name"] = cert.name
            log_data["certificate_id"] = cert.id
            metrics.send(
                "certificate_deactivate",
                "counter",
                1,
                metric_tags={
                    "status": log_data["valid"],
                    "certificate_name": log_data["certificate_name"],
                    "certificate_id": log_data["certificate_id"]
                },
            )
            current_app.logger.info(log_data)

            database.update(cert)

        except Exception as e:
            current_app.logger.info(log_data)
            sentry.captureException()
            current_app.logger.exception(e)
Beispiel #4
0
def check_revoked():
    """
    Function attempts to update Lemur's internal cache with revoked
    certificates. This is called periodically by Lemur. It checks both
    CRLs and OCSP to see if a certificate is revoked. If Lemur is unable
    encounters an issue with verification it marks the certificate status
    as `unknown`.
    """

    log_data = {
        "function": f"{__name__}.{sys._getframe().f_code.co_name}",
        "message": "Checking for revoked Certificates"
    }
    there_are_still_certs = True
    page = 1
    count = 1000
    ocsp_err_count = 0
    crl_err_count = 0
    while there_are_still_certs:
        # get all valid certs issued until day before. This is to avoid OCSP not knowing about a newly created cert.
        certs = get_all_valid_certs(
            current_app.config.get("SUPPORTED_REVOCATION_AUTHORITY_PLUGINS",
                                   []),
            paginate=True,
            page=page,
            count=count,
            created_on_or_before=arrow.now().shift(days=-1))
        if len(certs) < count:
            # this must be tha last page
            there_are_still_certs = False
        else:
            metrics.send("certificate_revoked_progress",
                         "counter",
                         1,
                         metric_tags={"page": page})
            page += 1

        for cert in certs:
            try:
                if cert.chain:
                    status, ocsp_err, crl_err = verify_string(
                        cert.body, cert.chain)
                else:
                    status, ocsp_err, crl_err = verify_string(cert.body, "")

                ocsp_err_count += ocsp_err
                crl_err_count += crl_err

                if status is None:
                    cert.status = "unknown"
                else:
                    cert.status = "valid" if status else "revoked"

                if cert.status == "revoked":
                    log_data["valid"] = cert.status
                    log_data["certificate_name"] = cert.name
                    log_data["certificate_id"] = cert.id
                    metrics.send(
                        "certificate_revoked",
                        "counter",
                        1,
                        metric_tags={
                            "status": log_data["valid"],
                            "certificate_name": log_data["certificate_name"],
                            "certificate_id": log_data["certificate_id"]
                        },
                    )
                    current_app.logger.info(log_data)

            except Exception as e:
                capture_exception()
                current_app.logger.warning(e)
                cert.status = "unknown"

            try:
                database.update(cert)
            except Exception as e:
                capture_exception()
                current_app.logger.warning(e)

    metrics.send(
        "certificate_revoked_ocsp_error",
        "gauge",
        ocsp_err_count,
    )
    metrics.send(
        "certificate_revoked_crl_error",
        "gauge",
        crl_err_count,
    )
    metrics.send(
        "certificate_revoked_checked",
        "gauge",
        (page - 1) * count + len(certs),
    )