API

ACME Client

class acmetk.client.AcmeClient(*, directory_url: str, private_key: str, contact: Dict[str, str] = None, server_cert: str = None, kid: str = None, hmac_key: str = None)

ACME compliant client.

__init__(*, directory_url: str, private_key: str, contact: Dict[str, str] = None, server_cert: str = None, kid: str = None, hmac_key: str = None)

Creates an AcmeClient instance.

Parameters
  • directory_url – The ACME server’s directory

  • private_key – Path of the private key to use to register the ACME account. Must be a PEM-encoded RSA or EC key file.

  • contactdict containing the contact info to supply on registration. May contain a key phone and a key email.

  • server_cert – Path of the server certificate to add to the SSL context

  • kid – The external account binding’s key identifier to be used on registration

  • hmac_key – The external account binding’s symmetric encryption key to be used on registration

FINALIZE_DELAY = 3.0

The delay in seconds between finalization attemps.

INVALID_NONCE_RETRIES = 5

The number of times the client should retry when the server returns the error badNonce.

async account_lookup()None

Looks up an account using the stored private key.

Also stores the account internally for subsequent requests.

Raises

acme.messages.Error If no account associated with the private key exists.

async account_register(email: str = None, phone: str = None, kid: str = None, hmac_key: str = None)None

Registers an account with the CA.

Also sends the given contact information and stores the account internally for subsequent requests. If the private key is already registered, then the account is only queried.

It is usually not necessary to call this method as the account is registered or fetched automatically in start().

Parameters
  • email – The contact email

  • phone – The contact phone number

  • kid – The external account binding’s key identifier

  • hmac_key – The external account binding’s symmetric encryption key

Raises

acme.messages.Error If the server rejects any of the contact information, the private key, or the external account binding.

async account_update(**kwargs)None

Updates the account’s contact information.

Parameters

kwargs – Kwargs that are passed to acme.messages.Registration’s constructor. May include a dict contact containing new contact information or status set to acme.messages.STATUS_DEACTIVATED to deactivate the account.

Raises

acme.messages.Error If the server rejects any of the contact info or the status update.

async authorization_get(authorization_url: str)acme.messages.Authorization

Fetches an authorization given its URL.

Parameters

authorization_url – The authorization’s URL.

Raises

aiohttp.ClientResponseError If the authorization does not exist.

Returns

The fetched authorization.

async authorizations_complete(order: acme.messages.Order)None

Completes all authorizations associated with the given order.

Uses one of the registered ChallengeSolver to complete one challenge per authorization.

Parameters

order – Order whose authorizations should be completed.

Raises

CouldNotCompleteChallenge If completion of one of the authorizations’ challenges failed.

async certificate_get(order: acme.messages.Order)str

Downloads the given order’s certificate.

Parameters

order – The order whose certificate to download.

Raises
Returns

The order’s certificate encoded as PEM.

async certificate_revoke(certificate: cryptography.x509.Certificate, reason: acmetk.models.messages.RevocationReason = None)bool

Revokes the given certificate.

Parameters
  • certificate – The certificate to revoke.

  • reason – Optional reason for revocation.

Raises
Returns

True if the revocation succeeded.

async challenge_get(challenge_url: str)acme.messages.ChallengeBody

Fetches a challenge given its URL.

Parameters

challenge_url – The challenge’s URL.

Raises

aiohttp.ClientResponseError If the challenge does not exist.

Returns

The fetched challenge.

async challenge_validate(challenge_url: str)None

Initiates the given challenge’s validation.

Parameters

challenge_url – The challenge’s URL.

Raises

aiohttp.ClientResponseError If the challenge does not exist.

async challenges_cleanup(solver: acmetk.client.challenge_solver.ChallengeSolver, challenges: List[Tuple[acme.messages.Identifier, acme.messages.ChallengeBody]])

Cleans up after the challenges leveraging the given solver.

Parameters
  • solver – The challenge solver to use.

  • challenges – List of identifier, challenge tuples to clean up after.

async challenges_complete(solver: acmetk.client.challenge_solver.ChallengeSolver, challenges: List[Tuple[acme.messages.Identifier, acme.messages.ChallengeBody]])

Attempts to complete the challenges leveraging the given solver.

Parameters
  • solver – The challenge solver to use.

  • challenges – List of identifier, challenge tuples to complete.

Raises

CouldNotCompleteChallenge If completion of one of the challenges failed.

async close()

Closes the client’s session.

The client may not be used for requests anymore after it has been closed.

property eab_credentials

The client’s currently stored external account binding credentials

Getter:

Returns the client’s currently stored external account binding credentials to be used on registration.

Setter:

Sets the client’s stored external account binding credentials

param credentials

The kid and hmac_key

raises

ValueError If the tuple does not contain exactly the kid and hmac_key.

async order_create(identifiers: Union[List[dict], List[str]])acmetk.models.messages.Order

Creates a new order with the given identifiers.

Parameters

identifierslist of identifiers that the order should contain. May either be a list of fully qualified domain names or a list of dict containing the type and name (both str) of each identifier.

Raises

acme.messages.Error If the server is unwilling to create an order with the requested identifiers.

Returns

The new order.

async order_finalize(order: acmetk.models.messages.Order, csr: cryptography.x509.CertificateSigningRequest)acmetk.models.messages.Order

Finalizes the order using the given CSR.

The caller needs to ensure that this method is called with asyncio.wait_for() and a time-out value. Otherwise it may result in an infinite loop if the CA never reports the order’s status as ready.

Parameters
  • order – Order that is to be finalized.

  • csr – The CSR that is submitted to apply for certificate issuance.

Raises
Returns

The finalized order.

async order_get(order_url: str)acmetk.models.messages.Order

Fetches an order given its URL.

Parameters

order_url – The order’s URL.

Raises

aiohttp.ClientResponseError If the order does not exist.

Returns

The fetched order.

async orders_get() → List[str]

Fetches the account’s orders list.

Returns

List containing the URLs of the account’s orders.

register_challenge_solver(challenge_solver: acmetk.client.challenge_solver.ChallengeSolver)

Registers a challenge solver with the client.

The challenge solver is used to complete authorizations’ challenges whose types it supports.

Parameters

challenge_solver – The challenge solver to register.

Raises

ValueError If a challenge solver is already registered that supports any of the challenge types that challenge_solver supports.

async start()

Starts the client’s session.

This method must be called after initialization and before making requests to an ACME server, as it fetches the ACME directory and registers the private key with the server.

It is advised to register at least one ChallengeSolver using register_challenge_solver() before starting the client.

Challenge Solvers

class acmetk.client.challenge_solver.ChallengeSolver

An abstract base class for challenge solver clients.

All challenge solver implementations must implement the methods complete_challenge() and cleanup_challenge(). Implementations must also be registered with the plugin registry via register_plugin(), so that the CLI script knows which configuration option corresponds to which challenge solver class.

SUPPORTED_CHALLENGES: Iterable[acmetk.models.challenge.ChallengeType]

The types of challenges that the challenge solver implementation supports.

abstract async cleanup_challenge(key: josepy.jwk.JWK, identifier: acme.messages.Identifier, challenge: acme.messages.ChallengeBody)

Performs cleanup for the given challenge.

This method should de-provision the resource that was provisioned for the given challenge. It is called once the challenge is complete, i.e. its status has transitioned to VALID or INVALID.

This method should not assume that the challenge was successfully completed, meaning it should silently return if there is nothing to clean up.

Parameters
  • key – The client’s account key.

  • identifier – The identifier that is associated with the challenge.

  • challenge – The challenge to clean up after.

abstract async complete_challenge(key: josepy.jwk.JWK, identifier: acme.messages.Identifier, challenge: acme.messages.ChallengeBody)

Complete the given challenge.

This method should complete the given challenge and then delay returning until the server is allowed to check for completion.

Parameters
  • key – The client’s account key.

  • identifier – The identifier that is associated with the challenge.

  • challenge – The challenge to be completed.

Raises

CouldNotCompleteChallenge If the challenge completion attempt failed.

async connect()

Handles connecting the solver implementation to its remote API.

Must not be overridden if no initial connection is required.

class acmetk.client.challenge_solver.DummySolver

Dummy challenge solver that does not actually complete any challenges.

SUPPORTED_CHALLENGES: Iterable[acmetk.models.challenge.ChallengeType] = frozenset({<ChallengeType.DNS_01: 'dns-01'>, <ChallengeType.HTTP_01: 'http-01'>})

The types of challenges that the solver supports.

async cleanup_challenge(key: josepy.jwk.JWK, identifier: acme.messages.Identifier, challenge: acme.messages.ChallengeBody)

Performs cleanup for the given challenge.

Does not actually do any cleanup, instead it just logs the mock attempt and pauses execution for one second.

Parameters
  • key – The client’s account key.

  • identifier – The identifier that is associated with the challenge.

  • challenge – The challenge to clean up after.

async complete_challenge(key: josepy.jwk.JWK, identifier: acme.messages.Identifier, challenge: acme.messages.ChallengeBody)

Does not complete the given challenge.

Instead, this method only logs the mock completion attempt and pauses execution for one second.

Parameters
  • key – The client’s account key.

  • identifier – The identifier that is associated with the challenge.

  • challenge – The challenge to be completed.

async connect()

Handles connecting the solver implementation to its remote API.

Must not be overridden if no initial connection is required.

class acmetk.client.challenge_solver.InfobloxClient(*, host, username, password, dns_servers=None, views=None)

InfoBlox DNS-01 challenge solver.

This challenge solver connects to an InfoBlox API to provision DNS TXT records in order to complete the ACME DNS-01 challenge type.

DEFAULT_DNS_SERVERS = ['1.1.1.1', '8.8.8.8']

The DNS servers to use if none are specified during initialization.

DEFAULT_VIEWS = ['Extern']

The views to use if none are specified during initialization.

POLLING_DELAY = 1.0

Time in seconds between consecutive DNS requests.

POLLING_TIMEOUT = 300.0

Time in seconds after which placing the TXT record is considered a failure.

SUPPORTED_CHALLENGES: Iterable[acmetk.models.challenge.ChallengeType] = frozenset({<ChallengeType.DNS_01: 'dns-01'>})

The types of challenges that the solver supports.

async cleanup_challenge(key: josepy.jwk.JWK, identifier: acme.messages.Identifier, challenge: acme.messages.ChallengeBody)

Performs cleanup for the given challenge.

This method de-provisions the TXT record that was created to complete the given challenge.

Parameters
  • key – The client’s account key.

  • identifier – The identifier that is associated with the challenge.

  • challenge – The challenge to clean up after.

async complete_challenge(key: josepy.jwk.JWK, identifier: acme.messages.Identifier, challenge: acme.messages.ChallengeBody)

Completes the given DNS-01 challenge.

This method provisions the TXT record needed to complete the given challenge. Then it polls the DNS for up to POLLING_TIMEOUT seconds to ensure that the record is visible to the remote CA’s DNS.

Parameters
  • key – The client’s account key.

  • identifier – The identifier that is associated with the challenge.

  • challenge – The challenge to be completed.

Raises

CouldNotCompleteChallenge If the challenge completion attempt failed.

async connect()

Connects to the InfoBlox API.

This method must be called before attempting to complete challenges.

async delete_txt_record(name: str, text: str)

Deletes a DNS TXT record.

Parameters
  • name – The name of the TXT record to delete.

  • text – The text of the TXT record to delete.

async query_txt_record(resolver: dns.asyncresolver.Resolver, name: str) → Set[str]

Queries a DNS TXT record.

Parameters

name – Name of the TXT record to query.

Returns

Set of strings stored in the TXT record.

async set_txt_record(name: str, text: str, views=None, ttl: int = 60)

Sets a DNS TXT record.

Parameters
  • name – The name of the TXT record.

  • text – The text of the TXT record.

  • views – List of views to set the TXT record in. Defaults to Intern and Extern.

  • ttl – Time to live of the TXT record in seconds.

Exceptions

exception acmetk.client.exceptions.AcmeClientException

General ACME client exception.

exception acmetk.client.exceptions.CouldNotCompleteChallenge(challenge, *args)

Exception that is raised if completion of a specific challenge failed.

challenge: acme.messages.ChallengeBody

The challenge whose completion was unsuccessful.

exception acmetk.client.exceptions.PollingException(obj, *args)

Exception that is used internally to communicate polling timeouts or errors.

External Account Binding Credentials

class acmetk.client.client.ExternalAccountBindingCredentials(kid: str, hmac_key: str)

Stores external account binding credentials to later create a binding JWS using ExternalAccountBinding.

create_eab(public_key: josepy.jwk.JWK, directory: dict)dict

Creates an external account binding from the stored credentials.

Parameters
  • public_key – The account’s public key

  • directory – The ACME server’s directory

Returns

The JWS representing the external account binding

hmac_key: str

The external account binding’s symmetric encryption key

kid: str

The external account binding’s key identifier

ACME Servers

ACME Server Base

class acmetk.server.AcmeServerBase(*, rsa_min_keysize=2048, ec_min_keysize=256, tos_url=None, mail_suffixes=None, subnets=None, use_forwarded_header=False, require_eab=False, allow_wildcard=False, **kwargs)

Base class for an ACME compliant server.

Implementations must also be registered with the plugin registry via register_plugin(), so that the CLI script knows which configuration option corresponds to which server class.

ORDERS_LIST_CHUNK_LEN = 10

Number of order links to include per request.

SUPPORTED_ACCOUNT_KEYS = (<class 'cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey'>, <class 'cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey'>)

The types of public keys that the server supports when creating ACME accounts.

SUPPORTED_CSR_KEYS = (<class 'cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey'>, <class 'cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey'>)

The types of public keys that the server supports in a certificate signing request.

SUPPORTED_EAB_JWS_ALGORITHMS = (HS256, HS384, HS512)

The symmetric JWS signing algorithms that the server supports for external account bindings.

SUPPORTED_JWS_ALGORITHMS = (RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512)

The JWS signing algorithms that the server supports.

VALID_DOMAIN_RE = re.compile('^(((?!-))(xn--|_{1,1})?[a-z0-9-]{0,61}[a-z0-9]{1,1}\\.)*(xn--)?([a-z0-9][a-z0-9\\-]{0,60}|[a-z0-9-]{1,30}\\.[a-z]{2,})$')

using from https://stackoverflow.com/questions/ 10306690/what-is-a-regular-expression-which-will-match-a-valid-domain-name-without-a-subd

better than nothing, but accepts names ending with -

_verify_order(obj: acme.messages.NewOrder, wildcardonly=False)

Verify the identifiers in an Order

Remove wildcards and validate with regex

Raises
async _verify_request(request, session, key_auth: bool = False, post_as_get: bool = False, expunge_account: bool = True)

Verifies an ACME request whose payload is encapsulated in a JWS.

6.2. Request Authentication

All requests to handlers apart from new_nonce() and directory() are authenticated.

Parameters
  • key_authTrue if the JWK inside the JWS should be used to verify its signature. False otherwise

  • post_as_getTrue if a POST-as-GET request is expected. False otherwise

  • expunge_accountTrue if the account object should be expunged from the session. Needs to be False if the account object is to be updated in the database later.

Raises
  • aiohttp.web.HTTPNotFound if the JWS contains a kid, but the corresponding account does not exist.

  • acme.messages.Error if any of the following are true:

    • The request does not contain a valid JWS

    • The handler expects a POST-as-GET request, but got a non-empty payload

    • The URL inside the JWS’ signature is not equal to the actual request URL

    • The signature was created using an algorithm that the server does not support, see SUPPORTED_JWS_ALGORITHMS

    • The client supplied a bad nonce in the JWS’ protected header

    • The JWS does not have either a JWK or a kid

    • The JWS’ signature is invalid

    • There is a mismatch between the URL’s kid and the JWS’ kid

    • The account corresponding to the kid does not have status acmetk.models.AccountStatus.VALID

async accounts(request)

Handler that updates or queries the given account.

7.3.2. Account Update

Only updates to the account’s status and contact fields are allowed. Returns the current account object if no updates were specified.

Raises
Returns

The account object.

async authz(request)

Handler that updates or queries the given authorization.

7.5. Identifier Authorization

Only updates to the authorization’s status field are allowed.

7.5.2. Deactivating an Authorization

Raises
Returns

The authorization object.

abstract async certificate(request)

Handler that queries the given certificate.

7.4.2. Downloading the Certificate

Raises

aiohttp.web.HTTPNotFound If the certificate does not exist.

Returns

The certificate’s full chain in PEM format.

async challenge(request)

Handler that queries the given challenge and initiates its validation.

7.5.1. Responding to Challenges

Raises

aiohttp.web.HTTPNotFound If the challenge does not exist.

Returns

The challenge object.

async classmethod create_app(config: Dict[str, Any], **kwargs) → acmetk.server.server.AcmeServerBase

A factory that also creates and initializes the database and session objects, reading the necessary arguments from the passed config dict.

Parameters

config – A dictionary holding the configuration. See Configuration for supported options.

Returns

The server instance

async directory(request)

Handler that returns the server’s directory.

7.1.1. Directory

Only adds the URL to the ToS if tos_url was set during construction.

Returns

The directory object.

async eab(request)

Handler that displays the user’s external account binding credentials, i.e. their kid and hmac_key after their client certificate has been verified and forwarded by the reverse proxy.

async error_middleware(request, handler)

Middleware that converts errors thrown in handlers to ACME compliant JSON and attaches the specified status code to the response.

Returns

The ACME error converted to JSON.

async finalize_order(request)

Handler that initiates finalization of the given order.

7.4. Applying for Certificate Issuance

Specifically: https://tools.ietf.org/html/rfc8555#page-47

Raises
  • aiohttp.web.HTTPNotFound If the order does not exist.

  • acme.messages.Error if any of the following are true:

    • The order is not in state acmetk.models.OrderStatus.READY

    • The CSR’s public key size is insufficient

    • The CSR’s signature is invalid

    • The identifiers that the CSR requests differ from those that the order has authorizations for

Returns

The updated order object.

abstract async handle_order_finalize(request, account_id: str, order_id: str)

Method that handles the actual finalization of an order.

This method should be called after the order’s status has been set to acmetk.models.OrderStatus.PROCESSING in finalize_order().

It should retrieve the order from the database and either generate the certificate from the stored CSR itself or submit it to another CA.

Afterwards the certificate should be stored alongside the order. The full_chain attribute needs to be populated and returned to the client in certificate() if the certificate was generated by another CA.

Parameters
  • account_id – The account’s id

  • order_id – The order’s id

async host_ip_middleware(request, handler)

Middleware that checks whether the requesting host’s IP is part of any of the subnets that are whitelisted.

Returns

  • HTTP status code 403 if the host’s IP is not part of any of the whitelisted subnets.

  • HTTP status code 400 if there is a X-Forwarded-For header spoofing attack going on.

async key_change(request)

7.3.5. Account Key Rollover

async new_account(request)

Handler that registers a new account.

7.3. Account Management

May also be used to find an existing account given a key.

7.3.1. Finding an Account URL Given a Key

Raises

acme.messages.Error if any of the following are true:

  • The public key’s key size is insufficient

  • The account exists but its status is not acmetk.models.AccountStatus.VALID

  • The client specified only_return_existing but no account with that public key exists

  • The client wants to create a new account but did not agree to the terms of service

Returns

The account object.

async new_nonce(request)

Handler that returns a new nonce.

7.2. Getting a Nonce

Returns

The nonce inside the Replay-Nonce header.

async new_order(request)

Handler that creates a new order.

7.4. Applying for Certificate Issuance

Returns

The order object.

async order(request)

Handler that queries the given order.

7.1.3. Order Objects

Raises

aiohttp.web.HTTPNotFound If the order does not exist.

Returns

The order object.

async orders(request)

Handler that retrieves the account’s chunked orders list.

7.1.2.1. Orders List

Returns

An object with key orders that holds a chunk of the account’s orders list.

register_challenge_validator(validator: acmetk.server.challenge_validator.ChallengeValidator)

Registers a ChallengeValidator with the server.

The validator is subsequently used to validate challenges of all types that it supports.

Parameters

validator – The challenge validator to be registered.

Raises

ValueError If a challenge validator is already registered that supports any of the challenge types that validator supports.

async revoke_cert(request)

Handler that initiates revocation of the given certificate.

7.6. Certificate Revocation

Raises
  • aiohttp.web.HTTPNotFound If the certificate does not exist.

  • acme.messages.Error if any of the following are true:

    • The client specified an unsupported revocation reason

    • The client’s account does not hold authorizations for all identifiers in the certificate

    • If the message was signed using the certificate’s private key

      • The public key of the certificate and the JWK differ

      • The JWS’ signature is invalid

Returns

HTTP status code 200 if the revocation succeeded.

async classmethod runner(config: Dict[str, Any], **kwargs) → Tuple[aiohttp.web.AppRunner, AcmeServerBase]

A factory that starts the server on the given hostname and port using an AppRunner after constructing a server instance using create_app().

Parameters
  • config – A dictionary holding the configuration. See Configuration for supported options.

  • kwargs – Additional kwargs are passed to the create_app() call.

Returns

A tuple containing the app runner as well as the server instance.

async classmethod unix_socket(config: Dict[str, Any], path: str, **kwargs) → Tuple[aiohttp.web.AppRunner, AcmeServerBase]

A factory that starts the server on a Unix socket bound to the given path using an AppRunner after constructing a server instance using create_app().

Parameters
  • config – A dictionary holding the configuration. See Configuration for supported options.

  • path – Path of the unix socket.

  • kwargs – Additional kwargs are passed to the create_app() call.

Returns

A tuple containing the app runner as well as the server instance.

verify_eab(request, pub_key: cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey, reg: acme.messages.Registration)

Verifies an ACME Registration request whose payload contains an external account binding JWS.

Parameters
  • pub_key – The public key that is contained in the outer JWS, i.e. the ACME account key.

  • reg – The registration message.

Raises
  • acme.messages.Error if any of the following are true:

    • The request does not contain a valid JWS

    • The request JWS does not contain an externalAccountBinding field

    • The EAB JWS was signed with an unsupported algorithm (SUPPORTED_EAB_JWS_ALGORITHMS)

    • The EAB JWS’ payload does not contain the same public key as the encapsulating JWS

    • The EAB JWS’ signature is invalid

ACME Relay Base

class acmetk.server.AcmeRelayBase(*, client, **kwargs)

Bases: acmetk.server.server.AcmeServerBase

Base for an ACME server that relays requests to a remote CA using an internal ACME client.

The account that is used to sign requests to the remote CA is shared between all users of the relay server.

At this time, challenges and authorizations are not shared between the relay server and the remote CA. Instead, the relay has to make sure that all authorizations for a given order are valid before applying for certificate issuance.

async certificate(request)

Handler that queries the given certificate.

7.4.2. Downloading the Certificate

Returns the full chain as retrieved from the CA by the internal client.

Raises

aiohttp.web.HTTPNotFound If the certificate does not exist.

Returns

The certificate’s full chain in PEM format.

async classmethod create_app(config: Dict[str, Any], *, client: acmetk.client.client.AcmeClient, **kwargs) → acmetk.server.server.AcmeRelayBase

A factory that also creates and initializes the database and session objects, reading the necessary arguments from the passed config dict.

Parameters
  • config – A dictionary holding the configuration. See Configuration for supported options.

  • client – The internal started AcmeClient instance

Returns

The server instance

async obtain_and_store_cert(order: acmetk.models.order.Order, order_ca: acme.messages.Order)

Method that obtains the certificate for the given order from the remote CA and stores it.

This method should be called after the finalization of the order has been completed in handle_order_finalize().

Parameters
  • order – The relay’s order

  • order_ca – The remote CA’s order object

async revoke_cert(request)

Handler that initiates revocation of the given certificate.

7.6. Certificate Revocation

The revocation is first relayed to the remote CA using the internal client before being processed internally.

Raises
  • aiohttp.web.HTTPNotFound If the certificate does not exist.

  • acme.messages.Error if any of the following are true:

    • The client specified an unsupported revocation reason

    • The client’s account does not hold authorizations for all identifiers in the certificate

    • If the message was signed using the certificate’s private key

      • The public key of the certificate and the JWK differ

      • The JWS’ signature is invalid

Returns

HTTP status code 200 if the revocation succeeded.

ACME Certificate Authority

class acmetk.server.AcmeCA(*, cert, private_key, **kwargs)

Bases: acmetk.server.server.AcmeServerBase

ACME compliant Certificate Authority.

async certificate(request)

Handler that queries the given certificate.

7.4.2. Downloading the Certificate

Raises

aiohttp.web.HTTPNotFound If the certificate does not exist.

Returns

The certificate’s full chain in PEM format.

async classmethod create_app(config, **kwargs)

A factory that also creates and initializes the database and session objects, reading the necessary arguments from the passed config dict.

Parameters

config – A dictionary holding the configuration. See Configuration for supported options.

Returns

The server instance

async handle_order_finalize(request, account_id: str, order_id: str)

Method that handles the actual finalization of an order.

This method is called after the order’s status has been set to acmetk.models.OrderStatus.PROCESSING in finalize_order().

It retrieves the order from the database and generates the certificate from the stored CSR, signing it using the CA’s private key.

Afterwards the certificate is stored alongside the order.

Parameters
  • account_id – The account’s id

  • order_id – The order’s id

ACME Broker

class acmetk.server.AcmeBroker(*, client, **kwargs)

Bases: acmetk.server.server.AcmeRelayBase

Server that relays requests to a remote CA employing a “broker” model.

Orders are only relayed to the remote CA when the finalization is already processing. This means that errors that may occur at the remote CA during order creation or finalization cannot be shown to the end user transparently. If that is a concern, then the AcmeProxy class should be used instead.

async handle_order_finalize(request, account_id: str, order_id: str)

Method that handles the actual finalization of an order.

This method is called after the order’s status has been set to acmetk.models.OrderStatus.PROCESSING in finalize_order().

The order is relayed to the remote CA here and the entire certificate acquisition process is handled by the internal client. The obtained certificate’s full chain is then stored in the database.

If the certificate acquisition fails, then the order’s status is set to acmetk.models.OrderStatus.INVALID.

Parameters
  • account_id – The account’s id

  • order_id – The order’s id

ACME Proxy

class acmetk.server.AcmeProxy(*, client, **kwargs)

Bases: acmetk.server.server.AcmeRelayBase

Server that relays requests to a remote CA employing a “proxy” model.

Orders are relayed to the remote CA transparently, which allows for the possibility to show errors to the end user as they occur at the remote CA.

async finalize_order(request)

Handler that initiates finalization of the given order.

7.4. Applying for Certificate Issuance

Specifically: https://tools.ietf.org/html/rfc8555#page-47

The order is refetched via the client using the stored proxied_url. The client then attempts to finalize the order at the remote CA. If an error is raised here, then it is transparently shown to the end user.

Raises
  • aiohttp.web.HTTPNotFound If the order does not exist.

  • acme.messages.Error if any of the following are true:

    • The order is not in state acmetk.models.OrderStatus.READY

    • The CSR’s public key size is insufficient

    • The CSR’s signature is invalid

    • The identifiers that the CSR requests differ from those that the order has authorizations for

Returns

The updated order object.

async handle_order_finalize(request, account_id: str, order_id: str)

Method that handles the actual finalization of an order.

This method is called after the order’s status has been set to acmetk.models.OrderStatus.PROCESSING in finalize_order().

The order is refetched from the remote CA here after which the internal client downloads the certificate and stores its full chain in the database.

Parameters
  • account_id – The account’s id

  • order_id – The order’s id

async new_order(request)

Handler that creates a new order.

7.4. Applying for Certificate Issuance

The order is also relayed to the remote CA by the internal client. This means that errors that might occur during the creation process are transparently shown to the end user.

Returns

The order object.

Challenge Validators

class acmetk.server.challenge_validator.ChallengeValidator

An abstract base class for challenge validator clients.

All challenge validator implementations must implement the method validate_challenge() that validates the given challenge. Implementations must also be registered with the plugin registry via register_plugin(), so that the CLI script knows which configuration option corresponds to which challenge validator class.

SUPPORTED_CHALLENGES: Iterable[acmetk.models.challenge.ChallengeType]

The types of challenges that the challenge validator implementation supports.

abstract async validate_challenge(challenge: acmetk.models.challenge.Challenge, **kwargs)

Validates the given challenge.

This method should attempt to validate the given challenge and raise a CouldNotValidateChallenge exception if the validation failed.

Parameters

challenge – The challenge to be validated

Raises

CouldNotValidateChallenge If the validation failed

exception acmetk.server.challenge_validator.CouldNotValidateChallenge(*args, detail=None)

Exception that is raised when any given challenge could not be validated.

with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

class acmetk.server.challenge_validator.DummyValidator

Does not do any validation and reports every challenge as valid.

SUPPORTED_CHALLENGES: Iterable[acmetk.models.challenge.ChallengeType] = frozenset({<ChallengeType.DNS_01: 'dns-01'>, <ChallengeType.HTTP_01: 'http-01'>})

The types of challenges that the validator supports.

async validate_challenge(challenge: acmetk.models.challenge.Challenge, **kwargs)

Does not validate the given challenge.

Instead, this method only logs the mock validation attempt and pauses execution for one second.

Parameters

challenge – The challenge to be validated

class acmetk.server.challenge_validator.RequestIPDNSChallengeValidator

Validator for the Request IP DNS challenge.

This validator does not actually validate a challenge defined by the ACME protocol. Instead, it checks whether the corresponding authorization’s identifier resolves to the IP that the validation request is being made from by checking for a A/AAAA record.

SUPPORTED_CHALLENGES: Iterable[acmetk.models.challenge.ChallengeType] = frozenset({<ChallengeType.DNS_01: 'dns-01'>, <ChallengeType.HTTP_01: 'http-01'>})

The types of challenges that the validator supports.

async query_records(name: str) → Set[str]

Queries DNS A and AAAA records.

Parameters

name – Name of the A/AAAA record to query.

Returns

Set of IPs that the A/AAAA records resolve to.

async validate_challenge(challenge: acmetk.models.challenge.Challenge, request=None)

Validates the given challenge.

This method takes a challenge of ChallengeType DNS_01 or HTTP_01 and does not actually validate that challenge, but instead checks whether the corresponding authorization’s identifier resolves to the IP address that the validation request is being made from.

Parameters

challenge – The challenge to be validated

Raises

CouldNotValidateChallenge If the validation failed

External Account Binding

class acmetk.server.external_account_binding.ExternalAccountBinding(email: str, url: str)

Represents an external account binding.

7.3.4. External Account Binding

EXPIRES_AFTER = datetime.timedelta(seconds=10800)

Timedelta after which an external account binding request is considered expired.

expired()bool

Returns whether the EAB has expired.

Returns

True iff the EAB has expired.

hmac_key: str

The key that is used to symmetrically sign the JWS.

kid: str

The key identifier provided by the external binding mechanism.

signature(key_json: str)str

Returns the EAB’s signature.

Parameters

key_json – The ACME account key that the external account is to be bound to.

url: str

The newAccount URL which is the same as in the encapsulating JWS.

verify(jws: acme.jws.JWS)bool

Checks the given signature against the EAB’s.

Parameters

jws – The EAB request JWS to be verified.

Returns

True iff the given signature and the EAB’s are equal.

when: datetime.datetime

The time when the EAB request was created.

class acmetk.server.external_account_binding.ExternalAccountBindingStore

Stores pending ExternalAccountBinding requests and offers methods for creation and verification.

create(request) → Tuple[str, str]

Creates an ExternalAccountBinding request and stores it internally for verification at a later point in time.

Parameters

request – The request that contains the PEM-encoded x509 client certificate in the X-SSL-CERT header.

Returns

The resulting pending EAB’s kid and hmac_key.

verify(kid: str, jws: acme.jws.JWS)bool

Verifies an external account binding given its ACME account key, kid and signature.

Parameters
  • kid – The EAB’s kid.

  • jws – The EAB request JWS.

Returns

True iff verification was successful.

class acmetk.server.external_account_binding.AcmeEABMixin(**kwargs)

Mixin for an AcmeServerBase implementation that provides external account binding creation and verification.

7.3.4. External Account Binding

An external account binding request is created when the user visits the /eab route. The EAB mechanism used here is email verification using an SSL client certificate. A reverse proxy should be configured to include a set of root certificates that the user’s browser can establish a chain of trust to. The reverse proxy then forwards the PEM and URL-encoded client certificate in the X-SSL-CERT header after verifying it.

async eab(request)

Handler that displays the user’s external account binding credentials, i.e. their kid and hmac_key after their client certificate has been verified and forwarded by the reverse proxy.

verify_eab(request, pub_key: cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey, reg: acme.messages.Registration)

Verifies an ACME Registration request whose payload contains an external account binding JWS.

Parameters
  • pub_key – The public key that is contained in the outer JWS, i.e. the ACME account key.

  • reg – The registration message.

Raises
  • acme.messages.Error if any of the following are true:

    • The request does not contain a valid JWS

    • The request JWS does not contain an externalAccountBinding field

    • The EAB JWS was signed with an unsupported algorithm (SUPPORTED_EAB_JWS_ALGORITHMS)

    • The EAB JWS’ payload does not contain the same public key as the encapsulating JWS

    • The EAB JWS’ signature is invalid

Plugin Registry

class acmetk.plugin_base.PluginRegistry

A class that serves as a central place to register and load plugins.

Plugins that are derived from a base class are stored in that base class’s registry.

config_mapping() → Dict[str, type]

Method that maps plugin config names to the actual class object.

Returns

Mapping from config names to the actual class objects.

get_plugin(config_name)type

Queries the registry for a plugin by config name.

Parameters

config_name – The plugin’s config name

Raises

ValueError If no plugin is registered by the given name

Returns

The found plugin class

classmethod get_registry(plugin_parent_cls: type)acmetk.plugin_base.PluginRegistry

Gets the plugin registry for the given parent class.

Parameters

plugin_parent_cls – The parent class.

Returns

The plugin registry for the given parent class.

classmethod load_plugins(path: str)None

Loads plugins from all modules under the given path.

Parameters

path – The path to load plugins from.

classmethod register_plugin(config_name)

Decorator that registers a class as a plugin under the given name. The name is used to refer to the class in config files.

Parameters

config_name – The plugin’s name in config files

Returns

The registered plugin class.

Models

Message types

class acmetk.models.messages.Account(**kwargs)

Bases: josepy.json_util.JSONObjectWithFields

Patched acme.messages.Registration message type that adds a kid field.

This is the representation of a user account that the AcmeClient uses internally. The kid field is sent to the remote server with every request and used for request verification. Fields that see no use inside the client have been removed.

contact: Tuple[str]

The account’s contact info.

kid: str

The account’s key ID.

orders: str

URL of the account’s orders list.

status: acmetk.models.account.AccountStatus

The account’s status.

class acmetk.models.messages.AccountUpdate(**kwargs)

Bases: acmetk.models.messages.JSONDeSerializableAllowEmpty, acme.messages.Registration

Patched acme.messages.Registration message type that adds a status field for status update requests.

Inherits from JSONDeSerializableAllowEmpty so that POST-as-GET requests don’t result in a parsing error.

status: acmetk.models.account.AccountStatus

The account’s new status.

class acmetk.models.messages.AuthorizationUpdate(**kwargs)

Bases: acmetk.models.messages.JSONDeSerializableAllowEmpty, josepy.json_util.JSONObjectWithFields

Message type that allows (de-)serialization of authorization update request payloads.

Inherits from JSONDeSerializableAllowEmpty so that POST-as-GET requests don’t result in a parsing error.

status: acmetk.models.authorization.AuthorizationStatus

The authorization’s new status.

class acmetk.models.messages.CertificateRequest(**kwargs)

Bases: josepy.json_util.JSONObjectWithFields

Message type for certificate requests.

Received by an AcmeServerBase instance at the order finalization step finalize_order().

csr: cryptography.x509.CertificateSigningRequest

The certificate signing request.

acmetk.models.messages.ERROR_CODE_STATUS = {'accountDoesNotExist': 404, 'orderNotReady': 403, 'unauthorized': 401}

ACME error types mapped to HTTP status codes.

6.7. Errors

class acmetk.models.messages.JSONDeSerializableAllowEmpty

Bases: josepy.interfaces.JSONDeSerializable

JSONDeSerializable that allows an empty string as the input for json_loads().

This subclass (sub-interface) is needed for AuthorizationUpdate as well as AccountUpdate, so the request payload can still be parsed into a valid (empty) update object although a POST-as-GET with an empty payload (b"") was performed.

classmethod json_loads(json_string: str) → josepy.interfaces.JSONDeSerializable

Deserialize from JSON document string.

Parameters

json_string – The json string to be deserialized.

Returns

The deserialized object whose type is a subclass of josepy.JSONDeSerializable.

class acmetk.models.messages.KeyChange(**kwargs)

Bases: josepy.json_util.JSONObjectWithFields

class acmetk.models.messages.NewOrder(**kwargs)

Bases: josepy.json_util.JSONObjectWithFields

Message type for new order requests.

classmethod from_data(identifiers: Union[List[Dict[str, str]], List[str]] = None, not_before: datetime.datetime = None, not_after: datetime.datetime = None)NewOrder

Class factory that takes care of parsing the list of identifiers.

Parameters
  • identifiers – Either a list of dict where each dict consists of the keys type and value, or a list of str that represent the DNS names.

  • not_before – The requested notBefore field in the certificate.

  • not_after – The requested notAfter field in the certificate.

Returns

The new order object.

identifiers: List[Dict[str, str]]

The requested identifiers.

not_after: datetime.datetime

The requested notAfter field in the certificate.

not_before: datetime.datetime

The requested notBefore field in the certificate.

class acmetk.models.messages.Order(**kwargs)

Bases: acme.messages.Order

Patched acme.messages.Order message type that adds a URL field.

The URL field is populated by copying the Location header from responses in the AcmeClient. This field is used by the AcmeProxy to store the proxied URL and to be able to map an internal order to that of the remote CA.

url: str

The order’s URL at the remote CA.

class acmetk.models.messages.Revocation(**kwargs)

Bases: josepy.json_util.JSONObjectWithFields

Message type for certificate revocation requests.

certificate: cryptography.x509.Certificate

The certificate to be revoked.

reason: acmetk.models.messages.RevocationReason

The reason for the revocation.

class acmetk.models.messages.RevocationReason(value)

Bases: enum.Enum

Certificate revocation reasons.

Defined in 5.3.1. Reason Code of RFC 5280.

class acmetk.models.messages.SignedKeyChange(**kwargs)

Bases: josepy.json_util.JSONObjectWithFields

acmetk.models.messages.get_status(error_type: str)int

Gets the HTTP status code that corresponds to the given ACME error type.

Defaults to status code 400 for a generic user error if no mapping was defined by RFC 8555.

Parameters

error_type – The ACME error type.

Returns

The corresponding HTTP status code.

Database models

Account

class acmetk.models.account.Account(**kwargs)

Database model for ACME account objects.

7.1.2. Account Objects

account_id

The account’s permanent identifier

authorized_identifiers(lower: bool = False) → Set[str]

Returns the identifiers that the account holds valid authorizations for.

Parameters

lower – True if the list of authorized identifiers should be lowercased.

Returns

The set of identifiers that the account holds authorizations for.

contact

The account’s contact info.

classmethod from_obj(jwk: josepy.jwk.JWK, obj: acme.messages.Registration)acmetk.models.account.Account

A factory that constructs a new Account from a message object.

The kid is set to the passed JWK’s SHA-256 hex digest and the status is set to valid.

Parameters
  • jwk – The account’s key.

  • obj – The registration message object.

Returns

The constructed account.

key

The account’s public key.

kid

The account key’s ID.

orders

List of orders (Order) associated with the account.

orders_list(request) → List[str]

Returns the account’s orders list.

Parameters

request – The client request needed to build the list of URLs.

Returns

A list of URLs of the account’s orders.

orders_url(request)str

Returns the URL of account’s orders list.

Parameters

request – The client request needed to build the URL.

Returns

The URL at which the account’s orders list may be requested.

status

The account’s status.

update(upd: acmetk.models.messages.AccountUpdate)

Updates the account with new information.

Possible updates are currently to the contact field and to the status field.

Parameters

upd – The requested updates.

validate_cert(cert: cryptography.x509.Certificate)bool

Validates whether the account holds authorizations for all names present in the certificate.

Parameters

cert – The certificate to validate.

Returns

True iff the account holds authorizations for all names present in the certificate.

Authorization

class acmetk.models.authorization.Authorization(**kwargs)

Database model for ACME authorization objects.

7.5. Identifier Authorization

authorization_id

The authorization’s ID.

challenges

List of challenges (Challenge) associated with the authorization.

expires

The datetime.datetime from which the authorization is considered expired.

classmethod for_identifier(identifier: acmetk.models.identifier.Identifier)Authorization

A factory that constructs a new authorization given an Identifier.

The field expires is set to 7 days in the future from the time this method is called and the status is initially set to pending.

The resulting authorization is not automatically associated with the given identifier.

Parameters

identifier – The identifier that the authorization will be associated with.

Returns

The constructed authorization.

identifier

The Identifier associated with the authorization.

is_expired()bool

Returns whether the authorization has expired.

Returns

True iff the authorization has expired.

is_valid(expired=False)bool

Returns whether the authorization is currently valid.

Takes into account not only the current status, but also whether the authorization has expired.

Parameters

expired – Reports an otherwise valid but expired authorization as valid if set to True.

Returns

True iff the authorization is valid.

status

The authorization’s status.

update(upd: acmetk.models.messages.AuthorizationUpdate)

Updates the authoziation’s status.

Parameters

upd – The requested status update.

url(request)str

Returns the authorization’s URL.

Parameters

request – The client request needed to build the URL.

Returns

The authorization’s URL.

async validate(session) → acmetk.models.authorization.AuthorizationStatus

Validates the authorization.

This method is usually not called directly. Rather, acmetk.models.challenge.Challenge.validate() calls it as a challenge that corresponds to the authorization is being validated.

Parameters

session – The open database session.

Returns

The authorization’s status after validation.

wildcard

Whether the authorization contains a wildcard.

Certificate

class acmetk.models.certificate.Certificate(**kwargs)

Database model for certificate objects.

The ACME RFC does not specify how certificate objects should be structured. It merely requires that the resulting certificate chain that the client downloads be encoded with the PEM encoding: 9.1. Media Type: application/pem-certificate-chain

There exists a check constraint on the resulting table to ensure that either the attribute cert or the attribute full_chain is set. cert is used by the AcmeCA as it appends its root certificate on certificate download. full_chain is used by all subclasses of AcmeRelayBase to easily store the full certificate chain that is downloaded from the remote CA.

cert

The actual client certificate (cryptography.x509.Certificate).

certificate_id

The certificate’s ID.

full_chain

The full chain of the certificate (str).

order

The acmetk.models.order.Order associated with the certificate.

reason

The revocation reason (RevocationReason).

revoke(reason: acmetk.models.messages.RevocationReason)

Sets the certificate’s status to revoked and copies the given reason.

Parameters

reason – The reason for revocation.

status

The certificate’s status.

Challenge

class acmetk.models.challenge.Challenge(**kwargs)

Database model for ACME challenge objects.

8. Identifier Validation Challenges

authorization

The Authorization associated with the challenge.

challenge_id

The challenge’s ID.

classmethod create_types(types: Iterable[acmetk.models.challenge.ChallengeType]) → List[acmetk.models.challenge.Challenge]

Returns new pending challenges of the given types.

Parameters

types – The types of challenges to be created.

Returns

The created challenges.

error

The error that occurred while validating the challenge.

status

The challenge’s status.

token

The token that is used during the challenge validation process. See 8.1. Key Authorizations

type

The challenge’s type (ChallengeType).

url(request)str

Returns the challenge’s URL.

Parameters

request – The client request needed to build the URL.

Returns

The challenge’s URL.

async validate(session, request, validator: acmetk.server.challenge_validator.ChallengeValidator) → acmetk.models.challenge.ChallengeStatus

Validates the challenge with the given validator.

Also, it calls its parent authorization’s validate() method and finally returns the new status after validation.

Parameters
  • session – The open database session.

  • validator – The challenge validator to perform the validation with.

Returns

The challenge’s status after validation.

validated

The datetime.datetime when the challenge was validated.

class acmetk.models.challenge.ChallengeType(value)

The types that a Challenge can have.

Subclassing str simplifies json serialization using json.dumps().

DNS_01 = 'dns-01'

The ACME dns-01 challenge type. See 8.4. DNS Challenge

HTTP_01 = 'http-01'

The ACME http-01 challenge type. See 8.3. HTTP Challenge

TLS_ALPN_01 = 'tls-alpn-01'

The ACME tls-alpn-01 challenge type. See RFC 8737

_member_type_

alias of builtins.str

Identifier

class acmetk.models.identifier.Identifier(**kwargs)

Database model for ACME identifier objects.

8. Identifier Validation Challenges

authorization

The Authorization associated with the identifier.

classmethod from_obj(obj: acme.messages.Identifier)acmetk.models.identifier.Identifier

A factory that constructs a new Identifier from a message object.

Parameters

obj – The identifier message object.

Returns

The constructed identifier.

identifier_id

The identifier’s ID.

order

The Order associated with the identifier.

type

The identifier’s type (IdentifierType).

value

The identifier’s value. In the case of a dns type identifier: the FQDN.

class acmetk.models.identifier.IdentifierType(value)

The types that a Identifier can have.

9.7.7. Identifier Types

Subclassing str simplifies json serialization using json.dumps().

DNS = 'dns'

The ACME DNS identifier type.

_member_type_

alias of builtins.str

Order

class acmetk.models.order.Order(**kwargs)

Database model for ACME order objects.

7.1.3. Order Objects

account

The Account that created the order.

certificate

The Certificate that was generated as a result of the order.

certificate_url(request)

Returns the order’s certificate URL.

Parameters

request – The client request needed to build the URL.

Returns

The URL at which the client may download the certificate that was generated as a result of the order.

csr

The cryptography.x509.CertificateSigningRequest that was submitted by the client.

expires

The datetime.datetime from which the order is considered expired.

finalize_url(request)str

Returns the order’s finalize URL.

Parameters

request – The client request needed to build the URL.

Returns

The URL at which the client may request the order to be finalized.

classmethod from_obj(account: acmetk.models.account.Account, obj: acme.messages.NewOrder, challenge_types: Iterable[acmetk.models.challenge.ChallengeType])Order

A factory that constructs a new Order from a message object.

The field expires is set to 7 days in the future from the time this method is called and the status is initially set to pending.

Furthermore, the order object is automatically associated with the given account and all Identifier, Authorization, and Challenge objects are created as well as associated with the order.

Parameters
  • account – The account’s key.

  • obj – The registration message object.

  • challenge_types – The types of challenges to create.

Returns

The constructed order.

identifiers

List of identifiers (Identifier) associated with the order.

notAfter

The requested notAfter field in the certificate.

notBefore

The requested notBefore field in the certificate.

order_id

The order’s ID.

proxied_error

The error that occured at the remote CA while processing the order.

proxied_url

The order’s URL at the remote CA.

status

The order’s status.

url(request)str

Returns the order’s URL.

Parameters

request – The client request needed to build the URL.

Returns

The order’s URL.

async validate() → acmetk.models.order.OrderStatus

Validates the order.

This method is usually not called directly. Rather, acmetk.models.authorization.Authorization.validate() calls it as a authorization that corresponds to the order is being validated.

Parameters

session – The open database session.

Returns

The order’s status after validation.

validate_csr(csr: cryptography.x509.CertificateSigningRequest)bool

Validates whether the given CSR’s names equal the order’s identifiers.

Accounts for different capitalizations.

Parameters

cert – The CSR to validate.

Returns

True iff the set of names in the CSR equals the order’s set of identifiers.

Utils

acmetk.util.forwarded_url(request) → yarl.URL

Returns the URL with the correct protocol scheme.

Looks for the X-Forwarded-Proto header and replaces the request URL’s protocol scheme if applicable.

Parameters

request – The request needed to build the URL.

Returns

The corrected URL.

acmetk.util.generate_cert_from_csr(csr: cryptography.x509.CertificateSigningRequest, root_cert: cryptography.x509.Certificate, root_key: cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey)cryptography.x509.Certificate

Generates a signed certificate from a certificate signing request given the certificate authority’s certificate and private key.

Parameters
  • csr – The certificate signing request to generate a certificate from.

  • root_cert – The signing CA’s root certificate.

  • root_key – The signing CA’s root key.

Returns

The generated certificate.

acmetk.util.generate_csr(CN: str, private_key: cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey, path: pathlib.Path, names: List[str])

Generates a certificate signing request.

Parameters
  • CN – The requested common name.

  • private_key – The private key to sign the CSR with.

  • path – The path to write the PEM-serialized CSR to.

  • names – The requested names in the CSR.

Returns

The generated CSR.

acmetk.util.generate_ec_key(path: pathlib.Path, key_size=256)cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey

Generates an EC private key and saves it to the given path as PEM.

Parameters
  • path – The path to write the PEM-serialized key to.

  • key_size – The EC key size.

Returns

The generated private key.

acmetk.util.generate_root_cert(path: pathlib.Path, country: str, state: str, locality: str, org_name: str, common_name: str) → Tuple[cryptography.x509.Certificate, cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey]

Generates a self-signed CA root certificate (RSA).

Parameters
  • path – The path of the generated private key. The resulting certificate will be saved to the same directory as root.crt.

  • country – The requested country name in the certificate.

  • state – The requested state or province name in the certificate.

  • locality – The requested locality name in the certificate.

  • org_name – The requested organization name in the certificate.

  • common_name – The requested common name in the certificate.

Returns

The resulting root certificate and corresponding private key.

acmetk.util.generate_rsa_key(path: pathlib.Path, key_size=2048)cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey

Generates an RSA private key and saves it to the given path as PEM.

Parameters
  • path – The path to write the PEM-serialized key to.

  • key_size – The RSA key size.

Returns

The generated private key.

acmetk.util.names_of(csr: cryptography.x509.CertificateSigningRequest, lower: bool = False) → Set[str]

Returns all names contained in the given CSR.

Parameters
  • csr – The CRS whose names to extract.

  • lower – True if the names should be returned in lowercase.

Returns

Set of the contained identifier strings.

acmetk.util.next_url(url: str, current_cursor: int)str

Returns the URL’s cursor query given its current value

Parameters

url – The URL whose cursor is to be incremented.

Returns

The URL with its cursor query value incremented.

acmetk.util.pem_split(pem: str) → List[Union[cryptography.x509.CertificateSigningRequest, cryptography.x509.Certificate]]

Parses a PEM encoded string and returns all contained CSRs and certificates.

Parameters

pem – The concatenated PEM encoded CSRs and certificates.

Returns

List of all certificate signing requests and certificates found in the PEM string.

acmetk.util.url_for(request, path: str, **kwargs)str

Builds a URL for a given path and optional parameters.

Parameters
  • request – The request needed to build the URL.

  • path – The path for which to build a URL.

  • kwargs – Optional parameters for URL construction, such as an account ID.

Returns

The constructed URL.