Example #1
0
    def enroll(self, csr):
        """ enroll certificate """
        self.logger.debug('CAhandler.enroll()')

        cert_bundle = None
        cert_raw = None

        error = self.check_config()

        if not error:
            try:
                # prepare the CSR
                csr = build_pem_file(self.logger, None, b64_url_recode(self.logger, csr), None, True)

                # load ca cert and key
                (ca_key, ca_cert) = self.load_ca_key_cert()

                # creating a rest form CSR
                req = crypto.load_certificate_request(crypto.FILETYPE_PEM, csr)
                # sign csr
                cert = crypto.X509()
                cert.gmtime_adj_notBefore(0)
                cert.gmtime_adj_notAfter(self.cert_validity_days * 86400)
                cert.set_issuer(ca_cert.get_subject())
                cert.set_subject(req.get_subject())
                cert.set_pubkey(req.get_pubkey())
                cert.set_serial_number(uuid.uuid4().int)
                # cert.set_serial_number(uts_now())
                cert.add_extensions(req.get_extensions())
                cert.add_extensions([
                    crypto.X509Extension(convert_string_to_byte('authorityKeyIdentifier'), False, convert_string_to_byte('keyid:always'), issuer=ca_cert),
                    crypto.X509Extension(convert_string_to_byte('extendedKeyUsage'), False, convert_string_to_byte('clientAuth')),
                ])
                cert.sign(ca_key, 'sha256')
                serial = cert.get_serial_number()
                # save cert if needed
                if self.cert_save_path and self.cert_save_path != None:
                    # create cert-store dir if not existing
                    if not os.path.isdir(self.cert_save_path):
                        self.logger.debug('create certsavedir {0}'.format(self.cert_save_path))
                        os.mkdir(self.cert_save_path)

                    with open('{0}/{1}.pem'.format(self.cert_save_path, str(serial)), 'wb') as fso:
                        fso.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
                # create bundle and raw cert
                cert_bundle = self.generate_pem_cert_chain(convert_byte_to_string(crypto.dump_certificate(crypto.FILETYPE_PEM, cert)), open(self.issuer_dict['cert']).read())
                cert_raw = convert_byte_to_string(base64.b64encode(crypto.dump_certificate(crypto.FILETYPE_ASN1, cert)))

            except BaseException as err:
                error = err

        self.logger.debug('Certificate.enroll() ended')
        return(error, cert_bundle, cert_raw)
Example #2
0
    def _certificate_chain_verify(self, cert, ca_cert):
        """ verify certificate chain """
        self.logger.debug('CAhandler._certificate_chain_verify()')

        error = None
        pem_file = build_pem_file(self.logger, None, b64_url_recode(self.logger, cert), True)

        try:
            cert = crypto.load_certificate(crypto.FILETYPE_PEM, pem_file)
        except BaseException as err_:
            cert = None
            error = err_

        if not error:
            #Create a certificate store and add ca cert(s)
            try:
                store = crypto.X509Store()
                store.add_cert(ca_cert)
            except BaseException:
                error = 'issuing certificate could not be added to trust-store'

            if not error:
                # add ca chain to truststore
                for cert_name in self.ca_cert_chain_list:
                    try:
                        with open(cert_name, 'r') as fso:
                            cain_cert = crypto.load_certificate(crypto.FILETYPE_PEM, fso.read())
                        store.add_cert(cain_cert)
                    except BaseException:
                        error = 'certificate {0} could not be added to trust store'.format(cert_name)

            if not error:
                # Create a certificate context using the store and the downloaded certificate
                store_ctx = crypto.X509StoreContext(store, cert)
                # Verify the certificate, returns None if it can validate the certificate
                try:
                    # pylint: disable=E1111
                    result = store_ctx.verify_certificate()
                except BaseException as err_:
                    result = str(err_)
            else:
                result = error
        else:
            result = 'certificate could not get parsed'

        self.logger.debug('CAhandler._certificate_chain_verify() ended with {0}'.format(result))
        return result
Example #3
0
    def enroll(self, csr):
        """ enroll certificate  """
        self.logger.debug('CAhandler.enroll()')

        cert_bundle = None
        cert_raw = None

        error = self._config_check()

        if not error:

            request_name = self._requestname_get(csr)

            # import CSR to database
            _csr_info = self._csr_import(csr, request_name)

            # prepare the CSR to be signed
            csr = build_pem_file(self.logger, None, b64_url_recode(self.logger, csr), None, True)

            # load ca cert and key
            (ca_key, ca_cert, ca_id) = self._ca_load()

            if ca_key and ca_cert:
                # load request
                req = crypto.load_certificate_request(crypto.FILETYPE_PEM, csr)

                # copy cn of request
                subject = req.get_subject()
                # rewrite CN if required
                if not subject.CN:
                    self.logger.debug('rewrite CN to {0}'.format(request_name))
                    subject.CN = request_name

                # create certificate object
                cert = crypto.X509()
                cert.set_pubkey(req.get_pubkey())
                cert.set_version(2)
                cert.set_serial_number(uuid.uuid4().int & (1<<63)-1)
                cert.set_issuer(ca_cert.get_subject())

                # load template if configured
                if self.template_name:
                    (dn_dic, template_dic) = self._template_load()
                else:
                    dn_dic = {}
                    template_dic = {}

                # set cert_validity
                if 'validity' in template_dic:
                    # take validity from template
                    cert_validity = template_dic['validity']
                else:
                    cert_validity = self.cert_validity_days
                cert.gmtime_adj_notBefore(0)
                cert.gmtime_adj_notAfter(cert_validity * 86400)

                # get extension list
                extension_list = self._extension_list_generate(template_dic, cert, ca_cert)
                # add extensions (copy from CSR and take the ones we constructed)
                cert.add_extensions(req.get_extensions())
                cert.add_extensions(extension_list)

                if dn_dic:
                    subject = self._subject_modify(subject, dn_dic)
                cert.set_subject(subject)

                # sign csr
                cert.sign(ca_key, 'sha256')
                serial = cert.get_serial_number()

                # get hsshes
                issuer_hash = ca_cert.subject_name_hash() & 0x7fffffff
                name_hash = cert.subject_name_hash() & 0x7fffffff

                # store certificate
                self._store_cert(ca_id, request_name, '{:X}'.format(serial), convert_byte_to_string(b64_encode(self.logger, crypto.dump_certificate(crypto.FILETYPE_ASN1, cert))), name_hash, issuer_hash)

                cert_bundle = self._pemcertchain_generate(convert_byte_to_string(crypto.dump_certificate(crypto.FILETYPE_PEM, cert)), convert_byte_to_string(crypto.dump_certificate(crypto.FILETYPE_PEM, ca_cert)))
                cert_raw = convert_byte_to_string(b64_encode(self.logger, crypto.dump_certificate(crypto.FILETYPE_ASN1, cert)))

        self.logger.debug('Certificate.enroll() ended')
        return(error, cert_bundle, cert_raw, None)
Example #4
0
    def enroll(self, csr):
        """ enroll certificate """
        self.logger.debug('CAhandler.enroll()')

        cert_bundle = None
        cert_raw = None

        error = self._config_check()

        if not error:
            try:
                # check CN and SAN against black/whitlist
                result = self._csr_check(csr)

                if result:
                    # prepare the CSR
                    csr = build_pem_file(self.logger, None, b64_url_recode(self.logger, csr), None, True)

                    # load ca cert and key
                    (ca_key, ca_cert) = self._ca_load()

                    # load certificate_profile (if applicable)
                    if self.openssl_conf:
                        cert_extension_dic = self._certificate_extensions_load()
                    else:
                        cert_extension_dic = []

                    # creating a rest form CSR
                    req = crypto.load_certificate_request(crypto.FILETYPE_PEM, csr)
                    # sign csr
                    cert = crypto.X509()
                    cert.gmtime_adj_notBefore(0)
                    cert.gmtime_adj_notAfter(self.cert_validity_days * 86400)
                    cert.set_issuer(ca_cert.get_subject())
                    cert.set_subject(req.get_subject())
                    cert.set_pubkey(req.get_pubkey())
                    cert.set_serial_number(uuid.uuid4().int)
                    cert.set_version(2)
                    cert.add_extensions(req.get_extensions())

                    default_extension_list = [
                        crypto.X509Extension(convert_string_to_byte('subjectKeyIdentifier'), False, convert_string_to_byte('hash'), subject=cert),
                        crypto.X509Extension(convert_string_to_byte('authorityKeyIdentifier'), False, convert_string_to_byte('keyid:always'), issuer=ca_cert),
                        crypto.X509Extension(convert_string_to_byte('basicConstraints'), True, convert_string_to_byte('CA:FALSE')),
                        crypto.X509Extension(convert_string_to_byte('extendedKeyUsage'), False, convert_string_to_byte('clientAuth,serverAuth')),
                    ]

                    if cert_extension_dic:
                        try:
                            cert.add_extensions(self._certificate_extensions_add(cert_extension_dic, cert, ca_cert))
                        except BaseException as err_:
                            self.logger.error('CAhandler.enroll() error while loading extensions form file. Use default set.\nerror: {0}'.format(err_))
                            cert.add_extensions(default_extension_list)
                    else:
                        # add keyUsage if it does not exist in CSR
                        ku_is_in = False
                        for ext in req.get_extensions():
                            if convert_byte_to_string(ext.get_short_name()) == 'keyUsage':
                                ku_is_in = True
                        if not ku_is_in:
                            default_extension_list.append(crypto.X509Extension(convert_string_to_byte('keyUsage'), True, convert_string_to_byte('digitalSignature,keyEncipherment')))

                        # add default extensions
                        cert.add_extensions(default_extension_list)

                    cert.sign(ca_key, 'sha256')

                    # store certifiate
                    self._certificate_store(cert)
                    # create bundle and raw cert
                    cert_bundle = self._pemcertchain_generate(convert_byte_to_string(crypto.dump_certificate(crypto.FILETYPE_PEM, cert)), open(self.issuer_dict['issuing_ca_cert']).read())
                    cert_raw = convert_byte_to_string(base64.b64encode(crypto.dump_certificate(crypto.FILETYPE_ASN1, cert)))
                else:
                    error = 'urn:ietf:params:acme:badCSR'

            except BaseException as err:
                self.logger.error('CAhandler.enroll() error: {0}'.format(err))
                error = 'Unknown exception'

        self.logger.debug('CAhandler.enroll() ended')
        return(error, cert_bundle, cert_raw, None)