Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

openssl_csr_info and x509_certificate_info: return more public key information #233

Merged
merged 6 commits into from
May 19, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelogs/fragments/233-public-key-info.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
minor_changes:
- "openssl_csr_info - now returns ``public_key_type`` and ``public_key_data`` (https:/ansible-collections/community.crypto/pull/233)."
- "x509_certificate_info - now returns ``public_key_type`` and ``public_key_data`` (https:/ansible-collections/community.crypto/pull/233)."
20 changes: 20 additions & 0 deletions plugins/module_utils/crypto/module_backends/certificate_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
pyopenssl_normalize_name_attribute,
)

from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.publickey_info import (
get_publickey_info,
)

MINIMAL_CRYPTOGRAPHY_VERSION = '1.6'
MINIMAL_PYOPENSSL_VERSION = '0.15'

Expand Down Expand Up @@ -137,6 +141,10 @@ def get_not_after(self):
def _get_public_key(self, binary):
pass

@abc.abstractmethod
def _get_public_key_object(self):
pass

@abc.abstractmethod
def _get_subject_key_identifier(self):
pass
Expand Down Expand Up @@ -189,6 +197,12 @@ def get_info(self):
pk = self._get_public_key(binary=True)
result['public_key_fingerprints'] = get_fingerprint_of_bytes(pk) if pk is not None else dict()

public_key_info = get_publickey_info(self.module, self.backend, key=self._get_public_key_object())
result.update({
'public_key_type': public_key_info['type'],
'public_key_data': public_key_info['public_data'],
})
felixfontein marked this conversation as resolved.
Show resolved Hide resolved

result['fingerprints'] = get_fingerprint_of_bytes(self._get_der_bytes())

if self.backend != 'pyopenssl':
Expand Down Expand Up @@ -336,6 +350,9 @@ def _get_public_key(self, binary):
serialization.PublicFormat.SubjectPublicKeyInfo
)

def _get_public_key_object(self):
return self.cert.public_key()

def _get_subject_key_identifier(self):
try:
ext = self.cert.extensions.get_extension_for_class(x509.SubjectKeyIdentifier)
Expand Down Expand Up @@ -471,6 +488,9 @@ def _get_public_key(self, binary):
self.module.warn('Your pyOpenSSL version does not support dumping public keys. '
'Please upgrade to version 16.0 or newer, or use the cryptography backend.')

def _get_public_key_object(self):
return self.cert.get_pubkey()

def _get_subject_key_identifier(self):
# Won't be implemented
return None
Expand Down
20 changes: 20 additions & 0 deletions plugins/module_utils/crypto/module_backends/csr_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
pyopenssl_parse_name_constraints,
)

from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.publickey_info import (
get_publickey_info,
)

MINIMAL_CRYPTOGRAPHY_VERSION = '1.3'
MINIMAL_PYOPENSSL_VERSION = '0.15'

Expand Down Expand Up @@ -116,6 +120,10 @@ def _get_name_constraints(self):
def _get_public_key(self, binary):
pass

@abc.abstractmethod
def _get_public_key_object(self):
pass

@abc.abstractmethod
def _get_subject_key_identifier(self):
pass
Expand Down Expand Up @@ -156,6 +164,12 @@ def get_info(self):
pk = self._get_public_key(binary=True)
result['public_key_fingerprints'] = get_fingerprint_of_bytes(pk) if pk is not None else dict()

public_key_info = get_publickey_info(self.module, self.backend, key=self._get_public_key_object())
result.update({
'public_key_type': public_key_info['type'],
'public_key_data': public_key_info['public_data'],
})
felixfontein marked this conversation as resolved.
Show resolved Hide resolved

if self.backend != 'pyopenssl':
ski = self._get_subject_key_identifier()
if ski is not None:
Expand Down Expand Up @@ -288,6 +302,9 @@ def _get_public_key(self, binary):
serialization.PublicFormat.SubjectPublicKeyInfo
)

def _get_public_key_object(self):
return self.csr.public_key()

def _get_subject_key_identifier(self):
try:
ext = self.csr.extensions.get_extension_for_class(x509.SubjectKeyIdentifier)
Expand Down Expand Up @@ -394,6 +411,9 @@ def _get_public_key(self, binary):
self.module.warn('Your pyOpenSSL version does not support dumping public keys. '
'Please upgrade to version 16.0 or newer, or use the cryptography backend.')

def _get_public_key_object(self):
return self.csr.get_pubkey()

def _get_subject_key_identifier(self):
# Won't be implemented
return None
Expand Down
71 changes: 71 additions & 0 deletions plugins/modules/openssl_csr_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,77 @@
returned: success
type: str
sample: "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A..."
public_key_type:
description:
- The CSR's public key's type.
- One of C(RSA), C(DSA), C(ECC), C(Ed25519), C(X25519), C(Ed448), or C(X448).
- Will start with C(unknown) if the key type cannot be determined.
returned: success
type: str
version_added: 1.7.0
sample: RSA
public_key_data:
description:
- Public key data. Depends on the public key's type.
returned: success
type: dict
version_added: 1.7.0
contains:
size:
description:
- Bit size of modulus (RSA) or prime number (DSA).
type: int
returned: When C(type=RSA) or C(type=DSA)
felixfontein marked this conversation as resolved.
Show resolved Hide resolved
modulus:
description:
- The RSA key's modulus.
type: int
returned: When C(type=RSA)
exponent:
description:
- The RSA key's public exponent.
type: int
returned: When C(type=RSA)
p:
description:
- The C(p) value for DSA.
- This is the prime modulus upon which arithmetic takes place.
type: int
returned: When C(type=DSA)
q:
description:
- The C(q) value for DSA.
- This is a prime that divides C(p - 1), and at the same time the order of the subgroup of the
multiplicative group of the prime field used.
type: int
returned: When C(type=DSA)
g:
description:
- The C(g) value for DSA.
- This is the element spanning the subgroup of the multiplicative group of the prime field used.
type: int
returned: When C(type=DSA)
curve:
description:
- The curve's name for ECC.
type: str
returned: When C(type=ECC)
exponent_size:
description:
- The maximum number of bits of a private key. This is basically the bit size of the subgroup used.
type: int
returned: When C(type=ECC)
x:
description:
- The C(x) coordinate for the public point on the elliptic curve.
type: int
returned: When C(type=ECC)
y:
description:
- For C(type=ECC), this is the C(y) coordinate for the public point on the elliptic curve.
- For C(type=DSA), this is the publicly known group element whose discrete logarithm w.r.t. C(g) is the private key.
type: int
returned: When C(type=DSA) or C(type=ECC)
public_key_fingerprints:
description:
- Fingerprints of CSR's public key.
Expand Down
71 changes: 71 additions & 0 deletions plugins/modules/x509_certificate_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,77 @@
returned: success
type: str
sample: "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A..."
public_key_type:
description:
- The certificate's public key's type.
- One of C(RSA), C(DSA), C(ECC), C(Ed25519), C(X25519), C(Ed448), or C(X448).
- Will start with C(unknown) if the key type cannot be determined.
returned: success
type: str
version_added: 1.7.0
sample: RSA
public_key_data:
description:
- Public key data. Depends on the public key's type.
returned: success
type: dict
version_added: 1.7.0
contains:
size:
description:
- Bit size of modulus (RSA) or prime number (DSA).
type: int
returned: When C(type=RSA) or C(type=DSA)
modulus:
description:
- The RSA key's modulus.
type: int
returned: When C(type=RSA)
exponent:
description:
- The RSA key's public exponent.
type: int
returned: When C(type=RSA)
p:
description:
- The C(p) value for DSA.
- This is the prime modulus upon which arithmetic takes place.
type: int
returned: When C(type=DSA)
q:
description:
- The C(q) value for DSA.
- This is a prime that divides C(p - 1), and at the same time the order of the subgroup of the
multiplicative group of the prime field used.
type: int
returned: When C(type=DSA)
g:
description:
- The C(g) value for DSA.
- This is the element spanning the subgroup of the multiplicative group of the prime field used.
type: int
returned: When C(type=DSA)
curve:
description:
- The curve's name for ECC.
type: str
returned: When C(type=ECC)
exponent_size:
description:
- The maximum number of bits of a private key. This is basically the bit size of the subgroup used.
type: int
returned: When C(type=ECC)
x:
description:
- The C(x) coordinate for the public point on the elliptic curve.
type: int
returned: When C(type=ECC)
y:
description:
- For C(type=ECC), this is the C(y) coordinate for the public point on the elliptic curve.
- For C(type=DSA), this is the publicly known group element whose discrete logarithm w.r.t. C(g) is the private key.
type: int
returned: When C(type=DSA) or C(type=ECC)
public_key_fingerprints:
description:
- Fingerprints of certificate's public key.
Expand Down
2 changes: 2 additions & 0 deletions tests/integration/targets/openssl_csr_info/tasks/impl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
- result.subject.organizationalUnitName == 'ACME Department'
- "['organizationalUnitName', 'Crypto Department'] in result.subject_ordered"
- "['organizationalUnitName', 'ACME Department'] in result.subject_ordered"
- result.public_key_type == 'RSA'
- result.public_key_data.size == default_rsa_key_size

- name: "({{ select_crypto_backend }}) Check SubjectKeyIdentifier and AuthorityKeyIdentifier"
assert:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
- result.subject.organizationalUnitName == 'ACME Department'
- "['organizationalUnitName', 'Crypto Department'] in result.subject_ordered"
- "['organizationalUnitName', 'ACME Department'] in result.subject_ordered"
- result.public_key_type == 'RSA'
- result.public_key_data.size == (default_rsa_key_size_certifiates | int)

- name: Check SubjectKeyIdentifier and AuthorityKeyIdentifier
assert:
Expand Down