ACME: add seealso references (#50320)

* Add seealso references to ACME modules.

* Bump to latest drafts.
This commit is contained in:
Felix Fontein 2018-12-26 14:26:46 +01:00 committed by John R Barker
commit a1dfce3aa1
7 changed files with 89 additions and 35 deletions

View file

@ -429,7 +429,7 @@ class ACMEDirectory(object):
and allows to obtain a Replay-Nonce. The acme_directory URL and allows to obtain a Replay-Nonce. The acme_directory URL
needs to support unauthenticated GET requests; ACME endpoints needs to support unauthenticated GET requests; ACME endpoints
requiring authentication are not supported. requiring authentication are not supported.
https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-7.1.1 https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-7.1.1
''' '''
def __init__(self, module, account): def __init__(self, module, account):
@ -500,7 +500,7 @@ class ACMEAccount(object):
def get_keyauthorization(self, token): def get_keyauthorization(self, token):
''' '''
Returns the key authorization for the given token Returns the key authorization for the given token
https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-8.1 https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-8.1
''' '''
accountkey_json = json.dumps(self.jwk, sort_keys=True, separators=(',', ':')) accountkey_json = json.dumps(self.jwk, sort_keys=True, separators=(',', ':'))
thumbprint = nopad_b64(hashlib.sha256(accountkey_json.encode('utf8')).digest()) thumbprint = nopad_b64(hashlib.sha256(accountkey_json.encode('utf8')).digest())
@ -541,10 +541,10 @@ class ACMEAccount(object):
''' '''
Sends a JWS signed HTTP POST request to the ACME server and returns Sends a JWS signed HTTP POST request to the ACME server and returns
the response as dictionary the response as dictionary
https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-6.2 https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-6.2
If payload is None, a POST-as-GET is performed. If payload is None, a POST-as-GET is performed.
(https://tools.ietf.org/html/draft-ietf-acme-acme-15#section-6.3) (https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-6.3)
''' '''
key_data = key_data or self.key_data key_data = key_data or self.key_data
jws_header = jws_header or self.jws_header jws_header = jws_header or self.jws_header
@ -575,7 +575,7 @@ class ACMEAccount(object):
try: try:
decoded_result = self.module.from_json(content.decode('utf8')) decoded_result = self.module.from_json(content.decode('utf8'))
# In case of badNonce error, try again (up to 5 times) # In case of badNonce error, try again (up to 5 times)
# (https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-6.6) # (https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-6.7)
if (400 <= info['status'] < 600 and if (400 <= info['status'] < 600 and
decoded_result.get('type') == 'urn:ietf:params:acme:error:badNonce' and decoded_result.get('type') == 'urn:ietf:params:acme:error:badNonce' and
failed_tries <= 5): failed_tries <= 5):
@ -651,7 +651,7 @@ class ACMEAccount(object):
``False`` if it already existed (e.g. it was not newly created), ``False`` if it already existed (e.g. it was not newly created),
or does not exist. In case the account was created or exists, or does not exist. In case the account was created or exists,
``data`` contains the account data; otherwise, it is ``None``. ``data`` contains the account data; otherwise, it is ``None``.
https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-7.3 https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-7.3
''' '''
contact = contact or [] contact = contact or []
@ -670,7 +670,7 @@ class ACMEAccount(object):
'contact': contact 'contact': contact
} }
if not allow_creation: if not allow_creation:
# https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-7.3.1 # https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-7.3.1
new_reg['onlyReturnExisting'] = True new_reg['onlyReturnExisting'] = True
if terms_agreed: if terms_agreed:
new_reg['termsOfServiceAgreed'] = True new_reg['termsOfServiceAgreed'] = True
@ -688,7 +688,7 @@ class ACMEAccount(object):
if result.get('status') == 'deactivated': if result.get('status') == 'deactivated':
# A probable bug in Pebble (https://github.com/letsencrypt/pebble/issues/179) # A probable bug in Pebble (https://github.com/letsencrypt/pebble/issues/179)
# and Boulder: this should not return a valid account object according to # and Boulder: this should not return a valid account object according to
# https://tools.ietf.org/html/draft-ietf-acme-acme-16#section-7.3.6: # https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-7.3.6:
# "Once an account is deactivated, the server MUST NOT accept further # "Once an account is deactivated, the server MUST NOT accept further
# requests authorized by that account's key." # requests authorized by that account's key."
if not allow_creation: if not allow_creation:
@ -755,7 +755,7 @@ class ACMEAccount(object):
The account URI will be stored in ``self.uri``; if it is ``None``, The account URI will be stored in ``self.uri``; if it is ``None``,
the account does not exist. the account does not exist.
https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-7.3 https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-7.3
''' '''
if self.uri is not None: if self.uri is not None:
@ -793,7 +793,7 @@ class ACMEAccount(object):
would be changed (check mode), and ``account_data`` the updated would be changed (check mode), and ``account_data`` the updated
account data. account data.
https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-7.3.2 https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-7.3.2
''' '''
# Create request # Create request
update_request = {} update_request = {}

View file

@ -21,16 +21,24 @@ version_added: "2.6"
short_description: Create, modify or delete ACME accounts short_description: Create, modify or delete ACME accounts
description: description:
- "Allows to create, modify or delete accounts with a CA supporting the - "Allows to create, modify or delete accounts with a CA supporting the
L(ACME protocol,https://tools.ietf.org/html/draft-ietf-acme-acme-14), L(ACME protocol,https://tools.ietf.org/html/draft-ietf-acme-acme-18),
such as L(Let's Encrypt,https://letsencrypt.org/)." such as L(Let's Encrypt,https://letsencrypt.org/)."
- "This module only works with the ACME v2 protocol." - "This module only works with the ACME v2 protocol."
notes: notes:
- "Facts about an ACME account can be retrieved with the M(acme_account_facts)
module."
- "The M(acme_certificate) module also allows to do basic account management. - "The M(acme_certificate) module also allows to do basic account management.
When using both modules, it is recommended to disable account management When using both modules, it is recommended to disable account management
for M(acme_certificate). For that, use the C(modify_account) option of for M(acme_certificate). For that, use the C(modify_account) option of
M(acme_certificate)." M(acme_certificate)."
seealso:
- name: Automatic Certificate Management Environment (ACME)
description: The current draft specification of the ACME protocol.
link: https://tools.ietf.org/html/draft-ietf-acme-acme-18
- module: acme_account_facts
description: Retrieves facts about an ACME account.
- module: openssl_privatekey
description: Can be used to create a private account key.
- module: acme_inspect
description: Allows to debug problems.
extends_documentation_fragment: extends_documentation_fragment:
- acme - acme
options: options:
@ -55,7 +63,7 @@ options:
description: description:
- "A list of contact URLs." - "A list of contact URLs."
- "Email addresses must be prefixed with C(mailto:)." - "Email addresses must be prefixed with C(mailto:)."
- "See https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-7.1.2 - "See https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-7.1.2
for what is allowed." for what is allowed."
- "Must be specified when state is C(present). Will be ignored - "Must be specified when state is C(present). Will be ignored
if state is C(absent) or C(changed_key)." if state is C(absent) or C(changed_key)."
@ -230,7 +238,7 @@ def main():
# Now we can start the account key rollover # Now we can start the account key rollover
if not module.check_mode: if not module.check_mode:
# Compose inner signed message # Compose inner signed message
# https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-7.3.6 # https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-7.3.5
url = account.directory['keyChange'] url = account.directory['keyChange']
protected = { protected = {
"alg": new_key_data['alg'], "alg": new_key_data['alg'],

View file

@ -21,11 +21,14 @@ version_added: "2.7"
short_description: Retrieves information on ACME accounts short_description: Retrieves information on ACME accounts
description: description:
- "Allows to retrieve information on accounts a CA supporting the - "Allows to retrieve information on accounts a CA supporting the
L(ACME protocol,https://tools.ietf.org/html/draft-ietf-acme-acme-14), L(ACME protocol,https://tools.ietf.org/html/draft-ietf-acme-acme-18),
such as L(Let's Encrypt,https://letsencrypt.org/)." such as L(Let's Encrypt,https://letsencrypt.org/)."
- "This module only works with the ACME v2 protocol." - "This module only works with the ACME v2 protocol."
notes: notes:
- "The M(acme_account) module allows to modify, create and delete ACME accounts." - "The M(acme_account) module allows to modify, create and delete ACME accounts."
seealso:
- module: acme_account
description: Allows to create, modify or delete an ACME account.
extends_documentation_fragment: extends_documentation_fragment:
- acme - acme
''' '''

View file

@ -21,7 +21,7 @@ version_added: "2.2"
short_description: Create SSL/TLS certificates with the ACME protocol short_description: Create SSL/TLS certificates with the ACME protocol
description: description:
- "Create and renew SSL/TLS certificates with a CA supporting the - "Create and renew SSL/TLS certificates with a CA supporting the
L(ACME protocol,https://tools.ietf.org/html/draft-ietf-acme-acme-14), L(ACME protocol,https://tools.ietf.org/html/draft-ietf-acme-acme-18),
such as L(Let's Encrypt,https://letsencrypt.org/). The current such as L(Let's Encrypt,https://letsencrypt.org/). The current
implementation supports the C(http-01), C(dns-01) and C(tls-alpn-01) implementation supports the C(http-01), C(dns-01) and C(tls-alpn-01)
challenges." challenges."
@ -36,7 +36,7 @@ description:
the necessary certificate has to be created and served. the necessary certificate has to be created and served.
It is I(not) the responsibility of this module to perform these steps." It is I(not) the responsibility of this module to perform these steps."
- "For details on how to fulfill these challenges, you might have to read through - "For details on how to fulfill these challenges, you might have to read through
L(the main ACME specification,https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-8) L(the main ACME specification,https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-8)
and the L(TLS-ALPN-01 specification,https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-05#section-3). and the L(TLS-ALPN-01 specification,https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-05#section-3).
Also, consider the examples provided for this module." Also, consider the examples provided for this module."
notes: notes:
@ -47,12 +47,31 @@ notes:
option." option."
- "This module was called C(letsencrypt) before Ansible 2.6. The usage - "This module was called C(letsencrypt) before Ansible 2.6. The usage
did not change." did not change."
- "If you want to use the C(tls-alpn-01) challenge, you can use the seealso:
M(acme_challenge_cert_helper) module to prepare the challenge certificate." - name: The Let's Encrypt documentation
- "You can use the M(certificate_complete_chain) module to find the root certificate description: Documentation for the Let's Encrypt Certification Authority.
for the returned fullchain." Provides useful information for example on rate limits.
- "In case you want to debug problems, you might be interested in the M(acme_inspect) link: https://letsencrypt.org/docs/
module." - name: Automatic Certificate Management Environment (ACME)
description: The current draft specification of the ACME protocol.
link: https://tools.ietf.org/html/draft-ietf-acme-acme-18
- name: ACME TLS ALPN Challenge Extension
description: The current draft specification of the C(tls-alpn-01) challenge.
link: https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-05
- module: acme_challenge_cert_helper
description: Helps preparing C(tls-alpn-01) challenges.
- module: openssl_privatekey
description: Can be used to create private keys (both for certificates and accounts).
- module: openssl_csr
description: Can be used to create a Certificate Signing Request (CSR).
- module: certificate_complete_chain
description: Allows to find the root certificate for the returned fullchain.
- module: acme_certificate_revoke
description: Allows to revoke certificates.
- module: acme_account
description: Allows to create, modify or delete an ACME account.
- module: acme_inspect
description: Allows to debug problems.
extends_documentation_fragment: extends_documentation_fragment:
- acme - acme
options: options:
@ -313,7 +332,7 @@ authorizations:
type: complex type: complex
contains: contains:
authorization: authorization:
description: ACME authorization object. See U(https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-7.1.4) description: ACME authorization object. See U(https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-7.1.4)
returned: success returned: success
type: dict type: dict
order_uri: order_uri:
@ -503,11 +522,11 @@ class ACMEClient(object):
keyauthorization = self.account.get_keyauthorization(token) keyauthorization = self.account.get_keyauthorization(token)
if type == 'http-01': if type == 'http-01':
# https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-8.3 # https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-8.3
resource = '.well-known/acme-challenge/' + token resource = '.well-known/acme-challenge/' + token
data[type] = {'resource': resource, 'resource_value': keyauthorization} data[type] = {'resource': resource, 'resource_value': keyauthorization}
elif type == 'dns-01': elif type == 'dns-01':
# https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-8.4 # https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-8.4
resource = '_acme-challenge' resource = '_acme-challenge'
value = nopad_b64(hashlib.sha256(to_bytes(keyauthorization)).digest()) value = nopad_b64(hashlib.sha256(to_bytes(keyauthorization)).digest())
record = (resource + domain[1:]) if domain.startswith('*.') else (resource + '.' + domain) record = (resource + domain[1:]) if domain.startswith('*.') else (resource + '.' + domain)
@ -584,7 +603,7 @@ class ACMEClient(object):
''' '''
Create a new certificate based on the csr. Create a new certificate based on the csr.
Return the certificate object as dict Return the certificate object as dict
https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-7.4 https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-7.4
''' '''
csr = pem_to_der(self.csr) csr = pem_to_der(self.csr)
new_cert = { new_cert = {
@ -618,7 +637,7 @@ class ACMEClient(object):
def _download_cert(self, url): def _download_cert(self, url):
''' '''
Download and parse the certificate chain. Download and parse the certificate chain.
https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-7.4.2 https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-7.4.2
''' '''
content, info = self.account.get_request(url, parse_json_result=False, headers={'Accept': 'application/pem-certificate-chain'}) content, info = self.account.get_request(url, parse_json_result=False, headers={'Accept': 'application/pem-certificate-chain'})
@ -686,7 +705,7 @@ class ACMEClient(object):
def _new_order_v2(self): def _new_order_v2(self):
''' '''
Start a new certificate order (ACME v2 protocol). Start a new certificate order (ACME v2 protocol).
https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-7.4 https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-7.4
''' '''
identifiers = [] identifiers = []
for domain in self.domains: for domain in self.domains:
@ -843,7 +862,7 @@ class ACMEClient(object):
''' '''
Deactivates all valid authz's. Does not raise exceptions. Deactivates all valid authz's. Does not raise exceptions.
https://community.letsencrypt.org/t/authorization-deactivation/19860/2 https://community.letsencrypt.org/t/authorization-deactivation/19860/2
https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-7.5.2 https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-7.5.2
''' '''
authz_deactivate = { authz_deactivate = {
'status': 'deactivated' 'status': 'deactivated'

View file

@ -21,7 +21,7 @@ version_added: "2.7"
short_description: Revoke certificates with the ACME protocol short_description: Revoke certificates with the ACME protocol
description: description:
- "Allows to revoke certificates issued by a CA supporting the - "Allows to revoke certificates issued by a CA supporting the
L(ACME protocol,https://tools.ietf.org/html/draft-ietf-acme-acme-14), L(ACME protocol,https://tools.ietf.org/html/draft-ietf-acme-acme-18),
such as L(Let's Encrypt,https://letsencrypt.org/)." such as L(Let's Encrypt,https://letsencrypt.org/)."
notes: notes:
- "Exactly one of C(account_key_src), C(account_key_content), - "Exactly one of C(account_key_src), C(account_key_content),
@ -31,6 +31,16 @@ notes:
was different than the one specified here. Also, depending on the was different than the one specified here. Also, depending on the
server, it can happen that some other error is returned if the server, it can happen that some other error is returned if the
certificate has already been revoked." certificate has already been revoked."
seealso:
- name: The Let's Encrypt documentation
description: Documentation for the Let's Encrypt Certification Authority.
Provides useful information for example on rate limits.
link: https://letsencrypt.org/docs/
- name: Automatic Certificate Management Environment (ACME)
description: The current draft specification of the ACME protocol.
link: https://tools.ietf.org/html/draft-ietf-acme-acme-18
- module: acme_inspect
description: Allows to debug problems.
extends_documentation_fragment: extends_documentation_fragment:
- acme - acme
options: options:
@ -186,7 +196,7 @@ def main():
result, info = account.send_signed_request(endpoint, payload) result, info = account.send_signed_request(endpoint, payload)
if info['status'] != 200: if info['status'] != 200:
already_revoked = False already_revoked = False
# Standarized error in draft 14 (https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-7.6) # Standarized error from draft 14 on (https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-7.6)
if result.get('type') == 'urn:ietf:params:acme:error:alreadyRevoked': if result.get('type') == 'urn:ietf:params:acme:error:alreadyRevoked':
already_revoked = True already_revoked = True
else: else:

View file

@ -26,6 +26,13 @@ description:
provides a simple way to generate the required certificates." provides a simple way to generate the required certificates."
- "The C(tls-alpn-01) implementation is based on - "The C(tls-alpn-01) implementation is based on
L(the draft-05 version of the specification,https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-05)." L(the draft-05 version of the specification,https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-05)."
seealso:
- name: Automatic Certificate Management Environment (ACME)
description: The current draft specification of the ACME protocol.
link: https://tools.ietf.org/html/draft-ietf-acme-acme-18
- name: ACME TLS ALPN Challenge Extension
description: The current draft specification of the C(tls-alpn-01) challenge.
link: https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-05
requirements: requirements:
- "cryptography >= 1.3" - "cryptography >= 1.3"
options: options:

View file

@ -21,7 +21,7 @@ version_added: "2.8"
short_description: Send direct requests to an ACME server short_description: Send direct requests to an ACME server
description: description:
- "Allows to send direct requests to an ACME server with the - "Allows to send direct requests to an ACME server with the
L(ACME protocol,https://tools.ietf.org/html/draft-ietf-acme-acme-14), L(ACME protocol,https://tools.ietf.org/html/draft-ietf-acme-acme-18),
which is supported by CAs such as L(Let's Encrypt,https://letsencrypt.org/)." which is supported by CAs such as L(Let's Encrypt,https://letsencrypt.org/)."
- "This module can be used to debug failed certificate request attempts, - "This module can be used to debug failed certificate request attempts,
for example when M(acme_certificate) fails or encounters a problem which for example when M(acme_certificate) fails or encounters a problem which
@ -39,6 +39,13 @@ notes:
acme_directory=https://acme-v02.api.letsencrypt.org/directory acme_version=2 acme_directory=https://acme-v02.api.letsencrypt.org/directory acme_version=2
account_uri=https://acme-v02.api.letsencrypt.org/acme/acct/1 method=get account_uri=https://acme-v02.api.letsencrypt.org/acme/acct/1 method=get
url=https://acme-v02.api.letsencrypt.org/acme/acct/1\")" url=https://acme-v02.api.letsencrypt.org/acme/acct/1\")"
seealso:
- name: Automatic Certificate Management Environment (ACME)
description: The current draft specification of the ACME protocol.
link: https://tools.ietf.org/html/draft-ietf-acme-acme-18
- name: ACME TLS ALPN Challenge Extension
description: The current draft specification of the C(tls-alpn-01) challenge.
link: https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-05
extends_documentation_fragment: extends_documentation_fragment:
- acme - acme
options: options:
@ -116,7 +123,7 @@ EXAMPLES = r'''
vars: vars:
account_info: account_info:
# For valid values, see # For valid values, see
# https://tools.ietf.org/html/draft-ietf-acme-acme-16#section-7.3 # https://tools.ietf.org/html/draft-ietf-acme-acme-18#section-7.3
contact: contact:
- mailto:me@example.com - mailto:me@example.com