Example #1
0
    def as_view(cls, responder_key, responder_cert, **kwargs):
        priv_err_msg = '%s: Could not read private key.' % responder_key
        pub_err_msg = '%s: Could not read public key.' % responder_cert

        # Preload the responder key and certificate for faster access.
        try:
            with open(responder_key, 'rb') as stream:
                responder_key = stream.read()
        except:
            raise ImproperlyConfigured(priv_err_msg)

        try:
            # try to load responder key and cert with oscrypto, to make sure they are actually usable
            load_private_key(responder_key)
        except:
            raise ImproperlyConfigured(priv_err_msg)

        if os.path.exists(responder_cert):
            with open(responder_cert, 'rb') as stream:
                responder_cert = stream.read()

        if not responder_cert:
            raise ImproperlyConfigured(pub_err_msg)

        try:
            load_certificate(responder_cert)
        except:
            raise ImproperlyConfigured(pub_err_msg)

        return super(OCSPView, cls).as_view(responder_key=responder_key,
                                            responder_cert=responder_cert,
                                            **kwargs)
Example #2
0
 def test_dump_certificate(self):
     cert = asymmetric.load_certificate(
         os.path.join(fixtures_dir, 'keys/test.crt'))
     pem_serialized = asymmetric.dump_certificate(cert)
     cert_reloaded = asymmetric.load_certificate(pem_serialized)
     self.assertIsInstance(cert_reloaded, asymmetric.Certificate)
     self.assertEqual('rsa', cert_reloaded.algorithm)
    def test_build_revoked_no_reason(self):
        issuer_key = asymmetric.load_private_key(
            os.path.join(fixtures_dir, 'test.key'))
        issuer_cert = asymmetric.load_certificate(
            os.path.join(fixtures_dir, 'test.crt'))
        subject_cert = asymmetric.load_certificate(
            os.path.join(fixtures_dir, 'test-inter.crt'))

        revoked_time = datetime(2015, 9, 1, 12, 0, 0, tzinfo=timezone.utc)
        builder = OCSPResponseBuilder('successful',
                                      [{
                                          'certificate': subject_cert,
                                          'certificate_status': 'revoked',
                                          'revocation_date': revoked_time
                                      }])
        ocsp_response = builder.build(issuer_key, issuer_cert)
        der_bytes = ocsp_response.dump()

        new_response = asn1crypto.ocsp.OCSPResponse.load(der_bytes)
        basic_response = new_response['response_bytes']['response'].parsed
        response_data = basic_response['tbs_response_data']
        cert_response = response_data['responses'][0]

        self.assertEqual('revoked', cert_response['cert_status'].name)
        self.assertEqual(
            revoked_time,
            cert_response['cert_status'].chosen['revocation_time'].native)
        self.assertEqual(
            'unspecified',
            cert_response['cert_status'].chosen['revocation_reason'].native)
Example #4
0
    def ocsp_validation(self, subject_cert, issuer_cert):
        ocsp_link = self.get_ocsp_link(subject_cert)

        subject_cert = asymmetric.load_certificate(
            crypto.dump_certificate(
                crypto.FILETYPE_ASN1,
                subject_cert
                )
            )

        issuer_cert = asymmetric.load_certificate(  
            crypto.dump_certificate(
                crypto.FILETYPE_ASN1,
                issuer_cert
            ))
        builder = OCSPRequestBuilder(subject_cert, issuer_cert)
        ocsp_request = builder.build()

        flag = False

        for x in range(1,3):
            try:
                r = requests.post(
                ocsp_link,
                data = ocsp_request.dump(),
                headers={"Content-Type": "application/ocsp-request"}
                )
                resposta = asn1crypto.ocsp.OCSPResponse.load(r.content)
                break
            except Exception as e:
                print("failed OCSP {0} times".format(x))

        return "good" == resposta['response_bytes']['response'].parsed['tbs_response_data']["responses"][0]["cert_status"].name
    def test_build_no_certificate(self):
        issuer_key = asymmetric.load_private_key(
            os.path.join(fixtures_dir, 'test.key'))
        issuer_cert = asymmetric.load_certificate(
            os.path.join(fixtures_dir, 'test.crt'))
        subject_cert = asymmetric.load_certificate(
            os.path.join(fixtures_dir, 'test-inter.crt'))

        with self.assertRaisesRegexp(
                ValueError,
                'must be set if the response_status is "successful"'):
            builder = OCSPResponseBuilder('successful', subject_cert, 'good')
            builder.certificate = None
            builder.build(issuer_key, issuer_cert)

        with self.assertRaisesRegexp(
                ValueError,
                'must be set if the response_status is "successful"'):
            builder = OCSPResponseBuilder('successful', subject_cert, 'good')
            builder.certificate_status = None
            builder.build(issuer_key, issuer_cert)

        with self.assertRaisesRegexp(
                ValueError,
                'must be set if the response_status is "successful"'):
            builder = OCSPResponseBuilder('successful', subject_cert)
            builder.build(issuer_key, issuer_cert)

        with self.assertRaisesRegexp(
                ValueError,
                'must be set if the response_status is "successful"'):
            builder = OCSPResponseBuilder('successful', None, 'good')
            builder.build(issuer_key, issuer_cert)
    def test_build_basic_request(self):
        issuer_cert = asymmetric.load_certificate(
            os.path.join(fixtures_dir, 'test.crt'))
        subject_cert = asymmetric.load_certificate(
            os.path.join(fixtures_dir, 'test-inter.crt'))

        builder = OCSPRequestBuilder(subject_cert, issuer_cert)
        ocsp_request = builder.build()
        der_bytes = ocsp_request.dump()

        new_request = asn1crypto.ocsp.OCSPRequest.load(der_bytes)
        tbs_request = new_request['tbs_request']

        self.assertEqual(None, new_request['optional_signature'].native)
        self.assertEqual('v1', tbs_request['version'].native)
        self.assertEqual(None, tbs_request['requestor_name'].native)
        self.assertEqual(1, len(tbs_request['request_list']))

        request = tbs_request['request_list'][0]
        self.assertEqual(
            'sha1', request['req_cert']['hash_algorithm']['algorithm'].native)
        self.assertEqual(issuer_cert.asn1.subject.sha1,
                         request['req_cert']['issuer_name_hash'].native)
        self.assertEqual(issuer_cert.asn1.public_key.sha1,
                         request['req_cert']['issuer_key_hash'].native)
        self.assertEqual(subject_cert.asn1.serial_number,
                         request['req_cert']['serial_number'].native)
        self.assertEqual(0, len(request['single_request_extensions']))

        self.assertEqual(1, len(tbs_request['request_extensions']))
        extn = tbs_request['request_extensions'][0]

        self.assertEqual('nonce', extn['extn_id'].native)
        self.assertEqual(16, len(extn['extn_value'].parsed.native))
    def test_build_basic_request(self):
        issuer_cert = asymmetric.load_certificate(os.path.join(fixtures_dir, "test.crt"))
        subject_cert = asymmetric.load_certificate(os.path.join(fixtures_dir, "test-inter.crt"))

        builder = OCSPRequestBuilder(subject_cert, issuer_cert)
        ocsp_request = builder.build()
        der_bytes = ocsp_request.dump()

        new_request = asn1crypto.ocsp.OCSPRequest.load(der_bytes)
        tbs_request = new_request["tbs_request"]

        self.assertEqual(None, new_request["optional_signature"].native)
        self.assertEqual("v1", tbs_request["version"].native)
        self.assertEqual(None, tbs_request["requestor_name"].native)
        self.assertEqual(1, len(tbs_request["request_list"]))

        request = tbs_request["request_list"][0]
        self.assertEqual("sha1", request["req_cert"]["hash_algorithm"]["algorithm"].native)
        self.assertEqual(issuer_cert.asn1.subject.sha1, request["req_cert"]["issuer_name_hash"].native)
        self.assertEqual(issuer_cert.asn1.public_key.sha1, request["req_cert"]["issuer_key_hash"].native)
        self.assertEqual(subject_cert.asn1.serial_number, request["req_cert"]["serial_number"].native)
        self.assertEqual(0, len(request["single_request_extensions"]))

        self.assertEqual(1, len(tbs_request["request_extensions"]))
        extn = tbs_request["request_extensions"][0]

        self.assertEqual("nonce", extn["extn_id"].native)
        self.assertEqual(16, len(extn["extn_value"].parsed.native))
    def test_build_signed_request(self):
        issuer_cert = asymmetric.load_certificate(os.path.join(fixtures_dir, "test.crt"))
        subject_cert = asymmetric.load_certificate(os.path.join(fixtures_dir, "test-inter.crt"))

        requestor_cert = asymmetric.load_certificate(os.path.join(fixtures_dir, "test-third.crt"))
        requestor_key = asymmetric.load_private_key(os.path.join(fixtures_dir, "test-third.key"))

        builder = OCSPRequestBuilder(subject_cert, issuer_cert)
        ocsp_request = builder.build(requestor_key, requestor_cert, [subject_cert, issuer_cert])
        der_bytes = ocsp_request.dump()

        new_request = asn1crypto.ocsp.OCSPRequest.load(der_bytes)
        tbs_request = new_request["tbs_request"]
        signature = new_request["optional_signature"]

        self.assertEqual("sha256", signature["signature_algorithm"].hash_algo)
        self.assertEqual("rsassa_pkcs1v15", signature["signature_algorithm"].signature_algo)
        self.assertEqual(3, len(signature["certs"]))
        self.assertEqual("v1", tbs_request["version"].native)
        self.assertEqual(requestor_cert.asn1.subject, tbs_request["requestor_name"].chosen)
        self.assertEqual(1, len(tbs_request["request_list"]))

        request = tbs_request["request_list"][0]
        self.assertEqual("sha1", request["req_cert"]["hash_algorithm"]["algorithm"].native)
        self.assertEqual(issuer_cert.asn1.subject.sha1, request["req_cert"]["issuer_name_hash"].native)
        self.assertEqual(issuer_cert.asn1.public_key.sha1, request["req_cert"]["issuer_key_hash"].native)
        self.assertEqual(subject_cert.asn1.serial_number, request["req_cert"]["serial_number"].native)
        self.assertEqual(0, len(request["single_request_extensions"]))

        self.assertEqual(1, len(tbs_request["request_extensions"]))
        extn = tbs_request["request_extensions"][0]

        self.assertEqual("nonce", extn["extn_id"].native)
        self.assertEqual(16, len(extn["extn_value"].parsed.native))
    def __init__(self, issuer_cert: str, responder_cert: str, responder_key: str,
                       fault: str, next_update_seconds: int):
        """
        Create a new OCSPResponder instance.

        :param issuer_cert: Path to the issuer certificate.
        :param responder_cert: Path to the certificate of the OCSP responder
            with the `OCSP Signing` extension.
        :param responder_key: Path to the private key belonging to the
            responder cert.
        :param validate_func: A function that - given a certificate serial -
            will return the appropriate :class:`CertificateStatus` and -
            depending on the status - a revocation datetime.
        :param cert_retrieve_func: A function that - given a certificate serial -
            will return the corresponding certificate as a string.
        :param next_update_seconds: The ``nextUpdate`` value that will be written
            into the response. Default: 9 hours.

        """
        # Certs and keys
        self._issuer_cert = asymmetric.load_certificate(issuer_cert)
        self._responder_cert = asymmetric.load_certificate(responder_cert)
        self._responder_key = asymmetric.load_private_key(responder_key)

        # Next update
        self._next_update_seconds = next_update_seconds

        self._fault = fault
    def test_build_good_response(self):
        issuer_key = asymmetric.load_private_key(os.path.join(fixtures_dir, 'test.key'))
        issuer_cert = asymmetric.load_certificate(os.path.join(fixtures_dir, 'test.crt'))
        subject_cert = asymmetric.load_certificate(os.path.join(fixtures_dir, 'test-inter.crt'))

        builder = OCSPResponseBuilder('successful', subject_cert, 'good')
        ocsp_response = builder.build(issuer_key, issuer_cert)
        der_bytes = ocsp_response.dump()

        new_response = asn1crypto.ocsp.OCSPResponse.load(der_bytes)
        basic_response = new_response['response_bytes']['response'].parsed
        response_data = basic_response['tbs_response_data']

        self.assertEqual('sha256', basic_response['signature_algorithm'].hash_algo)
        self.assertEqual('rsassa_pkcs1v15', basic_response['signature_algorithm'].signature_algo)
        self.assertEqual('v1', response_data['version'].native)
        self.assertEqual('by_key', response_data['responder_id'].name)
        self.assertEqual(
            issuer_cert.asn1.public_key.sha1,
            response_data['responder_id'].chosen.native
        )
        self.assertGreaterEqual(datetime.now(timezone.utc), response_data['produced_at'].native)
        self.assertEqual(1, len(response_data['responses']))
        self.assertEqual(0, len(response_data['response_extensions']))

        cert_response = response_data['responses'][0]

        self.assertEqual('sha1', cert_response['cert_id']['hash_algorithm']['algorithm'].native)
        self.assertEqual(issuer_cert.asn1.subject.sha1, cert_response['cert_id']['issuer_name_hash'].native)
        self.assertEqual(issuer_cert.asn1.public_key.sha1, cert_response['cert_id']['issuer_key_hash'].native)
        self.assertEqual(subject_cert.asn1.serial_number, cert_response['cert_id']['serial_number'].native)

        self.assertEqual('good', cert_response['cert_status'].name)
        self.assertGreaterEqual(datetime.now(timezone.utc), cert_response['this_update'].native)
        self.assertGreaterEqual(set(), cert_response.critical_extensions)
Example #11
0
    def frompem(cls, issuer_cert: StrOrBytes, responder_cert: StrOrBytes, responder_key: StrOrBytes,
                       validate_func: ValidateFunc, cert_retrieve_func: CertRetrieveFunc = None,
                       next_update_days: int = 7):
        """
        Create a new OCSPResponder instance from filepaths or bytes.
        :param issuer_cert: Path to or Bytes of the issuer certificate.
        :param responder_cert: Path to or Bytes of the certificate of the OCSP responder
            with the `OCSP Signing` extension.
        :param responder_key: Path to or Bytes of the private key belonging to the
            responder cert.
        :param validate_func: A function that - given a certificate serial -
            will return the appropriate :class:`CertificateStatus` and -
            depending on the status - a revocation datetime.
        :param cert_retrieve_func: A function that - given a certificate serial -
            will return the corresponding certificate as a string.
        :param next_update_days: The ``nextUpdate`` value that will be written
            into the response. Default: 7 days.
        """
        # Certs and keys
        _issuer_cert = asymmetric.load_certificate(issuer_cert)
        _responder_cert = asymmetric.load_certificate(responder_cert)
        _responder_key = asymmetric.load_private_key(responder_key)

        return cls(_issuer_cert, _responder_cert, _responder_key,
                validate_func=validate_func,
                cert_retrieve_func=cert_retrieve_func,
                next_update_days=next_update_days)
    def test_build_revoked_response(self):
        issuer_key = asymmetric.load_private_key(
            os.path.join(fixtures_dir, 'test.key'))
        issuer_cert = asymmetric.load_certificate(
            os.path.join(fixtures_dir, 'test.crt'))
        subject_cert = asymmetric.load_certificate(
            os.path.join(fixtures_dir, 'test-inter.crt'))

        revoked_time = datetime(2015, 9, 1, 12, 0, 0, tzinfo=timezone.utc)
        builder = OCSPResponseBuilder(
            'successful', [{
                'certificate': subject_cert,
                'certificate_status': 'key_compromise',
                'revocation_date': revoked_time
            }])
        ocsp_response = builder.build(issuer_key, issuer_cert)
        der_bytes = ocsp_response.dump()

        new_response = asn1crypto.ocsp.OCSPResponse.load(der_bytes)
        basic_response = new_response['response_bytes']['response'].parsed
        response_data = basic_response['tbs_response_data']

        self.assertEqual('sha256',
                         basic_response['signature_algorithm'].hash_algo)
        self.assertEqual('rsassa_pkcs1v15',
                         basic_response['signature_algorithm'].signature_algo)
        self.assertEqual('v1', response_data['version'].native)
        self.assertEqual('by_key', response_data['responder_id'].name)
        self.assertEqual(issuer_cert.asn1.public_key.sha1,
                         response_data['responder_id'].chosen.native)
        self.assertGreaterEqual(datetime.now(timezone.utc),
                                response_data['produced_at'].native)
        self.assertEqual(1, len(response_data['responses']))
        self.assertEqual(0, len(response_data['response_extensions']))

        cert_response = response_data['responses'][0]

        self.assertEqual(
            'sha1',
            cert_response['cert_id']['hash_algorithm']['algorithm'].native)
        self.assertEqual(issuer_cert.asn1.subject.sha1,
                         cert_response['cert_id']['issuer_name_hash'].native)
        self.assertEqual(issuer_cert.asn1.public_key.sha1,
                         cert_response['cert_id']['issuer_key_hash'].native)
        self.assertEqual(subject_cert.asn1.serial_number,
                         cert_response['cert_id']['serial_number'].native)

        self.assertEqual('revoked', cert_response['cert_status'].name)
        self.assertEqual(
            revoked_time,
            cert_response['cert_status'].chosen['revocation_time'].native)
        self.assertEqual(
            'key_compromise',
            cert_response['cert_status'].chosen['revocation_reason'].native)
        self.assertGreaterEqual(datetime.now(timezone.utc),
                                cert_response['this_update'].native)
        self.assertGreaterEqual(set(), cert_response.critical_extensions)
Example #13
0
    def get_ocsp_status(self,cert,is_cert,cert_url,is_cert_url):
        t0 = time.clock()
        #print "Issuer Certificate is >> %s" %(is_cert_name)
        c = OpenSSL.crypto
        
        if not isinstance(cert, c.X509) or not isinstance(is_cert, c.X509):
            return False
        
        id_cert_buf = c.dump_certificate(c.FILETYPE_PEM, cert)
        issuer_cert_buf = c.dump_certificate(c.FILETYPE_PEM, is_cert)
        # with open(cert_name,"rb") as f:
        #     id_cert_buf = f.read()
        # with open(is_cert_name,"rb") as f:
        #     issuer_cert_buf = f.read()

        id_cert = asymmetric.load_certificate(id_cert_buf)
        issuer_cert = asymmetric.load_certificate(issuer_cert_buf)

        builder = OCSPRequestBuilder(id_cert, issuer_cert)
        ocsp_request = builder.build()

        ocsp_req_dump = ocsp_request.dump()

        cert_ocsp_url = cert_url 
        is_ocsp_url = is_cert_url 
        
        resp = requests.post(cert_ocsp_url, ocsp_req_dump)

        ocsp_response = resp.content

        ocspResponse = OCSPResponse()
        basicOcspResponse = BasicOCSPResponse()

        decoded_resp = der_decoder.decode(ocsp_response, asn1Spec=ocspResponse)
        
        for resp in decoded_resp:
        
            if isinstance(resp, OCSPResponse):
                ocsp_response_status = resp.getComponentByName('responseStatus')
                
                ocsp_resp_bytes = resp.getComponentByName('responseBytes')
                ocsp_resp = ocsp_resp_bytes.getComponentByName('response') 
                basic_ocsp_response, _ = der_decoder.decode(ocsp_resp, asn1Spec=basicOcspResponse)
                tbs_response_data = basic_ocsp_response.getComponentByName('tbsResponseData')
                responses = tbs_response_data.getComponentByName('responses')
                for response in responses:
                    
                    serial_no = response.getComponentByName('certID').getComponentByName('serialNumber')                
                    #print str(serial_no)
                    #print response.getComponentByName('certStatus').getName()
                    print time.clock() - t0
                    if response.getComponentByName('certStatus').getName() == "good":
                        return True
                    else:
                        return False
    def test_build_delta_crl(self):
        root_certificate = asymmetric.load_certificate(os.path.join(fixtures_dir, 'root.crt'))

        crl_issuer_private_key = asymmetric.load_private_key(
            os.path.join(fixtures_dir, 'crl_issuer.key'),
            'password123'
        )
        crl_issuer_certificate = asymmetric.load_certificate(os.path.join(fixtures_dir, 'crl_issuer.crt'))

        builder = CertificateListBuilder(
            'http://crl.example.com/delta',
            crl_issuer_certificate,
            50001
        )
        builder.certificate_issuer = root_certificate
        builder.issuer_certificate_url = 'http://download.example.com/crl_issuer'
        builder.delta_of = 50000

        certificate_list = builder.build(crl_issuer_private_key)
        der_bytes = certificate_list.dump()

        new_cert_list = crl.CertificateList.load(der_bytes)
        tbs_cert_list = new_cert_list['tbs_cert_list']
        revoked_certificates = tbs_cert_list['revoked_certificates']

        now = datetime.now(timezone.utc)

        self.assertEqual('v3', tbs_cert_list['version'].native)
        self.assertEqual('rsassa_pkcs1v15', tbs_cert_list['signature'].signature_algo)
        self.assertEqual('sha256', tbs_cert_list['signature'].hash_algo)
        self.assertEqual(crl_issuer_certificate.asn1.subject, tbs_cert_list['issuer'])
        self.assertEqual(crl_issuer_certificate.asn1.subject.sha256, tbs_cert_list['issuer'].sha256)
        self.assertGreaterEqual(now, tbs_cert_list['this_update'].native)
        self.assertLess(now, tbs_cert_list['next_update'].native)
        self.assertEqual(set(['issuing_distribution_point', 'delta_crl_indicator']), new_cert_list.critical_extensions)

        self.assertEqual(0, len(revoked_certificates))

        self.assertEqual(None, new_cert_list.issuer_alt_name_value)
        self.assertEqual(50001, new_cert_list.crl_number_value.native)
        self.assertEqual(50000, new_cert_list.delta_crl_indicator_value.native)
        self.assertEqual('full_name', new_cert_list.issuing_distribution_point_value['distribution_point'].name)
        self.assertEqual(
            'uniform_resource_identifier',
            new_cert_list.issuing_distribution_point_value['distribution_point'].chosen[0].name
        )
        self.assertEqual(
            'http://crl.example.com/delta',
            new_cert_list.issuing_distribution_point_value['distribution_point'].chosen[0].native
        )
        self.assertEqual(crl_issuer_certificate.asn1.key_identifier, new_cert_list.authority_key_identifier)
        self.assertEqual([], new_cert_list.delta_crl_distribution_points)
        self.assertEqual(['http://download.example.com/crl_issuer'], new_cert_list.issuer_cert_urls)
    def test_build_delegated_good_response_cert_serial(self):
        responder_key = asymmetric.load_private_key(
            os.path.join(fixtures_dir, 'test-ocsp.key'), 'password')
        responder_cert = asymmetric.load_certificate(
            os.path.join(fixtures_dir, 'test-ocsp.crt'))
        issuer_cert = asymmetric.load_certificate(
            os.path.join(fixtures_dir, 'test.crt'))
        subject_cert = asymmetric.load_certificate(
            os.path.join(fixtures_dir, 'test-inter.crt'))

        builder = OCSPResponseBuilder('successful', None, 'good')
        builder.certificate_issuer = issuer_cert
        builder.certificate_serial_number = subject_cert.asn1.serial_number
        ocsp_response = builder.build(responder_key, responder_cert)
        der_bytes = ocsp_response.dump()

        new_response = asn1crypto.ocsp.OCSPResponse.load(der_bytes)
        basic_response = new_response['response_bytes']['response'].parsed
        response_data = basic_response['tbs_response_data']

        self.assertEqual('sha256',
                         basic_response['signature_algorithm'].hash_algo)
        self.assertEqual('rsassa_pkcs1v15',
                         basic_response['signature_algorithm'].signature_algo)
        self.assertEqual('v1', response_data['version'].native)
        self.assertEqual('by_key', response_data['responder_id'].name)
        self.assertEqual(responder_cert.asn1.public_key.sha1,
                         response_data['responder_id'].chosen.native)
        self.assertGreaterEqual(datetime.now(timezone.utc),
                                response_data['produced_at'].native)
        self.assertEqual(1, len(response_data['responses']))
        self.assertEqual(0, len(response_data['response_extensions']))

        cert_response = response_data['responses'][0]

        self.assertEqual(
            'sha1',
            cert_response['cert_id']['hash_algorithm']['algorithm'].native)
        self.assertEqual(issuer_cert.asn1.subject.sha1,
                         cert_response['cert_id']['issuer_name_hash'].native)
        self.assertEqual(issuer_cert.asn1.public_key.sha1,
                         cert_response['cert_id']['issuer_key_hash'].native)
        self.assertEqual(subject_cert.asn1.serial_number,
                         cert_response['cert_id']['serial_number'].native)

        self.assertEqual('good', cert_response['cert_status'].name)
        self.assertGreaterEqual(datetime.now(timezone.utc),
                                cert_response['this_update'].native)
        self.assertGreaterEqual(set(), cert_response.critical_extensions)
    def test_build_delta_crl(self):
        root_certificate = asymmetric.load_certificate(os.path.join(fixtures_dir, "root.crt"))

        crl_issuer_private_key = asymmetric.load_private_key(
            os.path.join(fixtures_dir, "crl_issuer.key"), "password123"
        )
        crl_issuer_certificate = asymmetric.load_certificate(os.path.join(fixtures_dir, "crl_issuer.crt"))

        builder = CertificateListBuilder("http://crl.example.com/delta", crl_issuer_certificate, 50001)
        builder.certificate_issuer = root_certificate
        builder.issuer_certificate_url = "http://download.example.com/crl_issuer"
        builder.delta_of = 50000

        certificate_list = builder.build(crl_issuer_private_key)
        der_bytes = certificate_list.dump()

        new_cert_list = crl.CertificateList.load(der_bytes)
        tbs_cert_list = new_cert_list["tbs_cert_list"]
        revoked_certificates = tbs_cert_list["revoked_certificates"]

        now = datetime.now(timezone.utc)

        self.assertEqual("v3", tbs_cert_list["version"].native)
        self.assertEqual("rsassa_pkcs1v15", tbs_cert_list["signature"].signature_algo)
        self.assertEqual("sha256", tbs_cert_list["signature"].hash_algo)
        self.assertEqual(crl_issuer_certificate.asn1.subject, tbs_cert_list["issuer"])
        self.assertEqual(crl_issuer_certificate.asn1.subject.sha256, tbs_cert_list["issuer"].sha256)
        self.assertGreaterEqual(now, tbs_cert_list["this_update"].native)
        self.assertLess(now, tbs_cert_list["next_update"].native)
        self.assertEqual(set(["issuing_distribution_point", "delta_crl_indicator"]), new_cert_list.critical_extensions)

        self.assertEqual(0, len(revoked_certificates))

        self.assertEqual(None, new_cert_list.issuer_alt_name_value)
        self.assertEqual(50001, new_cert_list.crl_number_value.native)
        self.assertEqual(50000, new_cert_list.delta_crl_indicator_value.native)
        self.assertEqual("full_name", new_cert_list.issuing_distribution_point_value["distribution_point"].name)
        self.assertEqual(
            "uniform_resource_identifier",
            new_cert_list.issuing_distribution_point_value["distribution_point"].chosen[0].name,
        )
        self.assertEqual(
            "http://crl.example.com/delta",
            new_cert_list.issuing_distribution_point_value["distribution_point"].chosen[0].native,
        )
        self.assertEqual(crl_issuer_certificate.asn1.key_identifier, new_cert_list.authority_key_identifier)
        self.assertEqual([], new_cert_list.delta_crl_distribution_points)
        self.assertEqual(["http://download.example.com/crl_issuer"], new_cert_list.issuer_cert_urls)
Example #17
0
    def setup(self, initial_data: dict = None):
        """
        Receives a user certificate from the front end
        """
        try:
            certificate_hex = initial_data["certificate"]
        except (TypeError, KeyError) as e:
            raise InvalidParameter("Missing required parameter 'certificate'",
                                   param="certificate") from e

        try:
            certificate = binascii.a2b_hex(certificate_hex)
        except (TypeError, ValueError) as e:
            raise InvalidParameter(
                "Failed to decode parameter `certificate` from hex-encoding",
                param="certificate") from e

        try:
            self._certificate_handle = load_certificate(certificate)
        except ValueError as e:
            raise InvalidParameter(
                "Failed to recognize `certificate` as a supported certificate format",
                param="certificate") from e

        self.certificate = certificate
Example #18
0
        def get_responder_cert(self):
            # User configured a loaded certificate
            if isinstance(self.responder_cert, asymmetric.Certificate):
                return self.responder_cert

            responder_cert = self.get_responder_cert_data()
            return load_certificate(responder_cert)
Example #19
0
def test_signing():
    """Test the signing and verification functions."""
    # Load the signature key
    with open(os.path.join(TEST_DIR, "cert_test.p12"), "rb") as fp:
        sign_key = Organization.load_key(fp.read(), "test")
    with open(os.path.join(TEST_DIR, "cert_test_public.pem"), "rb") as fp:
        verify_cert = asymmetric.load_certificate(fp.read())

    # Test failure of signature verification
    with pytest.raises(IntegrityError):
        cms.verify_message(b"data", INVALID_DATA, None)

    # Test signature without signed attributes
    cms.sign_message(b"data",
                     digest_alg="sha256",
                     sign_key=sign_key,
                     use_signed_attributes=False)

    # Test pss signature and verification
    signature = cms.sign_message(b"data",
                                 digest_alg="sha256",
                                 sign_key=sign_key,
                                 sign_alg="rsassa_pss")
    cms.verify_message(b"data", signature, verify_cert)

    # Test unsupported signature alg
    with pytest.raises(AS2Exception):
        cms.sign_message(b"data",
                         digest_alg="sha256",
                         sign_key=sign_key,
                         sign_alg="rsassa_pssa")
Example #20
0
    def load_key(key_str, key_pass):
        """ Function to load password protected key file in p12 or pem format"""

        try:
            # First try to parse as a p12 file
            key, cert, _ = asymmetric.load_pkcs12(key_str, key_pass)
        except ValueError as e:
            # If it fails due to invalid password raise error here
            if e.args[0] == 'Password provided is invalid':
                raise AS2Exception('Password not valid for Private Key.')

            # if not try to parse as a pem file
            key, cert = None, None
            for kc in split_pem(key_str):
                try:
                    cert = asymmetric.load_certificate(kc)
                except (ValueError, TypeError):
                    try:
                        key = asymmetric.load_private_key(kc, key_pass)
                    except OSError:
                        raise AS2Exception(
                            'Invalid Private Key or password is not correct.')

        if not key or not cert:
            raise AS2Exception(
                'Invalid Private key file or Public key not included.')

        return key, cert
Example #21
0
    def from_certificate(
            cls,
            cert: "Union[bytes, Asn1CryptoCertificate, OsCryptoCertificate]"):
        """
        Get personal info from an oscrypto/asn1crypto Certificate object

        For a closer look at where the attributes come from:
        asn1crypto.x509.NameType
        """
        if isinstance(cert, bytes):
            cert = load_certificate(cert)
        cert: "Asn1CryptoCertificate" = getattr(cert, "asn1", cert)
        subject = cert.subject.native

        # ID codes usually given as PNO{EE,LT,LV}-XXXXXX.
        # LV ID codes contain a dash so we need to be careful about it.
        id_code = subject["serial_number"]
        if id_code.startswith("PNO"):
            prefix, id_code = id_code.split("-", 1)  # pylint: disable=unused-variable

        return cls(
            country=subject["country_name"],
            id_code=id_code,
            given_name=subject["given_name"],
            surname=subject["surname"],
            asn1_certificate=cert,
        )
Example #22
0
def test_encryption():
    """Test the encryption and decryption functions."""
    with open(os.path.join(TEST_DIR, "cert_test.p12"), "rb") as fp:
        decrypt_key = Organization.load_key(fp.read(), "test")
    with open(os.path.join(TEST_DIR, "cert_test_public.pem"), "rb") as fp:
        encrypt_cert = asymmetric.load_certificate(fp.read())

    with pytest.raises(DecryptionError):
        cms.decrypt_message(INVALID_DATA, None)

    # Test all the encryption algorithms
    enc_algorithms = [
        "rc2_128_cbc",
        "rc4_128_cbc",
        "aes_128_cbc",
        "aes_192_cbc",
        "aes_256_cbc",
    ]
    for enc_algorithm in enc_algorithms:
        encrypted_data = cms.encrypt_message(b"data", enc_algorithm, encrypt_cert)
        _, decrypted_data = cms.decrypt_message(encrypted_data, decrypt_key)
        assert decrypted_data == b"data"

    # Test no encryption algorithm
    with pytest.raises(AS2Exception):
        cms.encrypt_message(b"data", "rc5_128_cbc", encrypt_cert)

    # Test no encryption algorithm on decrypt
    encrypted_data = cms.encrypt_message(b"data", "des_64_cbc", encrypt_cert)
    with pytest.raises(AS2Exception):
        cms.decrypt_message(encrypted_data, decrypt_key)
Example #23
0
 def test_cert_ec_attributes(self):
     cert = asymmetric.load_certificate(
         os.path.join(fixtures_dir, 'keys/test-ec-named.crt'))
     self.assertEqual(256, cert.bit_size)
     self.assertEqual(32, cert.byte_size)
     self.assertEqual('secp256r1', cert.curve)
     self.assertEqual('ec', cert.algorithm)
Example #24
0
 def get_responder_cert(self):
     try:
         pub = force_bytes(Certificate.objects.get(serial=self.responder_cert).pub)
     except Certificate.DoesNotExist:
         with open(self.responder_cert, 'rb') as stream:
             pub = stream.read()
     return load_certificate(pub)
Example #25
0
    def validate(self, msg, sig):
        if self._cert is None:
            raise CryptoException("Cannot validate: no certificate")

        try:
            oscrypto_asymmetric.rsa_pkcs1v15_verify(oscrypto_asymmetric.load_certificate(self._cert), sig, msg, "sha1")
        except oscrypto_errors.SignatureError as err:
            raise CryptoException("Cannot validate: %s" % (err))
Example #26
0
    def get_responder_cert(self):
        if os.path.exists(self.responder_cert):
            with open(self.responder_cert, 'rb') as stream:
                responder_cert = stream.read()
        else:
            responder_cert = Certificate.objects.get(serial=self.responder_cert)

        return load_certificate(responder_cert)
Example #27
0
def convert_to_oscrypto(chain):
    """Converts a list of certs from OpenSSL.crypto.x509 to oscrypto._openssl.asymmetric.Certificate"""
    l = []
    for c in chain:
        l.append(
            asymmetric.load_certificate(
                crypto.dump_certificate(crypto.FILETYPE_PEM, c)))
    return l
    def test_build_signed_request(self):
        issuer_cert = asymmetric.load_certificate(
            os.path.join(fixtures_dir, 'test.crt'))
        subject_cert = asymmetric.load_certificate(
            os.path.join(fixtures_dir, 'test-inter.crt'))

        requestor_cert = asymmetric.load_certificate(
            os.path.join(fixtures_dir, 'test-third.crt'))
        requestor_key = asymmetric.load_private_key(
            os.path.join(fixtures_dir, 'test-third.key'))

        builder = OCSPRequestBuilder(subject_cert, issuer_cert)
        ocsp_request = builder.build(requestor_key, requestor_cert,
                                     [subject_cert, issuer_cert])
        der_bytes = ocsp_request.dump()

        new_request = asn1crypto.ocsp.OCSPRequest.load(der_bytes)
        tbs_request = new_request['tbs_request']
        signature = new_request['optional_signature']

        self.assertEqual('sha256', signature['signature_algorithm'].hash_algo)
        self.assertEqual('rsassa_pkcs1v15',
                         signature['signature_algorithm'].signature_algo)
        self.assertEqual(3, len(signature['certs']))
        self.assertEqual('v1', tbs_request['version'].native)
        self.assertEqual(requestor_cert.asn1.subject,
                         tbs_request['requestor_name'].chosen)
        self.assertEqual(1, len(tbs_request['request_list']))

        request = tbs_request['request_list'][0]
        self.assertEqual(
            'sha1', request['req_cert']['hash_algorithm']['algorithm'].native)
        self.assertEqual(issuer_cert.asn1.subject.sha1,
                         request['req_cert']['issuer_name_hash'].native)
        self.assertEqual(issuer_cert.asn1.public_key.sha1,
                         request['req_cert']['issuer_key_hash'].native)
        self.assertEqual(subject_cert.asn1.serial_number,
                         request['req_cert']['serial_number'].native)
        self.assertEqual(0, len(request['single_request_extensions']))

        self.assertEqual(1, len(tbs_request['request_extensions']))
        extn = tbs_request['request_extensions'][0]

        self.assertEqual('nonce', extn['extn_id'].native)
        self.assertEqual(16, len(extn['extn_value'].parsed.native))
def verifycert(certificate,store,server=False):
	# Load do cert ja feito
	# DO OCSP para ver as crl
	if server == False:
		cert = oscrypto.load_certificate(openssl.dump_certificate(openssl.FILETYPE_ASN1, certificate))
		issuer_cert = oscrypto.load_certificate(getIssuer(certificate))
		ocsp_builder = OCSPRequestBuilder(cert, issuer_cert)

		ocsp_request = ocsp_builder.build().dump()

		CN = certificate.get_subject().commonName

		if CN in ('Baltimore CyberTrust Root', 'ECRaizEstado'):
			url = 'http://ocsp.omniroot.com/baltimoreroot/'
		elif CN[:-4] == 'Cartao de Cidadao':
			url = 'http://ocsp.ecee.gov.pt/'
		elif CN[:-5] == 'EC de Autenticacao do Cartao de Cidadao':
			url = 'http://ocsp.root.cartaodecidadao.pt/publico/ocsp'
		else:
			url = 'http://ocsp.auc.cartaodecidadao.pt/publico/ocsp'

		http_req = urllib2.Request(
			url,
			data=ocsp_request,
			headers={'Content-Type': 'application/ocsp-request'}
		)

		http = urllib2.urlopen(http_req)
		ocsp_response = http.read()

		ocsp_response = asn1crypto.ocsp.OCSPResponse.load(ocsp_response)
		response_data = ocsp_response.basic_ocsp_response['tbs_response_data']
		cert_response = response_data['responses'][0]

		#print cert_response['cert_status'].name

		if cert_response['cert_status'].name != 'good':
			return False

	try:
		certV = openssl.X509StoreContext(store, certificate)
		certV.verify_certificate()
	except:
		return False
	return True
    def test_build_revoked_no_reason(self):
        issuer_key = asymmetric.load_private_key(os.path.join(fixtures_dir, 'test.key'))
        issuer_cert = asymmetric.load_certificate(os.path.join(fixtures_dir, 'test.crt'))
        subject_cert = asymmetric.load_certificate(os.path.join(fixtures_dir, 'test-inter.crt'))

        revoked_time = datetime(2015, 9, 1, 12, 0, 0, tzinfo=timezone.utc)
        builder = OCSPResponseBuilder('successful', subject_cert, 'revoked', revoked_time)
        ocsp_response = builder.build(issuer_key, issuer_cert)
        der_bytes = ocsp_response.dump()

        new_response = asn1crypto.ocsp.OCSPResponse.load(der_bytes)
        basic_response = new_response['response_bytes']['response'].parsed
        response_data = basic_response['tbs_response_data']
        cert_response = response_data['responses'][0]

        self.assertEqual('revoked', cert_response['cert_status'].name)
        self.assertEqual(revoked_time, cert_response['cert_status'].chosen['revocation_time'].native)
        self.assertEqual('unspecified', cert_response['cert_status'].chosen['revocation_reason'].native)
Example #31
0
def validateCert(store, cert, server=False):

    if not server:
        issuer = getIssuerCertificate(cert)

        subject_cert = asymmetric.load_certificate(dumpCertificate(
            cert, False))
        issuer_cert = asymmetric.load_certificate(
            dumpCertificate(issuer, False))

        builder = OCSPRequestBuilder(subject_cert, issuer_cert)
        ocsp_request_der = builder.build().dump()

        cert_name = cert.get_subject().commonName

        if cert_name in ('Baltimore CyberTrust Root', 'ECRaizEstado'):
            ocsp_url = 'http://ocsp.omniroot.com/baltimoreroot/'
        elif cert_name[:-4] == 'Cartao de Cidadao':
            ocsp_url = 'http://ocsp.ecee.gov.pt/'
        elif cert_name[:-5] == 'EC de Autenticacao do Cartao de Cidadao':
            ocsp_url = 'http://ocsp.root.cartaodecidadao.pt/publico/ocsp'
        else:
            ocsp_url = 'http://ocsp.auc.cartaodecidadao.pt/publico/ocsp'

        http_req = urllib2.Request(
            ocsp_url,
            data=ocsp_request_der,
            headers={'Content-Type': 'application/ocsp-request'})
        http = urllib2.urlopen(http_req)
        ocsp_response_der = http.read()
        ocsp_response = asn1crypto.ocsp.OCSPResponse.load(ocsp_response_der)
        response_data = ocsp_response.basic_ocsp_response['tbs_response_data']
        cert_response = response_data['responses'][0]

        if cert_response['cert_status'].name != 'good':
            return False

    context_store = openssl.X509StoreContext(store, cert)
    try:
        context_store.verify_certificate()

        return True
    except:
        return False
Example #32
0
    def ocsp_request(self):
        """
        Generate an OCSP request or return an already cached request.

        :return bytes: A binary representation of a
            :class:`asn1crypto.ocsp.OCSPRequest` which is in turn represented
            by a :class:`asn1crypto.core.Sequence`.
        """
        ocsp_request_builder = ocspbuilder.OCSPRequestBuilder(
            asymmetric.load_certificate(self.end_entity),
            asymmetric.load_certificate(self.chain[-2]))
        ocsp_request_builder.nonce = False
        ocsp_request = ocsp_request_builder.build().dump()
        # This data can be posted to the OCSP URI to debug further
        if LOG.isEnabledFor(logging.DEBUG):
            LOG.debug(
                "Request data: \n%s",
                pretty_base64(ocsp_request, line_len=75, prefix=" " * 36))
        return ocsp_request
Example #33
0
    def validate(self, msg, sig):
        if self._cert is None:
            raise CryptoException('Cannot validate: no certificate')

        try:
            oscrypto_asymmetric.rsa_pkcs1v15_verify(
                oscrypto_asymmetric.load_certificate(self._cert),
                sig, msg, 'sha1')
        except oscrypto_errors.SignatureError as err:
            raise CryptoException('Cannot validate: {}'.format(err))
Example #34
0
    def generate_certificate(self, domain, save_model):
        """This function takes a domain name as a parameter and then creates
        a certificate and key with the domain name (replacing dots
        by underscores), finally signing the certificate using specified CA and
        returns the path of key and cert files. If you are yet to generate a CA
        then check the top comments"""

        logger.info("SimpleCA: certificate creation request %s" % (domain,))

        ca_private_key = asymmetric.load_private_key(
            self.ca_key,
            password=settings.CA_KEY_PASSWD)
        ca_certificate = asymmetric.load_certificate(self.ca_crt)

        end_entity_public_key, end_entity_private_key = \
            asymmetric.generate_pair('rsa', bit_size=2048)

        builder = CertificateBuilder(
            {
                'country_name': 'CR',
                'state_or_province_name': 'San Jose',
                'locality_name': 'Costa Rica',
                'organization_name': save_model.name,
                "organizational_unit_name": save_model.institution_unit,
                'common_name': domain,
            },
            end_entity_public_key
        )
        now = timezone.now()
        builder.issuer = ca_certificate
        builder.begin_date = now
        builder.end_date = now+timedelta(settings.CA_CERT_DURATION)
        builder.key_usage = set(['digital_signature'])
        end_entity_certificate = builder.build(ca_private_key)
        # settings.CA_CERT_DURATION

        server_public_key, server_private_key = \
            asymmetric.generate_pair('rsa', bit_size=2048)

        save_model.private_key = asymmetric.dump_private_key(
            end_entity_private_key, None)
        save_model.public_key = asymmetric.dump_public_key(
            end_entity_public_key)
        save_model.public_certificate = pem_armor_certificate(
            end_entity_certificate)

        save_model.server_sign_key = asymmetric.dump_private_key(
            server_private_key, None)
        save_model.server_public_key = asymmetric.dump_public_key(
            server_public_key)

        logger.debug("SimpleCA: New certificate for %s is %r" %
                     (domain, save_model.public_certificate))
        return save_model
    def test_build_basic_crl(self):
        root_private_key = asymmetric.load_private_key(os.path.join(fixtures_dir, 'root.key'), 'password123')
        root_certificate = asymmetric.load_certificate(os.path.join(fixtures_dir, 'root.crt'))

        builder = CertificateListBuilder(
            'http://crl.example.com',
            root_certificate,
            50000
        )
        revoked_at = datetime(2015, 8, 1, 12, 0, 0, tzinfo=timezone.utc)
        builder.add_certificate(29232181, revoked_at, 'key_compromise')
        certificate_list = builder.build(root_private_key)
        der_bytes = certificate_list.dump()

        new_cert_list = crl.CertificateList.load(der_bytes)
        tbs_cert_list = new_cert_list['tbs_cert_list']
        revoked_certificates = tbs_cert_list['revoked_certificates']

        now = datetime.now(timezone.utc)

        self.assertEqual('v3', tbs_cert_list['version'].native)
        self.assertEqual('rsassa_pkcs1v15', tbs_cert_list['signature'].signature_algo)
        self.assertEqual('sha256', tbs_cert_list['signature'].hash_algo)
        self.assertEqual(root_certificate.asn1.subject, tbs_cert_list['issuer'])
        self.assertEqual(root_certificate.asn1.subject.sha256, tbs_cert_list['issuer'].sha256)
        self.assertGreaterEqual(now, tbs_cert_list['this_update'].native)
        self.assertLess(now, tbs_cert_list['next_update'].native)
        self.assertEqual(set(['issuing_distribution_point']), new_cert_list.critical_extensions)

        self.assertEqual(1, len(revoked_certificates))
        revoked_cert = revoked_certificates[0]
        self.assertEqual(29232181, revoked_cert['user_certificate'].native)
        self.assertEqual(revoked_at, revoked_cert['revocation_date'].native)
        self.assertEqual(set(), revoked_cert.critical_extensions)
        self.assertEqual('key_compromise', revoked_cert.crl_reason_value.native)
        self.assertEqual(None, revoked_cert.invalidity_date_value)
        self.assertEqual(None, revoked_cert.certificate_issuer_value)
        self.assertEqual(None, revoked_cert.issuer_name)

        self.assertEqual(None, new_cert_list.issuer_alt_name_value)
        self.assertEqual(50000, new_cert_list.crl_number_value.native)
        self.assertEqual(None, new_cert_list.delta_crl_indicator_value)
        self.assertEqual('full_name', new_cert_list.issuing_distribution_point_value['distribution_point'].name)
        self.assertEqual(
            'uniform_resource_identifier',
            new_cert_list.issuing_distribution_point_value['distribution_point'].chosen[0].name
        )
        self.assertEqual(
            'http://crl.example.com',
            new_cert_list.issuing_distribution_point_value['distribution_point'].chosen[0].native
        )
        self.assertEqual(root_certificate.asn1.key_identifier, new_cert_list.authority_key_identifier)
        self.assertEqual(None, new_cert_list.freshest_crl_value)
        self.assertEqual(None, new_cert_list.authority_information_access_value)
def isRevoked(url, rawCert):
    subject_cert = asymmetric.load_certificate(base64.b64decode(rawCert))
    builder = OCSPRequestBuilder(subject_cert, issuerCerts[url])
    ocsp_request = builder.build()
    url = urlparse(url)
    headers = {}
    conn = httplib.HTTPConnection(url.netloc)
    conn.request("POST", url.path, ocsp_request.dump(), headers)
    res = conn.getresponse().read()
    ocspResponseClass = ocsp.OCSPResponse.load(res)
    return (ocspResponseClass.response_data['responses'][0]['cert_status'].name != 'good')
Example #37
0
def handle_ocsp_requests(caid):

    # Import section (specifically for OCSP)
    from asn1crypto.util import timezone
    from asn1crypto.ocsp import OCSPRequest
    from oscrypto import asymmetric
    from ocspbuilder import OCSPResponseBuilder

    # Getting CA information
    key = Key.query.filter_by(ca=caid).first()
    if not key:
        abort(config.http_notfound, {"message": config.error_pkey_notfound})
    private, public = key.dump(config.path_keys)
    with open(private, "rb") as f:
        issuer_key = asymmetric.load_private_key(f.read(), "testtest")
    with open(public, "rb") as f:
        issuer_cert = asymmetric.load_certificate(f.read())

    # Parsing the OCSP request
    ocsp = OCSPRequest.load(request.get_data())
    tbs_request = ocsp['tbs_request']
    request_list = tbs_request['request_list']
    if len(request_list) != 1:
        abort(config.http_notimplemented,
              {"message": config.error_multiple_requests})
    single_request = request_list[0]  # TODO: Support more than one request
    req_cert = single_request['req_cert']
    serial = hex(req_cert['serial_number'].native)[2:]

    # Getting certificate
    cert = Certificate.query.filter_by(serial=serial).first()
    if not cert:
        abort(config.http_notfound, {"message": config.error_cert_notfound})
    cert_path = cert.dump(config.path_keys)
    with open(cert_path, "rb") as f:
        subject_cert = asymmetric.load_certificate(f.read())

    # A response for a certificate in good standing
    builder = OCSPResponseBuilder(u'successful', subject_cert, u'good')
    ocsp_response = builder.build(issuer_key, issuer_cert)
    return ocsp_response.dump()
    def test_build_no_certificate(self):
        issuer_key = asymmetric.load_private_key(os.path.join(fixtures_dir, 'test.key'))
        issuer_cert = asymmetric.load_certificate(os.path.join(fixtures_dir, 'test.crt'))
        subject_cert = asymmetric.load_certificate(os.path.join(fixtures_dir, 'test-inter.crt'))

        with self.assertRaisesRegexp(ValueError, 'must be set if the response_status is "successful"'):
            builder = OCSPResponseBuilder('successful', subject_cert, 'good')
            builder.certificate = None
            ocsp_response = builder.build(issuer_key, issuer_cert)

        with self.assertRaisesRegexp(ValueError, 'must be set if the response_status is "successful"'):
            builder = OCSPResponseBuilder('successful', subject_cert, 'good')
            builder.certificate_status = None
            ocsp_response = builder.build(issuer_key, issuer_cert)

        with self.assertRaisesRegexp(ValueError, 'must be set if the response_status is "successful"'):
            builder = OCSPResponseBuilder('successful', subject_cert)
            ocsp_response = builder.build(issuer_key, issuer_cert)

        with self.assertRaisesRegexp(ValueError, 'must be set if the response_status is "successful"'):
            builder = OCSPResponseBuilder('successful', None, 'good')
            ocsp_response = builder.build(issuer_key, issuer_cert)
    def test_build_basic_crl(self):
        root_private_key = asymmetric.load_private_key(os.path.join(fixtures_dir, "root.key"), "password123")
        root_certificate = asymmetric.load_certificate(os.path.join(fixtures_dir, "root.crt"))

        builder = CertificateListBuilder("http://crl.example.com", root_certificate, 50000)
        revoked_at = datetime(2015, 8, 1, 12, 0, 0, tzinfo=timezone.utc)
        builder.add_certificate(29232181, revoked_at, "key_compromise")
        certificate_list = builder.build(root_private_key)
        der_bytes = certificate_list.dump()

        new_cert_list = crl.CertificateList.load(der_bytes)
        tbs_cert_list = new_cert_list["tbs_cert_list"]
        revoked_certificates = tbs_cert_list["revoked_certificates"]

        now = datetime.now(timezone.utc)

        self.assertEqual("v3", tbs_cert_list["version"].native)
        self.assertEqual("rsassa_pkcs1v15", tbs_cert_list["signature"].signature_algo)
        self.assertEqual("sha256", tbs_cert_list["signature"].hash_algo)
        self.assertEqual(root_certificate.asn1.subject, tbs_cert_list["issuer"])
        self.assertEqual(root_certificate.asn1.subject.sha256, tbs_cert_list["issuer"].sha256)
        self.assertGreaterEqual(now, tbs_cert_list["this_update"].native)
        self.assertLess(now, tbs_cert_list["next_update"].native)
        self.assertEqual(set(["issuing_distribution_point"]), new_cert_list.critical_extensions)

        self.assertEqual(1, len(revoked_certificates))
        revoked_cert = revoked_certificates[0]
        self.assertEqual(29232181, revoked_cert["user_certificate"].native)
        self.assertEqual(revoked_at, revoked_cert["revocation_date"].native)
        self.assertEqual(set(), revoked_cert.critical_extensions)
        self.assertEqual("key_compromise", revoked_cert.crl_reason_value.native)
        self.assertEqual(None, revoked_cert.invalidity_date_value)
        self.assertEqual(None, revoked_cert.certificate_issuer_value)
        self.assertEqual(None, revoked_cert.issuer_name)

        self.assertEqual(None, new_cert_list.issuer_alt_name_value)
        self.assertEqual(50000, new_cert_list.crl_number_value.native)
        self.assertEqual(None, new_cert_list.delta_crl_indicator_value)
        self.assertEqual("full_name", new_cert_list.issuing_distribution_point_value["distribution_point"].name)
        self.assertEqual(
            "uniform_resource_identifier",
            new_cert_list.issuing_distribution_point_value["distribution_point"].chosen[0].name,
        )
        self.assertEqual(
            "http://crl.example.com",
            new_cert_list.issuing_distribution_point_value["distribution_point"].chosen[0].native,
        )
        self.assertEqual(root_certificate.asn1.key_identifier, new_cert_list.authority_key_identifier)
        self.assertEqual(None, new_cert_list.freshest_crl_value)
        self.assertEqual(None, new_cert_list.authority_information_access_value)
Example #40
0
    def __init__(self, issuer_cert: str, responder_cert: str, responder_key: str,
                       validate_func: ValidateFunc, cert_retrieve_func: CertRetrieveFunc,
                       next_update_days: int = 7):
        """
        Create a new OCSPResponder instance.

        :param issuer_cert: Path to the issuer certificate.
        :param responder_cert: Path to the certificate of the OCSP responder
            with the `OCSP Signing` extension.
        :param responder_key: Path to the private key belonging to the
            responder cert.
        :param validate_func: A function that - given a certificate serial -
            will return the appropriate :class:`CertificateStatus` and -
            depending on the status - a revocation datetime.
        :param cert_retrieve_func: A function that - given a certificate serial -
            will return the corresponding certificate as a string.
        :param next_update_days: The ``nextUpdate`` value that will be written
            into the response. Default: 7 days.

        """
        # Certs and keys
        self._issuer_cert = asymmetric.load_certificate(issuer_cert)
        self._responder_cert = asymmetric.load_certificate(responder_cert)
        self._responder_key = asymmetric.load_private_key(responder_key)

        # Functions
        self._validate = validate_func
        self._cert_retrieve = cert_retrieve_func

        # Next update
        self._next_update_days = next_update_days

        # Bottle
        self._app = Bottle()

        # Initialize routing
        self._route()
Example #41
0
# coding: utf-8
from __future__ import unicode_literals, division, absolute_import, print_function

import os

from oscrypto import asymmetric
from certbuilder import CertificateBuilder


fixtures_dir = os.path.join(os.path.dirname(__file__), '..', 'tests', 'fixtures')


root_ca_private_key = asymmetric.load_private_key(os.path.join(fixtures_dir, 'test.key'))
root_ca_certificate = asymmetric.load_certificate(os.path.join(fixtures_dir, 'test.crt'))

root_ocsp_public_key, root_ocsp_private_key = asymmetric.generate_pair('rsa', bit_size=2048)

with open(os.path.join(fixtures_dir, 'test-ocsp.key'), 'wb') as f:
    f.write(asymmetric.dump_private_key(root_ocsp_private_key, 'password', target_ms=20))

builder = CertificateBuilder(
    {
        'country_name': 'US',
        'state_or_province_name': 'Massachusetts',
        'locality_name': 'Newbury',
        'organization_name': 'Codex Non Sufficit LC',
        'organization_unit_name': 'Testing',
        'common_name': 'CodexNS OCSP Responder',
    },
    root_ocsp_public_key
)
Example #42
0
 def test_dump_certificate(self):
     cert = asymmetric.load_certificate(os.path.join(fixtures_dir, 'keys/test.crt'))
     pem_serialized = asymmetric.dump_certificate(cert)
     cert_reloaded = asymmetric.load_certificate(pem_serialized)
     self.assertIsInstance(cert_reloaded, asymmetric.Certificate)
     self.assertEqual('rsa', cert_reloaded.algorithm)
Example #43
0
 def test_cert_ec_attributes(self):
     cert = asymmetric.load_certificate(os.path.join(fixtures_dir, 'keys/test-ec-named.crt'))
     self.assertEqual(256, cert.bit_size)
     self.assertEqual(32, cert.byte_size)
     self.assertEqual('secp256r1', cert.curve)
     self.assertEqual('ec', cert.algorithm)
Example #44
0
    def _build_ocsp_response(self, ocsp_request: OCSPRequest) -> OCSPResponse:
        """
        Create and return an OCSP response from an OCSP request.
        """
        # Get the certificate serial
        tbs_request = ocsp_request['tbs_request']
        request_list = tbs_request['request_list']
        if len(request_list) != 1:
            logger.warning('Received OCSP request with multiple sub requests')
            raise NotImplemented('Combined requests not yet supported')
        single_request = request_list[0]  # TODO: Support more than one request
        req_cert = single_request['req_cert']
        serial = req_cert['serial_number'].native

        # Check certificate status
        try:
            certificate_status, revocation_date = self._validate(serial)
        except Exception as e:
            logger.exception('Could not determine certificate status: %s', e)
            return self._fail(ResponseStatus.internal_error)

        # Retrieve certificate
        try:
            subject_cert_contents = self._cert_retrieve(serial)
        except Exception as e:
            logger.exception('Could not retrieve certificate with serial %s: %s', serial, e)
            return self._fail(ResponseStatus.internal_error)

        # Parse certificate
        try:
            subject_cert = asymmetric.load_certificate(subject_cert_contents.encode('utf8'))
        except Exception as e:
            logger.exception('Returned certificate with serial %s is invalid: %s', serial, e)
            return self._fail(ResponseStatus.internal_error)

        # Build the response
        builder = OCSPResponseBuilder(**{
            'response_status': ResponseStatus.successful.value,
            'certificate': subject_cert,
            'certificate_status': certificate_status.value,
            'revocation_date': revocation_date,
        })

        # Parse extensions
        for extension in tbs_request['request_extensions']:
            extn_id = extension['extn_id'].native
            critical = extension['critical'].native
            value = extension['extn_value'].parsed

            # This variable tracks whether any unknown extensions were encountered
            unknown = False

            # Handle nonce extension
            if extn_id == 'nonce':
                builder.nonce = value.native

            # That's all we know
            else:
                unknown = True

            # If an unknown critical extension is encountered (which should not
            # usually happen, according to RFC 6960 4.1.2), we should throw our
            # hands up in despair and run.
            if unknown is True and critical is True:
                logger.warning('Could not parse unknown critical extension: %r',
                        dict(extension.native))
                return self._fail(ResponseStatus.internal_error)

            # If it's an unknown non-critical extension, we can safely ignore it.
            elif unknown is True:
                logger.info('Ignored unknown non-critical extension: %r', dict(extension.native))

        # Set certificate issuer
        builder.certificate_issuer = self._issuer_cert

        # Set next update date
        builder.next_update = datetime.now(timezone.utc) + timedelta(days=self._next_update_days)

        return builder.build(self._responder_key, self._responder_cert)
Example #45
0
 def test_cert_attributes(self):
     cert = asymmetric.load_certificate(os.path.join(fixtures_dir, 'keys/test.crt'))
     self.assertEqual(2048, cert.bit_size)
     self.assertEqual(256, cert.byte_size)
     self.assertEqual('rsa', cert.algorithm)
Example #46
0
    def get_ocsp_response(self, data):
        try:
            ocsp_request = asn1crypto.ocsp.OCSPRequest.load(data)

            tbs_request = ocsp_request['tbs_request']
            request_list = tbs_request['request_list']
            if len(request_list) != 1:
                log.error('Received OCSP request with multiple sub requests')
                raise NotImplemented('Combined requests not yet supported')
            single_request = request_list[0]  # TODO: Support more than one request
            req_cert = single_request['req_cert']
            serial = serial_from_int(req_cert['serial_number'].native)
        except Exception as e:
            log.exception('Error parsing OCSP request: %s', e)
            return self.fail('malformed_request')

        ca = CertificateAuthority.objects.get(serial=self.ca_serial)

        try:
            cert = Certificate.objects.filter(ca=ca).get(serial=serial)
        except Certificate.DoesNotExist:
            log.warn('OCSP request for unknown cert received.')
            return self.fail('internal_error')  # TODO: return a 'unkown' response instead

        builder = OCSPResponseBuilder(
            response_status='successful',  # ResponseStatus.successful.value,
            certificate=load_certificate(force_bytes(cert.pub)),
            certificate_status=cert.ocsp_status,
            revocation_date=cert.revoked_date,
        )

        # Parse extensions
        for extension in tbs_request['request_extensions']:
            extn_id = extension['extn_id'].native
            critical = extension['critical'].native
            value = extension['extn_value'].parsed

            # This variable tracks whether any unknown extensions were encountered
            unknown = False

            # Handle nonce extension
            if extn_id == 'nonce':
                builder.nonce = value.native

            # That's all we know
            else:
                unknown = True

            # If an unknown critical extension is encountered (which should not
            # usually happen, according to RFC 6960 4.1.2), we should throw our
            # hands up in despair and run.
            if unknown is True and critical is True:
                log.warning('Could not parse unknown critical extension: %r',
                        dict(extension.native))
                return self._fail('internal_error')

            # If it's an unknown non-critical extension, we can safely ignore it.
            elif unknown is True:
                log.info('Ignored unknown non-critical extension: %r', dict(extension.native))

        builder.certificate_issuer = load_certificate(force_bytes(ca.pub))
        builder.next_update = timezone.now() + timedelta(days=1)

        responder_cert = self.get_responder_cert()

        return builder.build(self.responder_key, responder_cert)
Example #47
0
def load_cert(name):
    return asymmetric.load_certificate(path.join(
        certs_dir,
        '{}.crt'.format(name)
    ))
Example #48
0
from oscrypto import asymmetric
from ocspbuilder import OCSPRequestBuilder
from pyasn1_modules.rfc2560 import OCSPResponse, BasicOCSPResponse
from OpenSSL import crypto
import OpenSSL


id_cert_path = 'certs/pem/citi.co.in.pem'
issuer_cert_path = 'certs/pem/citi.intermediate.ca.pem'

id_cert_buf = open(id_cert_path, 'r').read()
issuer_cert_buf = open(issuer_cert_path, 'r').read()

id_cert = asymmetric.load_certificate(id_cert_buf)
issuer_cert = asymmetric.load_certificate(issuer_cert_buf)

id_cert_filebuf = open(id_cert_path, 'r').read()
id_cert_x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, id_cert_filebuf)

#print dir(id_cert_x509)
#print id_cert_x509.get_serial_number()
id_cert_serial_number = format(id_cert_x509.get_serial_number(), 'x')
print "Checking OCSP status for cert : " + id_cert_serial_number
print '\n'

builder = OCSPRequestBuilder(id_cert, issuer_cert)
ocsp_request = builder.build()
#print type(ocsp_request)

ocsp_req_dump = ocsp_request.dump()