##### SUMMARY
During some discussions over the last half year or so, we've discussed deprecating the `assertonly` provider and replacing it with `_info` modules + assert statements, or possibly more `_info` / other modules.

I want to use this issue to track what can already be replaced with `openssl_certificate_info` + `assert`, and what still needs features (or new modules).

I hope I listed everything that `assertonly` can check; please verify this :)

##### ISSUE TYPE
- Feature Idea

##### COMPONENT NAME
openssl_certificate
openssl_certificate_info

##### ASSERTONLY FEATURES
The task snippets assume that `result` is the result of registering the `openssl_certificate_info` output, if not said otherwise.

- [x] `signature_algorithms`

  ```.yaml
  - assert:
      that:
        - "result.signature_algorithm == 'sha256WithRSAEncryption' or result.signature_algorithm == 'sha512WithRSAEncryption'"
  ```

- [x] `subject` and  `subject_strict`

  ```.yaml
  - assert:
      that:
        - "result.subject.commonName == 'ansible.com'"
        - "result.subject | len == 1"  # for subject_strict
  ```

- [x] `issuer` and `issuer_strict`

  ```.yaml
  - assert:
      that:
        - "result.issuer.commonName == 'ansible.com'"
        - "result.issuer | len == 1"  # for issuer_strict
  ```

- [x] `has_expired`

  ```.yaml
  - assert:
      that:
        - result.expired
  ```

- [x] `version`

  ```.yaml
  - assert:
      that:
        - result.version == 3
  ```

- [x] `key_usage` and `key_usage_strict`

  ```.yaml
  - assert:
      that:
        - "'Data Encipherment' in result.key_usage"
        - "result.key_usage | len == 1"  # for key_usage_strict
  ```

- [x] `extended_key_usage` and `extended_key_usage_strict`

  ```.yaml
  - assert:
      that:
        - "'DVCS' in result.extended_key_usage"
        - "result.extended_key_usage | len == 1"  # for extended_key_usage_strict
  ```

- [x] `subject_alt_name` and `subject_alt_name_strict`

  ```.yaml
  - assert:
      that:
        - "'dns:ansible.com' in result.subject_alt_name"
        - "result.subject_alt_name | len == 1"  # for subject_alt_name_strict
  ```

- [x] `not_before` and `not_after`

  ```.yaml
  - assert:
      that:
        - "result.not_before == '20190413202428Z'"
        - "result.not_after == '20190331202428Z'"
  ```

  What's not working yet: relative timestamps don't work out of the box, since Ansible has no date / time filters. This can partially be done with `valid_at`, though.

- [x] `valid_at`,  `invalid_at` and  `valid_in`

  ```.yaml
  - openssl_certificate_info:
      path: ...
      valid_at:
        one_day_ten_hours: "+1d+10h"
    register: result
  - assert:
      that:
        - "result.valid_at.one_day_ten_hours"  # for valid_at
        - "not result.valid_at.one_day_ten_hours"  # for invalid_at
  ```

- [x] `privatekey`: check whether public keys of private key and certificate are identical

  ```.yaml
  - openssl_privatekey_info:
      path: ...
    register: result_privatekey
  - assert:
      that:
        - result.public_key == result_privatekey.public_key
  ```

- [x] `csr`: check CSR signature (CSR signature must be valid, and CSR public key must equal certificate public key)

  ```.yaml
  - openssl_csr_info:
      path: ...
      # module will fail if CSR signature is invalid
    register: result_csr
  - assert:
      that:
        - result.public_key == result_csr.public_key
  ```

- [x] `csr`: check CSR subject

  ```.yaml
  - openssl_csr_info:
      path: ...
    register: result_csr
  - assert:
      that:
        - result.subject == result_csr.subject
  ```

- [x] `csr`: check CSR extensions

  ```.yaml
  - openssl_csr_info:
      path: ...
    register: result_csr
  - assert:
      that:
        - result.extensions_by_oid == result_csr.extensions_by_oid
  ```

rt = self.get_relative_time_option(self.valid_at, 'valid_at')
        return self.cert.not_valid_before, rt, self.cert.not_valid_after
    def _validate_invalid_at(self):
        rt = self.get_relative_time_option(self.invalid_at, 'invalid_at')
        return self.cert.not_valid_before, rt, self.cert.not_valid_after
    def _validate_valid_in(self):
        valid_in_date = self.get_relative_time_option(self.valid_in, "valid_in")
        return self.cert.not_valid_before, valid_in_date, self.cert.not_valid_after
class AssertOnlyCertificate(AssertOnlyCertificateBase):
    """validate the supplied certificate."""
    def __init__(self, module):
        super(AssertOnlyCertificate, self).__init__(module, 'pyopenssl')
        
        for param in ['signature_algorithms', 'key_usage', 'extended_key_usage',
                      'subject_alt_name', 'subject', 'issuer', 'not_before',
                      'not_after', 'valid_at', 'invalid_at']:
            attr = getattr(self, param)
            if isinstance(attr, list) and attr:
                if isinstance(attr[0], str):
                    setattr(self, param, [to_bytes(item) for item in attr])
                elif isinstance(attr[0], tuple):
                    setattr(self, param, [(to_bytes(item[0]), to_bytes(item[1])) for item in attr])
            elif isinstance(attr, tuple):
                setattr(self, param, dict((to_bytes(k), to_bytes(v)) for (k, v) in attr.items()))
            elif isinstance(attr, dict):
                setattr(self, param, dict((to_bytes(k), to_bytes(v)) for (k, v) in attr.items()))
            elif isinstance(attr, str):
                setattr(self, param, to_bytes(attr))
    def _validate_privatekey(self):