Пример #1
0
 def test_iri_to_uri(self):
     self.assertEqual(
         b'ldap://ldap.e-szigno.hu/CN=Microsec%20e-Szigno%20Root%20CA,OU=e-Szigno%20CA,'
         b'O=Microsec%20Ltd.,L=Budapest,C=HU?certificateRevocationList;binary',
         util.iri_to_uri(
             'ldap://ldap.e-szigno.hu/CN=Microsec e-Szigno Root CA,'
             'OU=e-Szigno CA,O=Microsec Ltd.,L=Budapest,C=HU?certificateRevocationList;binary'
         )
     )
     self.assertEqual(
         b'ldap://directory.d-trust.net/CN=D-TRUST%20Root%20Class%203%20CA%202%202009,'
         b'O=D-Trust%20GmbH,C=DE?certificaterevocationlist',
         util.iri_to_uri(
             'ldap://directory.d-trust.net/CN=D-TRUST Root Class 3 CA 2 2009,'
             'O=D-Trust GmbH,C=DE?certificaterevocationlist'
         )
     )
     self.assertEqual(
         b'ldap://directory.d-trust.net/CN=D-TRUST%20Root%20Class%203%20CA%202%20EV%202009,'
         b'O=D-Trust%20GmbH,C=DE?certificaterevocationlist',
         util.iri_to_uri(
             'ldap://directory.d-trust.net/CN=D-TRUST Root Class 3 CA 2 EV 2009,'
             'O=D-Trust GmbH,C=DE?certificaterevocationlist'
         )
     )
Пример #2
0
 def test_iri_to_uri(self):
     self.assertEqual(
         b'ldap://ldap.e-szigno.hu/CN=Microsec%20e-Szigno%20Root%20CA,OU=e-Szigno%20CA,'
         b'O=Microsec%20Ltd.,L=Budapest,C=HU?certificateRevocationList;binary',
         util.iri_to_uri(
             'ldap://ldap.e-szigno.hu/CN=Microsec e-Szigno Root CA,'
             'OU=e-Szigno CA,O=Microsec Ltd.,L=Budapest,C=HU?certificateRevocationList;binary'
         )
     )
     self.assertEqual(
         b'ldap://directory.d-trust.net/CN=D-TRUST%20Root%20Class%203%20CA%202%202009,'
         b'O=D-Trust%20GmbH,C=DE?certificaterevocationlist',
         util.iri_to_uri(
             'ldap://directory.d-trust.net/CN=D-TRUST Root Class 3 CA 2 2009,'
             'O=D-Trust GmbH,C=DE?certificaterevocationlist'
         )
     )
     self.assertEqual(
         b'ldap://directory.d-trust.net/CN=D-TRUST%20Root%20Class%203%20CA%202%20EV%202009,'
         b'O=D-Trust%20GmbH,C=DE?certificaterevocationlist',
         util.iri_to_uri(
             'ldap://directory.d-trust.net/CN=D-TRUST Root Class 3 CA 2 EV 2009,'
             'O=D-Trust GmbH,C=DE?certificaterevocationlist'
         )
     )
Пример #3
0
def _grab_crl(user_agent, url, timeout):
    """
    Fetches a CRL and parses it

    :param user_agent:
        A unicode string of the user agent to use when fetching the URL

    :param url:
        A unicode string of the URL to fetch the CRL from

    :param timeout:
        The number of seconds after which an HTTP request should timeout

    :return:
        An asn1crypto.crl.CertificateList object
    """

    if sys.version_info < (3,):
        url = util.iri_to_uri(url)
    request = Request(url)
    request.add_header(b'Accept', b'application/pkix-crl')
    request.add_header(b'User-Agent', user_agent.encode('iso-8859-1'))
    response = urlopen(request, None, timeout)
    data = response.read()
    if pem.detect(data):
        _, _, data = pem.unarmor(data)
    return crl.CertificateList.load(data)
Пример #4
0
def fetch_certs(certificate_list, user_agent=None, timeout=10):
    """
    Fetches certificates from the authority information access extension of
    an asn1crypto.crl.CertificateList object and places them into the
    cert registry.

    :param certificate_list:
        An asn1crypto.crl.CertificateList object

    :param user_agent:
        The HTTP user agent to use when requesting the CRL. If None,
        a default is used in the format "certvalidation 1.0.0".

    :param timeout:
        The number of seconds after which an HTTP request should timeout

    :raises:
        urllib.error.URLError/urllib2.URLError - when a URL/HTTP error occurs
        socket.error - when a socket error occurs

    :return:
        A list of any asn1crypto.x509.Certificate objects that were fetched
    """

    output = []

    if user_agent is None:
        user_agent = 'certvalidator %s' % __version__
    elif not isinstance(user_agent, str_cls):
        raise TypeError('user_agent must be a unicode string, not %s' % type_name(user_agent))

    for url in certificate_list.issuer_cert_urls:
        if sys.version_info < (3,):
            url = util.iri_to_uri(url)
        request = Request(url)
        request.add_header(b'Accept', b'application/pkix-cert,application/pkcs7-mime')
        request.add_header(b'User-Agent', user_agent.encode('iso-8859-1'))
        response = urlopen(request, None, timeout)

        content_type = response.headers['Content-Type'].strip()
        response_data = response.read()

        if content_type == 'application/pkix-cert':
            output.append(x509.Certificate.load(response_data))

        elif content_type == 'application/pkcs7-mime':
            signed_data = cms.SignedData.load(response_data)
            if isinstance(signed_data['certificates'], cms.CertificateSet):
                for cert_choice in signed_data['certificates']:
                    if cert_choice.name == 'certificate':
                        output.append(cert_choice.chosen)
        else:
            raise ValueError('Unknown content type of %s when fetching issuer certificate for CRL' % repr(content_type))

    return output
Пример #5
0
        def __init__(self, url):
            """
            Wrapper that converts IRI's to URI's before passing to super, and
            automatically adds the Host header

            :param url:
                A unicode string of the URL to request
            """

            super(Request, self).__init__(util.iri_to_uri(url))
            self.add_header('Host',
                            self.get_host().decode('ascii').split(":")[0])
Пример #6
0
        def __init__(self,
                     url,
                     data=None,
                     headers={},
                     origin_req_host=None,
                     unverifiable=False):
            """
            Wrapper for the ``__init__`` method of urllib that converts IRI's
            to URI's before setting the url attribute.

            :param url str: Valid URL
            :param data str: Data to send to the server or None
            :param headers dict: Dictionary containing [header type]: [header
                value] items
            :param origin_req_host str: Host name or IP address of the original
                request that was initiated
            :param unverifiable bool: Indicates whether the request is
                unverifiable, as defined by RFC 2965.
            """
            url = util.iri_to_uri(url)
            _Request.__init__(self, url, data, headers, origin_req_host,
                              unverifiable)
Пример #7
0
def fetch(cert, issuer, hash_algo='sha1', nonce=True, user_agent=None, timeout=10):
    """
    Fetches an OCSP response for a certificate

    :param cert:
        An asn1cyrpto.x509.Certificate object to get an OCSP reponse for

    :param issuer:
        An asn1crypto.x509.Certificate object that is the issuer of cert

    :param hash_algo:
        A unicode string of "sha1" or "sha256"

    :param nonce:
        A boolean - if the nonce extension should be used to prevent replay
        attacks

    :param user_agent:
        The HTTP user agent to use when requesting the OCSP response. If None,
        a default is used in the format "certvalidation 1.0.0".

    :param timeout:
        The number of seconds after which an HTTP request should timeout

    :raises:
        urllib.error.URLError/urllib2.URLError - when a URL/HTTP error occurs
        socket.error - when a socket error occurs

    :return:
        An asn1crypto.ocsp.OCSPResponse object
    """

    if not isinstance(cert, x509.Certificate):
        raise TypeError('cert must be an instance of asn1crypto.x509.Certificate, not %s' % type_name(cert))

    if not isinstance(issuer, x509.Certificate):
        raise TypeError('issuer must be an instance of asn1crypto.x509.Certificate, not %s' % type_name(issuer))

    if hash_algo not in set(['sha1', 'sha256']):
        raise ValueError('hash_algo must be one of "sha1", "sha256", not %s' % repr(hash_algo))

    if not isinstance(nonce, bool):
        raise TypeError('nonce must be a bool, not %s' % type_name(nonce))

    if user_agent is None:
        user_agent = 'certvalidator %s' % __version__
    elif not isinstance(user_agent, str_cls):
        raise TypeError('user_agent must be a unicode string, not %s' % type_name(user_agent))

    cert_id = ocsp.CertId({
        'hash_algorithm': algos.DigestAlgorithm({'algorithm': hash_algo}),
        'issuer_name_hash': getattr(cert.issuer, hash_algo),
        'issuer_key_hash': getattr(issuer.public_key, hash_algo),
        'serial_number': cert.serial_number,
    })

    request = ocsp.Request({
        'req_cert': cert_id,
    })
    tbs_request = ocsp.TBSRequest({
        'request_list': ocsp.Requests([request]),
    })

    if nonce:
        nonce_extension = ocsp.TBSRequestExtension({
            'extn_id': 'nonce',
            'critical': False,
            'extn_value': core.OctetString(core.OctetString(os.urandom(16)).dump())
        })
        tbs_request['request_extensions'] = ocsp.TBSRequestExtensions([nonce_extension])

    ocsp_request = ocsp.OCSPRequest({
        'tbs_request': tbs_request,
    })

    last_e = None
    for ocsp_url in cert.ocsp_urls:
        try:
            if sys.version_info < (3,):
                ocsp_url = util.iri_to_uri(ocsp_url)
            request = Request(ocsp_url)
            _add_header(request, 'Accept', 'application/ocsp-response')
            _add_header(request, 'Content-Type', 'application/ocsp-request')
            _add_header(request, 'User-Agent', user_agent)
            response = urlopen(request, ocsp_request.dump(), timeout)
            ocsp_response = ocsp.OCSPResponse.load(response.read())
            request_nonce = ocsp_request.nonce_value
            response_nonce = ocsp_response.nonce_value
            if request_nonce and response_nonce and request_nonce.native != response_nonce.native:
                raise errors.OCSPValidationError(
                    'Unable to verify OCSP response since the request and response nonces do not match'
                )
            return ocsp_response

        except (URLError) as e:
            last_e = e

    raise last_e
Пример #8
0
def fetch(cert,
          issuer,
          hash_algo='sha1',
          nonce=True,
          user_agent=None,
          timeout=10):
    """
    Fetches an OCSP response for a certificate

    :param cert:
        An asn1cyrpto.x509.Certificate object to get an OCSP reponse for

    :param issuer:
        An asn1crypto.x509.Certificate object that is the issuer of cert

    :param hash_algo:
        A unicode string of "sha1" or "sha256"

    :param nonce:
        A boolean - if the nonce extension should be used to prevent replay
        attacks

    :param user_agent:
        The HTTP user agent to use when requesting the OCSP response. If None,
        a default is used in the format "certvalidation 1.0.0".

    :param timeout:
        The number of seconds after which an HTTP request should timeout

    :raises:
        urllib.error.URLError/urllib2.URLError - when a URL/HTTP error occurs
        socket.error - when a socket error occurs

    :return:
        An asn1crypto.ocsp.OCSPResponse object
    """

    if not isinstance(cert, x509.Certificate):
        raise TypeError(
            'cert must be an instance of asn1crypto.x509.Certificate, not %s' %
            type_name(cert))

    if not isinstance(issuer, x509.Certificate):
        raise TypeError(
            'issuer must be an instance of asn1crypto.x509.Certificate, not %s'
            % type_name(issuer))

    if hash_algo not in set(['sha1', 'sha256']):
        raise ValueError('hash_algo must be one of "sha1", "sha256", not %s' %
                         repr(hash_algo))

    if not isinstance(nonce, bool):
        raise TypeError('nonce must be a bool, not %s' % type_name(nonce))

    if user_agent is None:
        user_agent = 'certvalidator %s' % __version__
    elif not isinstance(user_agent, str_cls):
        raise TypeError('user_agent must be a unicode string, not %s' %
                        type_name(user_agent))

    cert_id = ocsp.CertId({
        'hash_algorithm':
        algos.DigestAlgorithm({'algorithm': hash_algo}),
        'issuer_name_hash':
        getattr(cert.issuer, hash_algo),
        'issuer_key_hash':
        getattr(issuer.public_key, hash_algo),
        'serial_number':
        cert.serial_number,
    })

    request = ocsp.Request({
        'req_cert': cert_id,
    })
    tbs_request = ocsp.TBSRequest({
        'request_list': ocsp.Requests([request]),
    })

    if nonce:
        nonce_extension = ocsp.TBSRequestExtension({
            'extn_id':
            'nonce',
            'critical':
            False,
            'extn_value':
            core.OctetString(core.OctetString(os.urandom(16)).dump())
        })
        tbs_request['request_extensions'] = ocsp.TBSRequestExtensions(
            [nonce_extension])

    ocsp_request = ocsp.OCSPRequest({
        'tbs_request': tbs_request,
    })

    last_e = None
    for ocsp_url in cert.ocsp_urls:
        try:
            if sys.version_info < (3, ):
                ocsp_url = util.iri_to_uri(ocsp_url)
            request = Request(ocsp_url)
            _add_header(request, 'Accept', 'application/ocsp-response')
            _add_header(request, 'Content-Type', 'application/ocsp-request')
            _add_header(request, 'User-Agent', user_agent)
            response = urlopen(request, ocsp_request.dump(), timeout)
            ocsp_response = ocsp.OCSPResponse.load(response.read())
            request_nonce = ocsp_request.nonce_value
            response_nonce = ocsp_response.nonce_value
            if request_nonce and response_nonce and request_nonce.native != response_nonce.native:
                raise errors.OCSPValidationError(
                    'Unable to verify OCSP response since the request and response nonces do not match'
                )
            return ocsp_response

        except (URLError) as e:
            last_e = e

    raise last_e