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
AcmeClientinstance.- 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.
contact –
dictcontaining 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.ErrorIf 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.ErrorIf 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 adictcontact containing new contact information or status set toacme.messages.STATUS_DEACTIVATEDto deactivate the account.- Raises
acme.messages.ErrorIf the server rejects any of the contact info or the status update.
Fetches an authorization given its URL.
- Parameters
authorization_url – The authorization’s URL.
- Raises
aiohttp.ClientResponseErrorIf the authorization does not exist.- Returns
The fetched authorization.
Completes all authorizations associated with the given order.
Uses one of the registered
ChallengeSolverto complete one challenge per authorization.- Parameters
order – Order whose authorizations should be completed.
- Raises
CouldNotCompleteChallengeIf 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
aiohttp.ClientResponseErrorIf the certificate does not exist.ValueErrorIf the order has not been finalized yet, i.e. the certificate property is None.
- 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
aiohttp.ClientResponseErrorIf the certificate does not exist.acme.messages.ErrorIf the revocation did not succeed.
- 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.ClientResponseErrorIf 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.ClientResponseErrorIf 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
CouldNotCompleteChallengeIf 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
ValueErrorIf 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
identifiers –
listof identifiers that the order should contain. May either be a list of fully qualified domain names or a list ofdictcontaining the type and name (bothstr) of each identifier.- Raises
acme.messages.ErrorIf 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
acme.messages.ErrorIf the server is unwilling to finalize the order.aiohttp.ClientResponseErrorIf the order does not exist.
- 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.ClientResponseErrorIf 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
ValueErrorIf 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
ChallengeSolverusingregister_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()andcleanup_challenge(). Implementations must also be registered with the plugin registry viaregister_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
VALIDorINVALID.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
CouldNotCompleteChallengeIf 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_TIMEOUTseconds 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
CouldNotCompleteChallengeIf 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.
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
acme.messages.ErrorIf the Order has invalid identifiers.
-
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.
All requests to handlers apart from
new_nonce()anddirectory()are authenticated.- Parameters
key_auth – True if the JWK inside the JWS should be used to verify its signature. False otherwise
post_as_get – True if a POST-as-GET request is expected. False otherwise
expunge_account – True 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.HTTPNotFoundif the JWS contains a kid, but the corresponding account does not exist.acme.messages.Errorif 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_ALGORITHMSThe 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.
Only updates to the account’s status and contact fields are allowed. Returns the current account object if no updates were specified.
- Raises
acme.messages.ErrorIf the requested update is not allowed.aiohttp.web.HTTPNotFoundIf the account does not exist.
- Returns
The account object.
-
async
authz(request)¶ Handler that updates or queries the given authorization.
Only updates to the authorization’s status field are allowed.
7.5.2. Deactivating an Authorization
- Raises
acme.messages.ErrorIf the requested update is not allowed.aiohttp.web.HTTPNotFoundIf the authorization does not exist.
- Returns
The authorization object.
-
abstract async
certificate(request)¶ Handler that queries the given certificate.
7.4.2. Downloading the Certificate
- Raises
aiohttp.web.HTTPNotFoundIf 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.HTTPNotFoundIf 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.
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.HTTPNotFoundIf the order does not exist.acme.messages.Errorif any of the following are true:The order is not in state
acmetk.models.OrderStatus.READYThe 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.PROCESSINGinfinalize_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.
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.Errorif 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.VALIDThe 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.
- 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.
- Raises
aiohttp.web.HTTPNotFoundIf the order does not exist.- Returns
The order object.
-
async
orders(request)¶ Handler that retrieves the account’s chunked 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
ChallengeValidatorwith 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
ValueErrorIf 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.
- Raises
aiohttp.web.HTTPNotFoundIf the certificate does not exist.acme.messages.Errorif 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.Errorif 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.AcmeServerBaseBase 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.HTTPNotFoundIf 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
AcmeClientinstance
- 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.
The revocation is first relayed to the remote CA using the internal client before being processed internally.
- Raises
aiohttp.web.HTTPNotFoundIf the certificate does not exist.acme.messages.Errorif 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
ACME Certificate Authority¶
-
class
acmetk.server.AcmeCA(*, cert, private_key, **kwargs)¶ Bases:
acmetk.server.server.AcmeServerBaseACME compliant Certificate Authority.
-
async
certificate(request)¶ Handler that queries the given certificate.
7.4.2. Downloading the Certificate
- Raises
aiohttp.web.HTTPNotFoundIf 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.PROCESSINGinfinalize_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
-
async
ACME Broker¶
-
class
acmetk.server.AcmeBroker(*, client, **kwargs)¶ Bases:
acmetk.server.server.AcmeRelayBaseServer 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
AcmeProxyclass 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.PROCESSINGinfinalize_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
-
async
ACME Proxy¶
-
class
acmetk.server.AcmeProxy(*, client, **kwargs)¶ Bases:
acmetk.server.server.AcmeRelayBaseServer 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.HTTPNotFoundIf the order does not exist.acme.messages.Errorif any of the following are true:The order is not in state
acmetk.models.OrderStatus.READYThe 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.PROCESSINGinfinalize_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.
-
async
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 viaregister_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
CouldNotValidateChallengeexception if the validation failed.- Parameters
challenge – The challenge to be validated
- Raises
CouldNotValidateChallengeIf 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
ChallengeTypeDNS_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
CouldNotValidateChallengeIf 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.
-
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.
-
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
ExternalAccountBindingrequests and offers methods for creation and verification.-
create(request) → Tuple[str, str]¶ Creates an
ExternalAccountBindingrequest and stores it internally for verification at a later point in time.
-
-
class
acmetk.server.external_account_binding.AcmeEABMixin(**kwargs)¶ Mixin for an
AcmeServerBaseimplementation 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.Errorif 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
-
async
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
ValueErrorIf 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.JSONObjectWithFieldsPatched
acme.messages.Registrationmessage type that adds a kid field.This is the representation of a user account that the
AcmeClientuses internally. Thekidfield 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.-
status: acmetk.models.account.AccountStatus¶ The account’s status.
-
-
class
acmetk.models.messages.AccountUpdate(**kwargs)¶ Bases:
acmetk.models.messages.JSONDeSerializableAllowEmpty,acme.messages.RegistrationPatched
acme.messages.Registrationmessage type that adds a status field for status update requests.Inherits from
JSONDeSerializableAllowEmptyso 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.JSONObjectWithFieldsMessage type that allows (de-)serialization of authorization update request payloads.
Inherits from
JSONDeSerializableAllowEmptyso 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.JSONObjectWithFieldsMessage type for certificate requests.
Received by an
AcmeServerBaseinstance at the order finalization stepfinalize_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.
-
class
acmetk.models.messages.JSONDeSerializableAllowEmpty¶ Bases:
josepy.interfaces.JSONDeSerializableJSONDeSerializable that allows an empty string as the input for
json_loads().This subclass (sub-interface) is needed for
AuthorizationUpdateas well asAccountUpdate, 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.
-
class
acmetk.models.messages.KeyChange(**kwargs)¶ Bases:
josepy.json_util.JSONObjectWithFields
-
class
acmetk.models.messages.NewOrder(**kwargs)¶ Bases:
josepy.json_util.JSONObjectWithFieldsMessage 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
- Returns
The new order object.
-
not_after: datetime.datetime¶ The requested notAfter field in the certificate.
-
not_before: datetime.datetime¶ The requested notBefore field in the certificate.
-
classmethod
-
class
acmetk.models.messages.Order(**kwargs)¶ Bases:
acme.messages.OrderPatched
acme.messages.Ordermessage 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 theAcmeProxyto store the proxied URL and to be able to map an internal order to that of the remote CA.
-
class
acmetk.models.messages.Revocation(**kwargs)¶ Bases:
josepy.json_util.JSONObjectWithFieldsMessage 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.EnumCertificate 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.
-
account_id¶ The account’s permanent identifier
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
Accountfrom 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(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
contactfield and to thestatusfield.- 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¶
Database model for ACME authorization objects.
The authorization’s ID.
List of challenges (
Challenge) associated with the authorization.
The
datetime.datetimefrom which the authorization is considered expired.
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.
The
Identifierassociated with the authorization.
Returns whether the authorization has expired.
- Returns
True iff the authorization has expired.
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.
The authorization’s status.
Updates the authoziation’s status.
- Parameters
upd – The requested status update.
Returns the authorization’s URL.
- Parameters
request – The client request needed to build the URL.
- Returns
The authorization’s URL.
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.
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
certor the attributefull_chainis set.certis used by theAcmeCAas it appends its root certificate on certificate download.full_chainis used by all subclasses ofAcmeRelayBaseto 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.
-
order¶ The
acmetk.models.order.Orderassociated with the certificate.
-
reason¶ The revocation reason (
RevocationReason).
-
revoke(reason: acmetk.models.messages.RevocationReason)¶ Sets the certificate’s
statusto 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
The
Authorizationassociated 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.datetimewhen the challenge was validated.
-
class
acmetk.models.challenge.ChallengeType(value)¶ The types that a
Challengecan have.Subclassing
strsimplifies json serialization usingjson.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
-
_member_type_¶ alias of
builtins.str
-
Identifier¶
-
class
acmetk.models.identifier.Identifier(**kwargs)¶ Database model for ACME identifier objects.
8. Identifier Validation Challenges
The
Authorizationassociated with the identifier.
-
classmethod
from_obj(obj: acme.messages.Identifier) → acmetk.models.identifier.Identifier¶ A factory that constructs a new
Identifierfrom a message object.- Parameters
obj – The identifier message object.
- Returns
The constructed identifier.
-
identifier_id¶ The identifier’s ID.
-
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
Identifiercan have.Subclassing
strsimplifies json serialization usingjson.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.
-
certificate¶ The
Certificatethat 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.CertificateSigningRequestthat was submitted by the client.
-
expires¶ The
datetime.datetimefrom 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
Orderfrom 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, andChallengeobjects 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.