openssl_certificate: make sure extensions are present when they are queried by assertonly (#53207)
* Make sure extensions are present when they are queried by assertonly provider. * Add changelog.
This commit is contained in:
parent
aba4bed803
commit
6249bb8ea4
4 changed files with 72 additions and 0 deletions
|
@ -0,0 +1,2 @@
|
||||||
|
bugfixes:
|
||||||
|
- "openssl_certificate - make sure that extensions are actually present when their values should be checked."
|
|
@ -886,9 +886,11 @@ class AssertOnlyCertificate(Certificate):
|
||||||
|
|
||||||
def _validate_keyUsage():
|
def _validate_keyUsage():
|
||||||
if self.keyUsage:
|
if self.keyUsage:
|
||||||
|
found = False
|
||||||
for extension_idx in range(0, self.cert.get_extension_count()):
|
for extension_idx in range(0, self.cert.get_extension_count()):
|
||||||
extension = self.cert.get_extension(extension_idx)
|
extension = self.cert.get_extension(extension_idx)
|
||||||
if extension.get_short_name() == b'keyUsage':
|
if extension.get_short_name() == b'keyUsage':
|
||||||
|
found = True
|
||||||
keyUsage = [OpenSSL._util.lib.OBJ_txt2nid(keyUsage) for keyUsage in self.keyUsage]
|
keyUsage = [OpenSSL._util.lib.OBJ_txt2nid(keyUsage) for keyUsage in self.keyUsage]
|
||||||
current_ku = [OpenSSL._util.lib.OBJ_txt2nid(usage.strip()) for usage in
|
current_ku = [OpenSSL._util.lib.OBJ_txt2nid(usage.strip()) for usage in
|
||||||
to_bytes(extension, errors='surrogate_or_strict').split(b',')]
|
to_bytes(extension, errors='surrogate_or_strict').split(b',')]
|
||||||
|
@ -897,12 +899,16 @@ class AssertOnlyCertificate(Certificate):
|
||||||
self.message.append(
|
self.message.append(
|
||||||
'Invalid keyUsage component (got %s, expected all of %s to be present)' % (str(extension).split(', '), self.keyUsage)
|
'Invalid keyUsage component (got %s, expected all of %s to be present)' % (str(extension).split(', '), self.keyUsage)
|
||||||
)
|
)
|
||||||
|
if not found:
|
||||||
|
self.message.append('Found no keyUsage extension')
|
||||||
|
|
||||||
def _validate_extendedKeyUsage():
|
def _validate_extendedKeyUsage():
|
||||||
if self.extendedKeyUsage:
|
if self.extendedKeyUsage:
|
||||||
|
found = False
|
||||||
for extension_idx in range(0, self.cert.get_extension_count()):
|
for extension_idx in range(0, self.cert.get_extension_count()):
|
||||||
extension = self.cert.get_extension(extension_idx)
|
extension = self.cert.get_extension(extension_idx)
|
||||||
if extension.get_short_name() == b'extendedKeyUsage':
|
if extension.get_short_name() == b'extendedKeyUsage':
|
||||||
|
found = True
|
||||||
extKeyUsage = [OpenSSL._util.lib.OBJ_txt2nid(keyUsage) for keyUsage in self.extendedKeyUsage]
|
extKeyUsage = [OpenSSL._util.lib.OBJ_txt2nid(keyUsage) for keyUsage in self.extendedKeyUsage]
|
||||||
current_xku = [OpenSSL._util.lib.OBJ_txt2nid(usage.strip()) for usage in
|
current_xku = [OpenSSL._util.lib.OBJ_txt2nid(usage.strip()) for usage in
|
||||||
to_bytes(extension, errors='surrogate_or_strict').split(b',')]
|
to_bytes(extension, errors='surrogate_or_strict').split(b',')]
|
||||||
|
@ -912,12 +918,16 @@ class AssertOnlyCertificate(Certificate):
|
||||||
'Invalid extendedKeyUsage component (got %s, expected all of %s to be present)' % (str(extension).split(', '),
|
'Invalid extendedKeyUsage component (got %s, expected all of %s to be present)' % (str(extension).split(', '),
|
||||||
self.extendedKeyUsage)
|
self.extendedKeyUsage)
|
||||||
)
|
)
|
||||||
|
if not found:
|
||||||
|
self.message.append('Found no extendedKeyUsage extension')
|
||||||
|
|
||||||
def _validate_subjectAltName():
|
def _validate_subjectAltName():
|
||||||
if self.subjectAltName:
|
if self.subjectAltName:
|
||||||
|
found = False
|
||||||
for extension_idx in range(0, self.cert.get_extension_count()):
|
for extension_idx in range(0, self.cert.get_extension_count()):
|
||||||
extension = self.cert.get_extension(extension_idx)
|
extension = self.cert.get_extension(extension_idx)
|
||||||
if extension.get_short_name() == b'subjectAltName':
|
if extension.get_short_name() == b'subjectAltName':
|
||||||
|
found = True
|
||||||
l_altnames = [altname.replace(b'IP Address', b'IP') for altname in
|
l_altnames = [altname.replace(b'IP Address', b'IP') for altname in
|
||||||
to_bytes(extension, errors='surrogate_or_strict').split(b', ')]
|
to_bytes(extension, errors='surrogate_or_strict').split(b', ')]
|
||||||
if (not self.subjectAltName_strict and not all(x in l_altnames for x in self.subjectAltName)) or \
|
if (not self.subjectAltName_strict and not all(x in l_altnames for x in self.subjectAltName)) or \
|
||||||
|
@ -925,6 +935,8 @@ class AssertOnlyCertificate(Certificate):
|
||||||
self.message.append(
|
self.message.append(
|
||||||
'Invalid subjectAltName component (got %s, expected all of %s to be present)' % (l_altnames, self.subjectAltName)
|
'Invalid subjectAltName component (got %s, expected all of %s to be present)' % (l_altnames, self.subjectAltName)
|
||||||
)
|
)
|
||||||
|
if not found:
|
||||||
|
self.message.append('Found no subjectAltName extension')
|
||||||
|
|
||||||
def _validate_notBefore():
|
def _validate_notBefore():
|
||||||
if self.notBefore:
|
if self.notBefore:
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
---
|
||||||
|
- name: Generate privatekey
|
||||||
|
openssl_privatekey:
|
||||||
|
path: '{{ output_dir }}/privatekey.pem'
|
||||||
|
|
||||||
|
- name: Generate CSR (no extensions)
|
||||||
|
openssl_csr:
|
||||||
|
path: '{{ output_dir }}/csr_noext.csr'
|
||||||
|
privatekey_path: '{{ output_dir }}/privatekey.pem'
|
||||||
|
subject:
|
||||||
|
commonName: www.example.com
|
||||||
|
useCommonNameForSAN: no
|
||||||
|
|
||||||
|
- name: Generate selfsigned certificate (no extensions)
|
||||||
|
openssl_certificate:
|
||||||
|
path: '{{ output_dir }}/cert_noext.pem'
|
||||||
|
csr_path: '{{ output_dir }}/csr_noext.csr'
|
||||||
|
privatekey_path: '{{ output_dir }}/privatekey.pem'
|
||||||
|
provider: selfsigned
|
||||||
|
selfsigned_digest: sha256
|
||||||
|
|
||||||
|
- name: Assert that subject_alt_name is there (should fail)
|
||||||
|
openssl_certificate:
|
||||||
|
path: '{{ output_dir }}/cert_noext.pem'
|
||||||
|
provider: assertonly
|
||||||
|
subject_alt_name:
|
||||||
|
- "DNS:example.com"
|
||||||
|
ignore_errors: yes
|
||||||
|
register: extension_missing_san
|
||||||
|
|
||||||
|
- name: Assert that key_usage is there (should fail)
|
||||||
|
openssl_certificate:
|
||||||
|
path: '{{ output_dir }}/cert_noext.pem'
|
||||||
|
provider: assertonly
|
||||||
|
key_usage:
|
||||||
|
- digitalSignature
|
||||||
|
ignore_errors: yes
|
||||||
|
register: extension_missing_ku
|
||||||
|
|
||||||
|
- name: Assert that extended_key_usage is there (should fail)
|
||||||
|
openssl_certificate:
|
||||||
|
path: '{{ output_dir }}/cert_noext.pem'
|
||||||
|
provider: assertonly
|
||||||
|
extended_key_usage:
|
||||||
|
- biometricInfo
|
||||||
|
ignore_errors: yes
|
||||||
|
register: extension_missing_eku
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- extension_missing_san is failed
|
||||||
|
- "'Found no subjectAltName extension' in extension_missing_san.msg"
|
||||||
|
- extension_missing_ku is failed
|
||||||
|
- "'Found no keyUsage extension' in extension_missing_ku.msg"
|
||||||
|
- extension_missing_eku is failed
|
||||||
|
- "'Found no extendedKeyUsage extension' in extension_missing_eku.msg"
|
|
@ -1,6 +1,8 @@
|
||||||
---
|
---
|
||||||
- block:
|
- block:
|
||||||
|
|
||||||
|
- import_tasks: assertonly.yml
|
||||||
|
|
||||||
- import_tasks: expired.yml
|
- import_tasks: expired.yml
|
||||||
|
|
||||||
- import_tasks: selfsigned.yml
|
- import_tasks: selfsigned.yml
|
||||||
|
|
Loading…
Reference in a new issue