Пример #1
0
    def revoke_certificate(self, cert_id, delete=False):
        cert_db = Certificate.query.get(cert_id)
        order_db = Order.query.get(cert_db.order_id)

        if cert_db.status == 'revoked':
            status = "This certificate is already revoked"
            print(status)
            return False, status

        certificate = crypto.load_pem_certificate(cert_db.body.encode('ASCII'))
        print("Revoking certificate for:")
        for domain in crypto.get_certificate_domains(certificate):
            print("     {}".format(domain))

        certificate = crypto.load_cert_for_revoke(cert_db.body.encode('ASCII'))
        try:
            self.client.revoke(certificate, 0)
            print("Certificate {} revoked.".format(cert_db.id))
            order_db.status = 'revoked'
            cert_db.status = 'revoked'
            if delete:
                print("Deleting certificate from database")
                database.delete(cert_db)
                order_db.resolved_cert_id = None
            else:
                database.add(cert_db)
            database.add(order_db)
            status = 'Revoked'
            print(status)
            return True, status
        except IOError:
            status = "Revoke failed"
            print(status)
            return False, status
Пример #2
0
def revoke_certificate(account_id: int, cert_id: int, delete: bool = False):
    account = Account.query.get(account_id)
    cert_db = Certificate.query.get(cert_id)
    
    if cert_db:
        order_db = Order.query.get(cert_db.order_id)

        if cert_db.status == 'revoked':
            if delete:
                database.delete(cert_db)
                order_db.resolved_cert_id = None
                database.add(order_db)
                status = "Deleted already revoked certificate"
                print(status)
                return True, status

            status = "This certificate is already revoked"
            print(status)
            return False, status

        if order_db.account_id != account_id:
            status = "This certificate does not belong to this account"
            print(status)
            return False, status

        acme = AcmeDnsHandler(account.id)
        return acme.revoke_certificate(cert_id, delete)
    
    else:
        status = "Certificate with id: {} does not exist".format(cert_id)
        print(status)
        return False, status
Пример #3
0
    def setUp(self):
        self.app = create_app(config_name="testing")
        self.client = self.app.test_client

        with self.app.app_context():
            db.create_all()
            user = users.User('admin', 'admin', True)
            database.add(user)
Пример #4
0
def init(pwd='changeme'):
    """Creates the db tables and admin user"""
    db.create_all()
    if users.User.query.filter_by(username='******').first() is not None:
        print("Admin user already exists")
    else:
        if not pwd:
            pwd = input("Enter password for admin user: ")
        user = users.User('admin', pwd, True)
        database.add(user)
Пример #5
0
    def setup_acme_account(self,
                           user_id,
                           email=None,
                           server=None,
                           rsa_key=None,
                           organization: str = None,
                           organizational_unit: str = None,
                           country: str = None,
                           state: str = None,
                           location: str = None):
        if not email:
            email = config.CERTIFIRE_EMAIL
        if not server:
            server = config.LETS_ENCRYPT_PRODUCTION
        if not rsa_key:
            rsa_key = crypto.generate_rsa_key()

        account = Account(user_id,
                          email,
                          server,
                          organization=organization,
                          organizational_unit=organizational_unit,
                          country=country,
                          state=state,
                          location=location)
        key = jose.JWKRSA(key=rsa_key)
        net = ClientNetwork(key, account=None, timeout=3600)
        client = BackwardsCompatibleClientV2(net, key, account.directory_uri)
        registration = client.new_account_and_tos(
            messages.NewRegistration.from_data(email=email))
        account.key = crypto.export_private_key(rsa_key).decode("utf-8")
        account.uri = registration.uri
        account.contents = json.dumps(registration.to_json())

        database.add(account)
        self.account = account
        self.key = key
        self.client = client
        return account
Пример #6
0
    def issue_certificate(self, final_order, order_id, destination_id=None):
        order_db = Order.query.get(order_id)
        cert_db = Certificate(user_id=order_db.user_id,
                              order_id=order_db.id,
                              status='pending',
                              csr=order_db.csr,
                              private_key=order_db.key)
        database.add(cert_db)

        pem_certificate, pem_chain = crypto.extract_cert_and_chain(
            final_order.fullchain_pem)
        certificate = crypto.load_pem_certificate(pem_certificate.encode())
        chain = crypto.load_pem_certificate(pem_chain.encode())

        cert_db.body = crypto.export_pem_certificate(certificate).decode(
            'UTF-8')
        cert_db.chain = crypto.export_pem_certificate(certificate).decode(
            'UTF-8')
        cert_db.chain += crypto.export_pem_certificate(chain).decode('UTF-8')
        cert_db.intermediate = crypto.export_pem_certificate(chain).decode(
            'UTF-8')
        cert_db.expiry = certificate.not_valid_after.strftime(
            config.EXPIRATION_FORMAT)
        cert_db.fingerprint = binascii.hexlify(
            certificate.fingerprint(crypto.hashes.SHA256())).decode('ascii')

        print("Expires: {}".format(cert_db.expiry))
        print("SHA256: {}".format(cert_db.fingerprint))

        order_db.status = 'valid'
        cert_db.status = 'valid'
        order_db.resolved_cert_id = cert_db.id
        print("Resolved certificate id: {}".format(order_db.resolved_cert_id))

        if destination_id:
            destination_db = Destination.query.get(destination_id)
            if destination_db.certDestinationPath:
                destination_db.upload(cert_db.body, cert_db.private_key,
                                      cert_db.intermediate)

        database.add(order_db)
        database.add(cert_db)

        return cert_db.id
Пример #7
0
    def create_order(self,
                     csr_pem,
                     provider,
                     order_id,
                     destination_id,
                     reissue=False):
        order_db = Order.query.get(order_id)
        destination_db = Destination.query.get(destination_id)
        if order_db.status == 'revoked' and not reissue:
            print("Cannot issue for order with revoked certificate {}".format(
                order_db.resolved_cert_id))
            return order_db.resolved_cert_id

        if order_db.status == 'valid' and reissue:
            print("Revoking existing certificate {}".format(
                order_db.resolved_cert_id))
            self.revoke_certificate(order_db.resolved_cert_id)

        order = self.client.new_order(csr_pem)
        pending_challenges = self.get_pending_challenges(order, 'http-01')

        if not pending_challenges:
            if reissue:
                deadline = datetime.datetime.now() + datetime.timedelta(
                    seconds=10)
                final_order = self.client.poll_and_finalize(order, deadline)
                order_db.contents = json.dumps(final_order.to_json())
                order_db.status = 'ready'
                database.add(order_db)
                cert_id = self.issue_certificate(final_order, order_id,
                                                 destination_id)

                return cert_id

            print("No pending challenges, reusing existing order")
            orderr = self.get_orderResource(order_id)
            if orderr.fullchain_pem is not None:
                if order_db.resolved_cert_id:
                    print("Certificate already issued")
                    return order_db.resolved_cert_id
                else:
                    print("Generating Certificate")
                    return self.issue_certificate(orderr, order_id,
                                                  destination_id)
            else:
                print("Reissuing certificate")

        order_db.uri = order.uri
        order_db.contents = json.dumps(order.to_json())
        database.add(order_db)

        destination_db = Destination.query.get(destination_id)
        print("Writing TXT Records")
        for domain, challenge in pending_challenges.items():
            chall_path = challenge.chall.path
            response, validation = challenge.response_and_validation(self.key)
            destination_db.upload_acme_token(chall_path, validation)
        time.sleep(5)

        for domain, challenge in pending_challenges.items():
            response = challenge.response(self.key)
            verified = response.simple_verify(challenge.chall, domain,
                                              self.key.public_key())
            if not verified:
                print("{} not verified".format(domain))

            #res = self.client.answer_challenge(challenge, response)
            time.sleep(5)
            print("Ansering challenge {} with response {}".format(
                challenge.validation(self.key), response.key_authorization))
            res = self.client.answer_challenge(challenge, response)
            print("Got response: {}".format(res.body.status.name))

        print("Finalizing order")
        deadline = datetime.datetime.now() + datetime.timedelta(
            seconds=10 * len(pending_challenges))
        #final_order = self.client.finalize_order(order, deadline)
        final_order = self.client.poll_and_finalize(order, deadline)
        order_db.contents = json.dumps(final_order.to_json())
        order_db.status = 'ready'
        database.add(order_db)

        print("Deleting TXT Records")
        for domain, challenge in pending_challenges.items():
            chall_path = challenge.chall.path
            destination_db.delete_acme_token(chall_path)

        cert_id = self.issue_certificate(final_order, order_id, destination_id)

        return cert_id
Пример #8
0
def create_order(account_id: int,
                 destination_id: int = None,
                 domains: list = None,
                 type: str = None,
                 provider: str = None,
                 email: str = None,
                 organization: str = None,
                 organizational_unit: str = None,
                 country: str = None,
                 state: str = None,
                 location: str = None,
                 reissue: bool = False,
                 csr: str = None,
                 key: str = None):

    account = Account.query.get(account_id)
    if not account:
        print("Account {} not found".format(account_id))
        return False, 0

    type = type if type else config.DEFAULT_AUTH_TYPE
    provider = provider if provider else config.DEFAULT_DNS
    email = email if email else account.email
    organization = organization if organization else account.organization
    organizational_unit = organizational_unit if organizational_unit else account.organizational_unit
    country = country if country else account.country
    state = state if state else account.state
    location = location if location else account.location

    if type == 'dns':
        if provider not in config.VALID_DNS_PROVIDERS:
            print("Invalid DNS Provider")
            return False, 0
        acme = AcmeDnsHandler(account.id)
    if type == 'sftp':
        acme = AcmeHttpHandler(account.id)

    if not domains:
        if not destination_id:
            print("No domains or destinations provided")
            return False, 0
        destination_db = Destination.query.get(destination_id)
        domains = [destination_db.host]
    else:
        if destination_id:
            destination_db = Destination.query.get(destination_id)
            if destination_db.host not in domains:
                domains = [destination_db.host] + domains

    domains_hash = hashlib.sha256(
        "_".join(domains).encode("ascii")).hexdigest()
    check = database.get_all(Order, domains_hash, 'hash')
    for order in check:
        if order.email == email and order.type == type and order.account_id == account.id:
            print("Order {} exists for given email: {} and account_id: {}.".format(
                order.uri, email, account.id))
            #acme_order = acme.create_order(order.csr, order.provider, order.id)
            AppContextThread(target=acme.create_order, args=(
                order.csr, order.provider, order.id, destination_id, reissue)).start()
            return False, order.id


    if not csr or key:
        csr, key = acme.generate_csr(
            domains, email, organization, organizational_unit, country, state, location)

    order = Order(destination_id, domains, type, provider, account.id, account.user_id, domains_hash,
                  csr, key, email, organization, organizational_unit, country, state, location)
    database.add(order)

    #acme_order = acme.create_order(csr, provider, order.id)
    AppContextThread(target=acme.create_order, args=(
        csr, provider, order.id, destination_id)).start()
    return True, order.id