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:
Felix Fontein 2019-03-05 00:09:48 +01:00 committed by René Moser
parent aba4bed803
commit 6249bb8ea4
4 changed files with 72 additions and 0 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- "openssl_certificate - make sure that extensions are actually present when their values should be checked."

View file

@ -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:

View file

@ -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"

View file

@ -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