Example #1
0
def validate_revocation_certificate_chain(chain, error_messages):
    # a failed try to use ocsp validation
    for i in range(1, len(chain)):
        subject = chain[i - 1]
        issuer = chain[i]
        builder = ocsp.OCSPRequestBuilder()

        builder = builder.add_certificate(subject, issuer, SHA1())
        req = builder.build()
        data = req.public_bytes(serialization.Encoding.DER)

        for e in subject.extensions:

            if isinstance(e.value, AuthorityInformationAccess):
                url = e.value._descriptions[0].access_location.value
                print(url)
                headers = {"Content-Type": "application/ocsp-request"}
                r = requests.post(url, data=data, headers=headers)
                ocsp_resp = ocsp.load_der_ocsp_response(r.content)
                print(ocsp_resp.certificate_status)

                if ocsp_resp.response_status == ocsp.OCSPResponseStatus.SUCCESSFUL:
                    if ocsp_resp.certificate_status == ocsp.OCSPCertStatus.UNKNOWN:
                        status = validate_revocation_certificate_chain_crl(
                            [subject, issuer], error_messages)
                        if not status:
                            return False
                    elif ocsp_resp.certificate_status == ocsp.OCSPCertStatus.REVOKED:
                        error_messages.append(
                            "One of the certificates is revoked")
                        return False
                else:
                    return False
    return True
Example #2
0
def extract_ocsp_result(ocsp_response):
    """Extract the OCSP result from the provided ocsp_response"""

    func_name: str = "extract_ocsp_result"

    try:
        ocsp_response = ocsp.load_der_ocsp_response(ocsp_response.content)
        # OCSP Response Status here:
        # https://cryptography.io/en/latest/_modules/cryptography/x509/ocsp/#OCSPResponseStatus
        # A status of 0 == OCSPResponseStatus.SUCCESSFUL
        if str(ocsp_response.response_status.value) != "0":
            # This will return one of five errors, which means connecting
            # to the OCSP Responder failed for one of the below reasons:
            # MALFORMED_REQUEST = 1
            # INTERNAL_ERROR = 2
            # TRY_LATER = 3
            # SIG_REQUIRED = 5
            # UNAUTHORIZED = 6
            ocsp_response = str(ocsp_response.response_status)
            ocsp_response = ocsp_response.split(".")
            raise Exception(
                f"{func_name}: OCSP Request Error: {ocsp_response[1]}")

        certificate_status = str(ocsp_response.certificate_status)
        certificate_status = certificate_status.split(".")
        return f"OCSP Status: {certificate_status[1]}"

    except ValueError as err:
        return f"{func_name}: {str(err)}"
Example #3
0
    def check_certificate(self, server, cert, issuer_url):
        """Checks the validitity of an ocsp server for an issuer"""

        r = requests.get(issuer_url)
        if not r.ok:
            raise ConnectionError("failed to fetch issuer certificate")
        der = r.content
        issuer_cert = self._bin2ascii(der)

        ocsp_url = self.build_certificate_url(server, cert, issuer_cert)

        # HTTP 1.1 mandates the addition of the Host header in ocsp responses
        header = {
            "Host": urlparse(ocsp_url).netloc,
            "Content-Type": "application/ocsp-request",
        }
        r = requests.get(ocsp_url, headers=header)
        if not r.ok:
            raise ConnectionError("failed to fetch ocsp certificate")

        ocsp_response = ocsp.load_der_ocsp_response(r.content)
        if ocsp_response.response_status == ocsp.OCSPResponseStatus.UNAUTHORIZED:
            raise AuthorizationError(
                "you are not authorized to view this ocsp certificate")
        if ocsp_response.response_status == ocsp.OCSPResponseStatus.SUCCESSFUL:
            if ocsp_response.certificate_status == ocsp.OCSPCertStatus.REVOKED:
                return False
            else:
                return True
        else:
            return False
 def test_serialize_reponse(self):
     resp_bytes = load_vectors_from_file(filename=os.path.join(
         "x509", "ocsp", "resp-revoked.der"),
                                         loader=lambda data: data.read(),
                                         mode="rb")
     resp = ocsp.load_der_ocsp_response(resp_bytes)
     assert resp.public_bytes(serialization.Encoding.DER) == resp_bytes
Example #5
0
 def test_serialize_reponse(self):
     resp_bytes = load_vectors_from_file(
         filename=os.path.join("x509", "ocsp", "resp-revoked.der"),
         loader=lambda data: data.read(),
         mode="rb"
     )
     resp = ocsp.load_der_ocsp_response(resp_bytes)
     assert resp.public_bytes(serialization.Encoding.DER) == resp_bytes
Example #6
0
def _check_ocsp_cryptography(cert_path: str, chain_path: str, url: str,
                             timeout: int) -> bool:
    # Retrieve OCSP response
    with open(chain_path, 'rb') as file_handler:
        issuer = x509.load_pem_x509_certificate(file_handler.read(),
                                                default_backend())
    with open(cert_path, 'rb') as file_handler:
        cert = x509.load_pem_x509_certificate(file_handler.read(),
                                              default_backend())
    builder = ocsp.OCSPRequestBuilder()
    builder = builder.add_certificate(cert, issuer, hashes.SHA1())
    request = builder.build()
    request_binary = request.public_bytes(serialization.Encoding.DER)
    try:
        response = requests.post(
            url,
            data=request_binary,
            headers={'Content-Type': 'application/ocsp-request'},
            timeout=timeout)
    except requests.exceptions.RequestException:
        logger.info("OCSP check failed for %s (are we offline?)",
                    cert_path,
                    exc_info=True)
        return False
    if response.status_code != 200:
        logger.info("OCSP check failed for %s (HTTP status: %d)", cert_path,
                    response.status_code)
        return False

    response_ocsp = ocsp.load_der_ocsp_response(response.content)

    # Check OCSP response validity
    if response_ocsp.response_status != ocsp.OCSPResponseStatus.SUCCESSFUL:
        logger.warning("Invalid OCSP response status for %s: %s", cert_path,
                       response_ocsp.response_status)
        return False

    # Check OCSP signature
    try:
        _check_ocsp_response(response_ocsp, request, issuer, cert_path)
    except UnsupportedAlgorithm as e:
        logger.warning(str(e))
    except errors.Error as e:
        logger.warning(str(e))
    except InvalidSignature:
        logger.warning('Invalid signature on OCSP response for %s', cert_path)
    except AssertionError as error:
        logger.warning('Invalid OCSP response for %s: %s.', cert_path,
                       str(error))
    else:
        # Check OCSP certificate status
        logger.debug("OCSP certificate status for %s is: %s", cert_path,
                     response_ocsp.certificate_status)
        return response_ocsp.certificate_status == ocsp.OCSPCertStatus.REVOKED

    return False
Example #7
0
def _check_certificate(issuer_cert, ocsp_bytes, validate=True):
    """A wrapper the return the validity of a known ocsp certificate"""

    ocsp_response = ocsp.load_der_ocsp_response(ocsp_bytes)

    if ocsp_response.response_status == ocsp.OCSPResponseStatus.UNAUTHORIZED:
        raise AuthorizationError(
            "you are not authorized to view this ocsp certificate")
    if ocsp_response.response_status == ocsp.OCSPResponseStatus.SUCCESSFUL:
        if ocsp_response.certificate_status != ocsp.OCSPCertStatus.GOOD:
            raise ConnectionError(
                f'Received an {str(ocsp_response.certificate_status).split(".")[1]} '
                "ocsp certificate status")
    else:
        raise ConnectionError(
            "failed to retrieve a sucessful response from the ocsp responder")

    if ocsp_response.this_update >= datetime.datetime.now():
        raise ConnectionError("ocsp certificate was issued in the future")

    if (ocsp_response.next_update
            and ocsp_response.next_update < datetime.datetime.now()):
        raise ConnectionError(
            "ocsp certificate has invalid update - in the past")

    responder_name = ocsp_response.responder_name
    issuer_hash = ocsp_response.issuer_key_hash
    responder_hash = ocsp_response.responder_key_hash

    cert_to_validate = issuer_cert
    if (responder_name is not None and responder_name == issuer_cert.subject
            or responder_hash == issuer_hash):
        cert_to_validate = issuer_cert
    else:
        certs = ocsp_response.certificates
        responder_certs = _get_certificates(certs, issuer_cert, responder_name,
                                            responder_hash)

        try:
            responder_cert = responder_certs[0]
        except IndexError:
            raise ConnectionError("no certificates found for the responder")

        ext = responder_cert.extensions.get_extension_for_class(
            x509.ExtendedKeyUsage)
        if ext is None or x509.oid.ExtendedKeyUsageOID.OCSP_SIGNING not in ext.value:
            raise ConnectionError("delegate not autorized for ocsp signing")
        cert_to_validate = responder_cert

    if validate:
        _verify_response(cert_to_validate, ocsp_response)
    return True
Example #8
0
def is_ocsp_valid(cert, issuer, hash_algo):
    if hash_algo == 'sha1':
        algorithm = hashes.SHA1
    elif hash_algo == 'sha224':
        algorithm = hashes.SHA224
    elif hash_algo == 'sha256':
        algorithm = hashes.SHA256
    elif hash_algo == 'sha385':
        algorithm = hashes.SHA384
    elif hash_algo == 'sha512':
        algorithm = hashes.SHA512
    else:
        log("Invalid hash algorithm '{}' used for OCSP validation. Validation ignored."
            .format(hash_algo),
            warning=True)
        return True

    if isinstance(issuer, list):
        issuer = issuer[
            0]  # First certificate in the CA chain is the immediate issuer

    try:
        ocsp_urls = []
        aia = cert.extensions.get_extension_for_oid(
            ExtensionOID.AUTHORITY_INFORMATION_ACCESS)
        for data in aia.value:
            if data.access_method == x509.OID_OCSP:
                ocsp_urls.append(data.access_location.value)

        # This is a bit of a hack due to validation problems within cryptography (TODO: Check if this is still true)
        # Correct replacement:  ocsprequest = ocsp.OCSPRequestBuilder().add_certificate(cert, issuer, algorithm).build()
        ocsprequest = ocsp.OCSPRequestBuilder(
            (cert, issuer, algorithm)).build()
        ocsprequestdata = ocsprequest.public_bytes(serialization.Encoding.DER)
        for ocsp_url in ocsp_urls:
            response = get_url(
                ocsp_url, ocsprequestdata, {
                    'Accept': 'application/ocsp-response',
                    'Content-Type': 'application/ocsp-request',
                })
            ocspresponsedata = response.read()
            ocspresponse = ocsp.load_der_ocsp_response(ocspresponsedata)
            if ocspresponse.response_status == ocsp.OCSPResponseStatus.SUCCESSFUL \
                    and ocspresponse.certificate_status == ocsp.OCSPCertStatus.REVOKED:
                return False
    except Exception as e:
        log("An exception occurred during OCSP validation (Validation will be ignored): {}"
            .format(e),
            error=True)

    return True
Example #9
0
def validate_revogation_status(cert):

    # check certificate revogation list
    # TODO: add more types of dist points
    print(cert.extensions)
    try:
        for j in cert.extensions.get_extension_for_class(x509.AuthorityInformationAccess).value:
            if j.access_method.dotted_string == "1.3.6.1.5.5.7.48.1": 
                rev_list=None

                #Downloading list
                print(j.access_location.value)
                file_name=wget.download(j.access_location.value)

                #Load ocsp response
                with open(file_name, "rb") as pem_file:
                    pem_data = pem_file.read()
                ocsp_resp = ocsp.load_der_ocsp_response(pem_data)

                print(ocsp_resp.response_status)
    except:
        print("OCSP not available.")



    try:
        for i in cert.extensions.get_extension_for_class(x509.CRLDistributionPoints).value:
            for b in i.full_name:
                file_name=b.value.split('/')[-1]
                rev_list=None
                #Downloading list
                print(wget.download(b.value))

                #read revocation list
                try:
                    rev_list=load_cert_revocation_list(file_name,"pem")
                except:
                    print("Not pem.")
                try:
                    rev_list=load_cert_revocation_list(file_name,"der")
                except:
                    print("Not der.")
                print(rev_list)
                if rev_list is None:
                    return False
                
                return cert.serial_number in [l.serial_number for l in rev_list]
    except:
        print("CRL not available.")
        return False
Example #10
0
def validate_chain(cert_to_check,issuer_cert):
    cert_to_check_signature=cert_to_check.signature
    issuer_public_key=issuer_cert.public_key()
    
    # TODO check if host has the same name I think
    builder = ocsp.OCSPRequestBuilder()
    # SHA1 is in this example because RFC 5019 mandates its use.
    builder = builder.add_certificate(cert_to_check, issuer_cert, SHA1())
    req = builder.build()

    for j in cert_to_check.extensions.get_extension_for_class(x509.AuthorityInformationAccess).value:
        if j.access_method.dotted_string == "1.3.6.1.5.5.7.48.1": 
            rev_list=None

            #Downloading list
            der=req.public_bytes(serialization.Encoding.DER)

            ocsp_link=j.access_location.value
            r=requests.post(ocsp_link,data=der)

            ocsp_resp = ocsp.load_der_ocsp_response(r.content)
            print(ocsp_resp.certificate_status)



                

    
    



    
    print(cert_to_check.extensions.get_extension_for_class(x509.KeyUsage).value)


    if (get_issuer_common_name(cert_to_check)!=get_common_name(issuer_cert)):
        print(get_issuer_common_name(cert_to_check))
        print(get_common_name(issuer_cert))
        return False 
        

    try:
        issuer_public_key.verify(cert_to_check_signature,cert_to_check.tbs_certificate_bytes,padding.PKCS1v15(),cert_to_check.signature_hash_algorithm)
    except:
        print("Failed to verify signature.")
        return False
    
    return True
Example #11
0
def get_ocsp_cert_status(ocsp_responder, cert, issuer_cert):
    encoded_req = get_oscp_request(cert, issuer_cert).public_bytes(
        serialization.Encoding.DER)
    ocsp_resp = requests.post(ocsp_responder, data=encoded_req)
    if ocsp_resp.ok:
        ocsp_decoded = ocsp.load_der_ocsp_response(ocsp_resp.content)
        if ocsp_decoded.response_status == OCSPResponseStatus.SUCCESSFUL:
            return ocsp_decoded.certificate_status
        else:
            raise Exception(
                f'Decoding ocsp response failed: {ocsp_decoded.response_status}'
            )
    raise Exception(
        f'Fetching ocsp cert status failed with response status: {ocsp_resp.status_code}'
    )
Example #12
0
def _check_ocsp_cryptography(cert_path, chain_path, url):
    # type: (str, str, str) -> bool
    # Retrieve OCSP response
    with open(chain_path, 'rb') as file_handler:
        issuer = x509.load_pem_x509_certificate(file_handler.read(), default_backend())
    with open(cert_path, 'rb') as file_handler:
        cert = x509.load_pem_x509_certificate(file_handler.read(), default_backend())
    builder = ocsp.OCSPRequestBuilder()
    builder = builder.add_certificate(cert, issuer, hashes.SHA1())
    request = builder.build()
    request_binary = request.public_bytes(serialization.Encoding.DER)
    try:
        response = requests.post(url, data=request_binary,
                                 headers={'Content-Type': 'application/ocsp-request'})
    except requests.exceptions.RequestException:
        logger.info("OCSP check failed for %s (are we offline?)", cert_path, exc_info=True)
        return False
    if response.status_code != 200:
        logger.info("OCSP check failed for %s (HTTP status: %d)", cert_path, response.status_code)
        return False

    response_ocsp = ocsp.load_der_ocsp_response(response.content)

    # Check OCSP response validity
    if response_ocsp.response_status != ocsp.OCSPResponseStatus.SUCCESSFUL:
        logger.error("Invalid OCSP response status for %s: %s",
                     cert_path, response_ocsp.response_status)
        return False

    # Check OCSP signature
    try:
        _check_ocsp_response(response_ocsp, request, issuer)
    except UnsupportedAlgorithm as e:
        logger.error(str(e))
    except errors.Error as e:
        logger.error(str(e))
    except InvalidSignature:
        logger.error('Invalid signature on OCSP response for %s', cert_path)
    except AssertionError as error:
        logger.error('Invalid OCSP response for %s: %s.', cert_path, str(error))
    else:
        # Check OCSP certificate status
        logger.debug("OCSP certificate status for %s is: %s",
                     cert_path, response_ocsp.certificate_status)
        return response_ocsp.certificate_status == ocsp.OCSPCertStatus.REVOKED

    return False
Example #13
0
 def callback(conn, encoded_ocsp, data):
     ocsp_resp = load_der_ocsp_response(encoded_ocsp)
     return ocsp_resp.response_status == OCSPResponseStatus.SUCCESSFUL and ocsp_resp.certificate_status == OCSPCertStatus.GOOD
def validate_revocation(cert, issuer):
    """
	Function used to check if a given certificate (or it's issuer) is revoked.
	:return: True, if it's revoked. False, otherwise.
	"""
    try:
        builder = ocsp.OCSPRequestBuilder()

        builder = builder.add_certificate(cert, issuer, SHA1())
        req = builder.build()

        for ext in cert.extensions.get_extension_for_class(
            x509.AuthorityInformationAccess
        ).value:
            if ext.access_method.dotted_string == "1.3.6.1.5.5.7.48.1":
                data = req.public_bytes(serialization.Encoding.DER)

                ocsp_url = ext.access_location.value
                request = requests.post(
                    ocsp_url,
                    headers={"Content-Type": "application/ocsp-request"},
                    data=data,
                )

                ocsp_resp = ocsp.load_der_ocsp_response(request.content)
                logger.warning(f"OCSP CERT STATUS: {ocsp_resp.certificate_status}")

                if (
                    ocsp_resp.certificate_status == ocsp.OCSPCertStatus.GOOD
                    or get_common_name(cert) == "ECRaizEstado"
                ):
                    return False
                else:
                    return True
    except:
        logger.debug("OCSP is not available for this certificate!")

    try:
        for ext in cert.extensions.get_extension_for_class(
            x509.CRLDistributionPoints
        ).value:
            for name in ext.full_name:
                file_name = wget.download(name.value)

                revocation_list = load_certificate_crl(file_name)

                if revocation_list is None:
                    return False

                cert_is_revoked = cert.serial_number in [
                    l.serial_number for l in revocation_list
                ]
        try:
            for ext in cert.extensions.get_extension_for_class(x509.FreshestCRL).value:
                for name in ext.full_name:
                    file_name = wget.download(name.value)

                    revocation_list = load_certificate_crl(file_name)

                    if revocation_list is None:
                        return False

                    cert_is_revoked = cert.serial_number in [
                        l.serial_number for l in revocation_list
                    ]
        except:
            logger.debug("DELTA CRL is not available for this certificate!")

        for ext in issuer.extensions.get_extension_for_class(
            x509.CRLDistributionPoints
        ).value:
            for name in ext.full_name:
                file_name = wget.download(name.value)

                revocation_list = load_certificate_crl(file_name)

                if revocation_list is None:
                    return False

                isser_is_revoked = issuer.serial_number in [
                    l.serial_number for l in revocation_list
                ]

        try:
            for ext in issuer.extensions.get_extension_for_class(
                x509.FreshestCRL
            ).value:
                for name in ext.full_name:
                    file_name = wget.download(name.value)

                    revocation_list = load_certificate_crl(file_name)

                    if revocation_list is None:
                        return False

                    isser_is_revoked = issuer.serial_number in [
                        l.serial_number for l in revocation_list
                    ]
        except:
            logger.debug("DELTA CRL is not available for this certificate!")

        return cert_is_revoked or isser_is_revoked
    except:
        logger.debug("CRL is not available for this certificate!")

    return True
Example #15
0
#!/bin/python3

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.hashes import SHA1
from cryptography.x509 import load_pem_x509_certificate, ocsp
import base64

#OCSP
cert1 = open("pubkey.crt", "r")
authority1 = open("pubkey.crt", "r")
cert = cert1.read().encode()
authority = authority1.read().encode()

certloader = load_pem_x509_certificate(cert, default_backend())
authorityloader = load_pem_x509_certificate(authority, default_backend())
builder = ocsp.OCSPRequestBuilder()

builder = builder.add_certificate(certloader, authorityloader, SHA1())
prereq = builder.build()

request = base64.b64encode(prereq.public_bytes(serialization.Encoding.DER))

#Load the request:
ocsp_req = ocsp.load_der_ocsp_request(request)
#E.g. show serial
print(ocsp_req.serial_number)

#Response
ocsp_resp = ocsp.load_der_ocsp_response(request)
Example #16
0
 def test_bad_response(self):
     with pytest.raises(ValueError):
         ocsp.load_der_ocsp_response(b"invalid")
    def perform(self) -> CertificateDeploymentAnalysisResult:
        received_certificate_chain = [
            load_pem_x509_certificate(pem_cert.encode("ascii"),
                                      backend=default_backend())
            for pem_cert in self.server_certificate_chain_as_pem
        ]
        leaf_cert = received_certificate_chain[0]

        # OCSP Must-Staple
        has_ocsp_must_staple = False
        try:
            tls_feature_ext = cast(
                cryptography.x509.TLSFeature,
                leaf_cert.extensions.get_extension_for_oid(
                    ExtensionOID.TLS_FEATURE))
            for feature_type in tls_feature_ext.value:
                if feature_type == cryptography.x509.TLSFeatureType.status_request:
                    has_ocsp_must_staple = True
                    break
        except ExtensionNotFound:
            pass

        # Received chain order
        is_chain_order_valid = True
        previous_issuer = None
        for index, cert in enumerate(received_certificate_chain):
            current_subject = cert.subject

            if index > 0:
                # Compare the current subject with the previous issuer in the chain
                if current_subject != previous_issuer:
                    is_chain_order_valid = False
                    break
            try:
                previous_issuer = cert.issuer
            except KeyError:
                # Missing issuer; this is okay if this is the last cert
                previous_issuer = None

        # Check if the leaf certificate is Extended Validation
        is_leaf_certificate_ev = False
        for trust_store in self.trust_stores_for_validation:
            if trust_store.ev_oids is None:
                # We only have the EV OIDs for Mozilla - skip other stores
                continue

            is_leaf_certificate_ev = trust_store.is_certificate_extended_validation(
                leaf_cert)

        # Check for Signed Timestamps
        number_of_scts: Optional[int] = 0
        try:
            # Look for the x509 extension
            sct_ext = leaf_cert.extensions.get_extension_for_oid(
                ExtensionOID.PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS)
            if isinstance(sct_ext.value,
                          cryptography.x509.UnrecognizedExtension):
                # The version of OpenSSL on the system is too old and can't parse the SCT extension
                number_of_scts = None

            # Count the number of entries in the extension
            sct_ext_value = cast(
                cryptography.x509.PrecertificateSignedCertificateTimestamps,
                sct_ext.value)
            number_of_scts = len(sct_ext_value)
        except ExtensionNotFound:
            pass

        # Try to generate the verified certificate chain using each trust store
        all_path_validation_results = []
        for trust_store in self.trust_stores_for_validation:
            path_validation_result = _verify_certificate_chain(
                self.server_certificate_chain_as_pem, trust_store)
            all_path_validation_results.append(path_validation_result)

        # Keep one trust store that was able to build the verified chain to then run additional checks
        trust_store_that_can_build_verified_chain = None
        verified_certificate_chain = None

        # But first tort the path validation results so the same trust_store always get picked for a given server
        def sort_function(path_validation: PathValidationResult) -> str:
            return path_validation.trust_store.name.lower()

        all_path_validation_results.sort(key=sort_function)

        # Then keep a trust store with a verified chain
        for path_validation_result in all_path_validation_results:
            if path_validation_result.was_validation_successful:
                trust_store_that_can_build_verified_chain = path_validation_result.trust_store
                verified_certificate_chain = path_validation_result.verified_certificate_chain
                break

        # Check if the anchor was sent by the server
        has_anchor_in_certificate_chain = None
        if verified_certificate_chain:
            has_anchor_in_certificate_chain = verified_certificate_chain[
                -1] in received_certificate_chain

        # Check if a SHA1-signed certificate is in the chain
        # Root certificates can still be signed with SHA1 so we only check leaf and intermediate certificates
        has_sha1_in_certificate_chain = None
        if verified_certificate_chain:
            has_sha1_in_certificate_chain = False
            for cert in verified_certificate_chain[:-1]:
                if isinstance(cert.signature_hash_algorithm, hashes.SHA1):
                    has_sha1_in_certificate_chain = True
                    break

        # Check if this is a distrusted Symantec-issued chain
        verified_chain_has_legacy_symantec_anchor = None
        if verified_certificate_chain:
            symantec_distrust_timeline = SymantecDistructTester.get_distrust_timeline(
                verified_certificate_chain)
            verified_chain_has_legacy_symantec_anchor = True if symantec_distrust_timeline else False

        # Check the OCSP response if there is one
        is_ocsp_response_trusted = None
        final_ocsp_response = None
        if self.server_ocsp_response:
            # Parse the OCSP response returned by nassl
            final_ocsp_response = load_der_ocsp_response(
                self.server_ocsp_response.as_der_bytes())

            # Check if the OCSP response is trusted
            if (trust_store_that_can_build_verified_chain
                    and final_ocsp_response.response_status
                    == OCSPResponseStatus.SUCCESSFUL):
                try:
                    nassl.ocsp_response.verify_ocsp_response(
                        self.server_ocsp_response,
                        trust_store_that_can_build_verified_chain.path)
                    is_ocsp_response_trusted = True
                except nassl.ocsp_response.OcspResponseNotTrustedError:
                    is_ocsp_response_trusted = False

        # All done
        return CertificateDeploymentAnalysisResult(
            received_certificate_chain=received_certificate_chain,
            leaf_certificate_subject_matches_hostname=
            _certificate_matches_hostname(leaf_cert, self.server_hostname),
            leaf_certificate_has_must_staple_extension=has_ocsp_must_staple,
            leaf_certificate_is_ev=is_leaf_certificate_ev,
            leaf_certificate_signed_certificate_timestamps_count=number_of_scts,
            received_chain_contains_anchor_certificate=
            has_anchor_in_certificate_chain,
            received_chain_has_valid_order=is_chain_order_valid,
            verified_chain_has_sha1_signature=has_sha1_in_certificate_chain,
            verified_chain_has_legacy_symantec_anchor=
            verified_chain_has_legacy_symantec_anchor,
            path_validation_results=all_path_validation_results,
            ocsp_response=final_ocsp_response,
            ocsp_response_is_trusted=is_ocsp_response_trusted,
        )
Example #18
0
 def _deepcopy_method_for_ocsp_response(inner_self: _OCSPResponse, memo: str) -> _OCSPResponse:
     return load_der_ocsp_response(inner_self.public_bytes(Encoding.DER))
Example #19
0
 def test_bad_response(self):
     with pytest.raises(ValueError):
         ocsp.load_der_ocsp_response(b"invalid")
Example #20
0
    def validate_revocation(self, cert_to_check, issuer_cert):

        try:
            builder = ocsp.OCSPRequestBuilder()

            builder = builder.add_certificate(cert_to_check, issuer_cert,
                                              SHA1())
            req = builder.build()
            for j in cert_to_check.extensions.get_extension_for_class(
                    x509.AuthorityInformationAccess).value:
                if j.access_method.dotted_string == "1.3.6.1.5.5.7.48.1":
                    rev_list = None

                    #Downloading list
                    der = req.public_bytes(serialization.Encoding.DER)

                    ocsp_link = j.access_location.value
                    r = requests.post(
                        ocsp_link,
                        headers={'Content-Type': 'application/ocsp-request'},
                        data=der)

                    ocsp_resp = ocsp.load_der_ocsp_response(r.content)
                    if ocsp_resp.certificate_status == ocsp.OCSPCertStatus.GOOD:
                        return False
                    else:
                        return True

        except Exception as e:
            logger.debug("OCSP not available")

        try:
            for i in cert_to_check.extensions.get_extension_for_class(
                    x509.CRLDistributionPoints).value:
                for b in i.full_name:
                    rev_list = None
                    #Downloading list
                    file_name = wget.download(b.value)
                    print()
                    #read revocation list
                    try:
                        rev_list = self.load_cert_revocation_list(
                            file_name, "pem")
                    except Exception as e:
                        logger.debug(e)
                    try:
                        rev_list = self.load_cert_revocation_list(
                            file_name, "der")
                    except:
                        logger.debug("Not der.")
                    if rev_list is None:
                        return False

                    flag = cert_to_check.serial_number in [
                        l.serial_number for l in rev_list
                    ]
            try:
                for i in cert_to_check.extensions.get_extension_for_class(
                        x509.FreshestCRL).value:
                    for b in i.full_name:
                        rev_list = None
                        #Downloading list
                        file_name = wget.download(b.value)
                        #read revocation list
                        try:
                            rev_list = self.load_cert_revocation_list(
                                file_name, "pem")
                        except Exception as e:
                            logger.debug(e)
                        try:
                            rev_list = self.load_cert_revocation_list(
                                file_name, "der")
                        except:
                            logger.debug("Not der.")
                        if rev_list is None:
                            return False

                        flag = cert_to_check.serial_number in [
                            l.serial_number for l in rev_list
                        ]
            except:
                logger.debug("DELTA CRL not available.")

            for i in issuer_cert.extensions.get_extension_for_class(
                    x509.CRLDistributionPoints).value:
                for b in i.full_name:
                    rev_list = None
                    #Downloading list
                    file_name = wget.download(b.value)
                    print()

                    #read revocation list
                    try:
                        rev_list = self.load_cert_revocation_list(
                            file_name, "pem")
                    except Exception as e:
                        logger.debug(e)

                    try:
                        rev_list = self.load_cert_revocation_list(
                            file_name, "der")
                    except:
                        logger.debug("Not der.")
                    if rev_list is None:
                        return False

                    flag1 = issuer_cert.serial_number in [
                        l.serial_number for l in rev_list
                    ]

                    return flag1 or flag

            try:
                for i in issuer_cert.extensions.get_extension_for_class(
                        x509.FreshestCRL).value:
                    for b in i.full_name:
                        rev_list = None
                        #Downloading list
                        file_name = wget.download(b.value)

                        #read revocation list
                        try:
                            rev_list = self.load_cert_revocation_list(
                                file_name, "pem")
                        except Exception as e:
                            logger.debug(e)

                        try:
                            rev_list = self.load_cert_revocation_list(
                                file_name, "der")
                        except:
                            logger.debug("Not der.")
                        if rev_list is None:
                            return False

                        flag1 = issuer_cert.serial_number in [
                            l.serial_number for l in rev_list
                        ]

            except:
                logger.debug("DELTA CRL not available.")
            return flag1 or flag

        except Exception as e:
            logger.debug("CRL not available")

        return True