openssl_csr: catch errors on bad SANs (#106)
* Catch errors on bad SANs. * Add changelog fragment. * Adjust cryptography version and error message.pull/108/head
parent
ccc9e4dab2
commit
a2f36f426a
|
@ -0,0 +1,2 @@
|
||||||
|
bugfixes:
|
||||||
|
- "openssl_csr - improve handling of IDNA errors (https://github.com/ansible-collections/community.crypto/issues/105)."
|
|
@ -605,10 +605,12 @@ class CertificateSigningRequestBase(OpenSSLObject):
|
||||||
self.subject = self.subject + parse_name_field(module.params['subject'])
|
self.subject = self.subject + parse_name_field(module.params['subject'])
|
||||||
self.subject = [(entry[0], entry[1]) for entry in self.subject if entry[1]]
|
self.subject = [(entry[0], entry[1]) for entry in self.subject if entry[1]]
|
||||||
|
|
||||||
|
self.using_common_name_for_san = False
|
||||||
if not self.subjectAltName and module.params['use_common_name_for_san']:
|
if not self.subjectAltName and module.params['use_common_name_for_san']:
|
||||||
for sub in self.subject:
|
for sub in self.subject:
|
||||||
if sub[0] in ('commonName', 'CN'):
|
if sub[0] in ('commonName', 'CN'):
|
||||||
self.subjectAltName = ['DNS:%s' % sub[1]]
|
self.subjectAltName = ['DNS:%s' % sub[1]]
|
||||||
|
self.using_common_name_for_san = True
|
||||||
break
|
break
|
||||||
|
|
||||||
if self.subject_key_identifier is not None:
|
if self.subject_key_identifier is not None:
|
||||||
|
@ -962,6 +964,22 @@ class CertificateSigningRequestCryptography(CertificateSigningRequestBase):
|
||||||
if str(e) == 'Algorithm must be a registered hash algorithm.' and digest is None:
|
if str(e) == 'Algorithm must be a registered hash algorithm.' and digest is None:
|
||||||
self.module.fail_json(msg='Signing with Ed25519 and Ed448 keys requires cryptography 2.8 or newer.')
|
self.module.fail_json(msg='Signing with Ed25519 and Ed448 keys requires cryptography 2.8 or newer.')
|
||||||
raise
|
raise
|
||||||
|
except UnicodeError as e:
|
||||||
|
# This catches IDNAErrors, which happens when a bad name is passed as a SAN
|
||||||
|
# (https://github.com/ansible-collections/community.crypto/issues/105).
|
||||||
|
# For older cryptography versions, this is handled by idna, which raises
|
||||||
|
# an idna.core.IDNAError. Later versions of cryptography deprecated and stopped
|
||||||
|
# requiring idna, whence we cannot easily handle this error. Fortunately, in
|
||||||
|
# most versions of idna, IDNAError extends UnicodeError. There is only version
|
||||||
|
# 2.3 where it extends Exception instead (see
|
||||||
|
# https://github.com/kjd/idna/commit/ebefacd3134d0f5da4745878620a6a1cba86d130
|
||||||
|
# and then
|
||||||
|
# https://github.com/kjd/idna/commit/ea03c7b5db7d2a99af082e0239da2b68aeea702a).
|
||||||
|
msg = 'Error while creating CSR: {0}\n'.format(e)
|
||||||
|
if self.using_common_name_for_san:
|
||||||
|
self.module.fail_json(msg=msg + 'This is probably caused because the Common Name is used as a SAN.'
|
||||||
|
' Specifying use_common_name_for_san=false might fix this.')
|
||||||
|
self.module.fail_json(msg=msg + 'This is probably caused by an invalid Subject Alternative DNS Name.')
|
||||||
|
|
||||||
return self.request.public_bytes(cryptography.hazmat.primitives.serialization.Encoding.PEM)
|
return self.request.public_bytes(cryptography.hazmat.primitives.serialization.Encoding.PEM)
|
||||||
|
|
||||||
|
|
|
@ -162,7 +162,7 @@
|
||||||
commonName: www.ansible.com
|
commonName: www.ansible.com
|
||||||
select_crypto_backend: '{{ select_crypto_backend }}'
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
|
||||||
- name: Generate CSR with invalid SAN
|
- name: Generate CSR with invalid SAN (1/2)
|
||||||
openssl_csr:
|
openssl_csr:
|
||||||
path: '{{ output_dir }}/csrinvsan.csr'
|
path: '{{ output_dir }}/csrinvsan.csr'
|
||||||
privatekey_path: '{{ output_dir }}/privatekey.pem'
|
privatekey_path: '{{ output_dir }}/privatekey.pem'
|
||||||
|
@ -171,6 +171,15 @@
|
||||||
register: generate_csr_invalid_san
|
register: generate_csr_invalid_san
|
||||||
ignore_errors: yes
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- name: Generate CSR with invalid SAN (2/2)
|
||||||
|
openssl_csr:
|
||||||
|
path: '{{ output_dir }}/csrinvsan2.csr'
|
||||||
|
privatekey_path: '{{ output_dir }}/privatekey.pem'
|
||||||
|
subject_alt_name: "DNS:system:kube-controller-manager"
|
||||||
|
select_crypto_backend: '{{ select_crypto_backend }}'
|
||||||
|
register: generate_csr_invalid_san_2
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
- name: Generate CSR with OCSP Must Staple
|
- name: Generate CSR with OCSP Must Staple
|
||||||
openssl_csr:
|
openssl_csr:
|
||||||
path: '{{ output_dir }}/csr_ocsp.csr'
|
path: '{{ output_dir }}/csr_ocsp.csr'
|
||||||
|
|
|
@ -62,12 +62,21 @@
|
||||||
- csr_oldapi_cn.stdout.split('=')[-1] == 'www.ansible.com'
|
- csr_oldapi_cn.stdout.split('=')[-1] == 'www.ansible.com'
|
||||||
- csr_oldapi_modulus.stdout == privatekey_modulus.stdout
|
- csr_oldapi_modulus.stdout == privatekey_modulus.stdout
|
||||||
|
|
||||||
- name: Validate invalid SAN
|
- name: Validate invalid SAN (1/2)
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- generate_csr_invalid_san is failed
|
- generate_csr_invalid_san is failed
|
||||||
- "'Subject Alternative Name' in generate_csr_invalid_san.msg"
|
- "'Subject Alternative Name' in generate_csr_invalid_san.msg"
|
||||||
|
|
||||||
|
- name: Validate invalid SAN (2/2)
|
||||||
|
# Note that pyOpenSSL simply accepts this name, and modern cryptography versions do so as well.
|
||||||
|
# The error has been observed with cryptography 1.7.2 and 1.9, but not with 2.3 and newer.
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- generate_csr_invalid_san_2 is failed
|
||||||
|
- "'The label system:kube-controller-manager is not a valid A-label' in generate_csr_invalid_san_2.msg"
|
||||||
|
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('2.0', '<')
|
||||||
|
|
||||||
- name: Validate OCSP Must Staple CSR (test - everything)
|
- name: Validate OCSP Must Staple CSR (test - everything)
|
||||||
shell: "openssl req -noout -in {{ output_dir }}/csr_ocsp.csr -text"
|
shell: "openssl req -noout -in {{ output_dir }}/csr_ocsp.csr -text"
|
||||||
register: csr_ocsp
|
register: csr_ocsp
|
||||||
|
|
Loading…
Reference in New Issue