Skip to main content

Async ACME client implementation

Project description

aioacme

PyPI - Status PyPI PyPI - Python Version PyPI - License CI Status codecov docs

Simple async client for ACME protocol.

Installation

pip install aioacme

Usage

Issue certificate with DNS-01 challenge:

import asyncio

import aioacme
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import ec, rsa

async def main():
    account_key = serialization.load_pem_private_key(...)
    
    async with aioacme.Client(
        account_key=account_key, 
        directory_url=aioacme.LETS_ENCRYPT_STAGING_DIRECTORY
    ) as client:
        order = await client.new_order([aioacme.Identifier("example.com")])
        
        for authorization_uri in order.authorizations:
            authorization = await client.get_authorization(authorization_uri)
            
            if authorization.status is aioacme.AuthorizationStatus.valid:
                # authorization reused
                continue
            
            challenge = next(
                c for c in authorization.challenges if c.type is aioacme.ChallengeType.dns01
            )
            
            domain = client.get_dns_challenge_domain(authorization.identifier.value)
            validation = client.get_dns_challenge_validation(challenge.token)
            
            print(f"Please add TXT record {domain} with the following content: {validation}")
            input("Press Enter when TXT record is created")
            
            await client.answer_challenge(challenge.url)
            
            while authorization.status not in (
                aioacme.AuthorizationStatus.valid,
                aioacme.AuthorizationStatus.invalid
            ):
                await asyncio.sleep(1)
                authorization = await client.get_authorization(authorization_uri)
            
            if authorization.status is aioacme.AuthorizationStatus.invalid:
                raise Exception(f"Authorization status is invalid: {authorization}")
            
        key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
        csr = (
            x509.CertificateSigningRequestBuilder()
            .subject_name(x509.Name([
                x509.NameAttribute(x509.NameOID.COMMON_NAME, "example.com")
            ]))
            .add_extension(x509.SubjectAlternativeName([
                x509.DNSName("example.com")
            ]), critical=False)
            .sign(key, hashes.SHA256())
        )
        order = await client.finalize_order(order.finalize, csr)
        
        while order.status not in {aioacme.OrderStatus.valid, aioacme.OrderStatus.invalid}:
            await asyncio.sleep(1)
            order = await client.get_order(order.uri)
            
        if order.status is aioacme.OrderStatus.invalid:
            raise Exception(f"Order status is invalid: {order}")
        
        cert = await client.get_certificate(order.certificate)
        print(cert.decode("ascii"))
        
        
asyncio.run(main())

License

This project is licensed under the MIT License - see the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aioacme-0.6.0.tar.gz (82.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aioacme-0.6.0-py3-none-any.whl (15.1 kB view details)

Uploaded Python 3

File details

Details for the file aioacme-0.6.0.tar.gz.

File metadata

  • Download URL: aioacme-0.6.0.tar.gz
  • Upload date:
  • Size: 82.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for aioacme-0.6.0.tar.gz
Algorithm Hash digest
SHA256 4fbb9f71e54ad4d7f7a7203959b2cc5c6b9ba82f1c2e0afafcf2fb2dd9c5310c
MD5 99ae31ff96ae3a2ddb0fd931ed36516b
BLAKE2b-256 2b13077688062f1a157bfd3fe9429a948e403e614d9638e9fdbda383361078c7

See more details on using hashes here.

Provenance

The following attestation bundles were made for aioacme-0.6.0.tar.gz:

Publisher: publish.yml on tkukushkin/aioacme

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file aioacme-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: aioacme-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 15.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for aioacme-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9fc33c36395f344e3cac83071571e409a6af7c9cf66c3b57578784b16e9371da
MD5 2224c5835510cb1dfcec898182e1bda2
BLAKE2b-256 6aeed1397683b92566e2e7e96be0d1a2b081a46b930e8d922c2e36d25479f05e

See more details on using hashes here.

Provenance

The following attestation bundles were made for aioacme-0.6.0-py3-none-any.whl:

Publisher: publish.yml on tkukushkin/aioacme

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page