openssl_publickey: Allow one to specify the output format (#27031)

Public key can be extracted extracted in different format from
the PEM formatted RSA pair.

This commit allows the user to specify the format s/he wants to generate
the public key:

  * PEM
  * OpenSSH
pull/27007/merge
Yanis Guenane 7 years ago committed by Sam Doran
parent 1dc608f2cf
commit bc30dddb81

@ -47,6 +47,13 @@ options:
choices: [ True, False ] choices: [ True, False ]
description: description:
- Should the key be regenerated even it it already exists - Should the key be regenerated even it it already exists
format:
required: false
default: PEM
choices: [ PEM, OpenSSH ]
description:
- The format of the public key.
version_added: "2.4"
path: path:
required: true required: true
description: description:
@ -58,10 +65,16 @@ options:
''' '''
EXAMPLES = ''' EXAMPLES = '''
# Generate an OpenSSL public key. # Generate an OpenSSL public key in PEM format.
- openssl_publickey:
path: /etc/ssl/public/ansible.com.pem
privatekey_path: /etc/ssl/private/ansible.com.pem
# Generate an OpenSSL public key in OpenSSH v2 format.
- openssl_publickey: - openssl_publickey:
path: /etc/ssl/public/ansible.com.pem path: /etc/ssl/public/ansible.com.pem
privatekey_path: /etc/ssl/private/ansible.com.pem privatekey_path: /etc/ssl/private/ansible.com.pem
format: OpenSSH
# Force regenerate an OpenSSL public key if it already exists # Force regenerate an OpenSSL public key if it already exists
- openssl_publickey: - openssl_publickey:
@ -82,6 +95,11 @@ privatekey:
returned: changed or success returned: changed or success
type: string type: string
sample: /etc/ssl/private/ansible.com.pem sample: /etc/ssl/private/ansible.com.pem
format:
description: The format of the public key (PEM, OpenSSH, ...)
returned: changed or success
type: string
sample: PEM
filename: filename:
description: Path to the generated TLS/SSL public key file description: Path to the generated TLS/SSL public key file
returned: changed or success returned: changed or success
@ -108,6 +126,8 @@ from ansible.module_utils.pycompat24 import get_exception
try: try:
from OpenSSL import crypto from OpenSSL import crypto
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization as crypto_serialization
except ImportError: except ImportError:
pyopenssl_found = False pyopenssl_found = False
else: else:
@ -126,6 +146,7 @@ class PublicKey(object):
def __init__(self, module): def __init__(self, module):
self.state = module.params['state'] self.state = module.params['state']
self.force = module.params['force'] self.force = module.params['force']
self.format = module.params['format']
self.name = os.path.basename(module.params['path']) self.name = os.path.basename(module.params['path'])
self.path = module.params['path'] self.path = module.params['path']
self.privatekey_path = module.params['privatekey_path'] self.privatekey_path = module.params['privatekey_path']
@ -134,15 +155,25 @@ class PublicKey(object):
self.fingerprint = {} self.fingerprint = {}
self.check_mode = module.check_mode self.check_mode = module.check_mode
def generate(self, module): def generate(self, module):
"""Generate the public key.""" """Generate the public key."""
if not os.path.exists(self.path) or self.force: if not os.path.exists(self.path) or self.force:
try: try:
privatekey_content = open(self.privatekey_path, 'r').read() privatekey_content = open(self.privatekey_path, 'r').read()
self.privatekey = crypto.load_privatekey(crypto.FILETYPE_PEM, privatekey_content)
publickey_content = crypto.dump_publickey(crypto.FILETYPE_PEM, self.privatekey) if self.format == 'OpenSSH':
key = crypto_serialization.load_pem_private_key(privatekey_content,
password=None,
backend=default_backend())
publickey_content = key.public_key().public_bytes(
crypto_serialization.Encoding.OpenSSH,
crypto_serialization.PublicFormat.OpenSSH
)
else:
self.privatekey = crypto.load_privatekey(crypto.FILETYPE_PEM, privatekey_content)
publickey_content = crypto.dump_publickey(crypto.FILETYPE_PEM, self.privatekey)
publickey_file = open(self.path, 'w') publickey_file = open(self.path, 'w')
publickey_file.write(publickey_content) publickey_file.write(publickey_content)
publickey_file.close() publickey_file.close()
@ -180,6 +211,7 @@ class PublicKey(object):
result = { result = {
'privatekey': self.privatekey_path, 'privatekey': self.privatekey_path,
'filename': self.path, 'filename': self.path,
'format': self.format,
'changed': self.changed, 'changed': self.changed,
'fingerprint': self.fingerprint, 'fingerprint': self.fingerprint,
} }
@ -195,6 +227,7 @@ def main():
force=dict(default=False, type='bool'), force=dict(default=False, type='bool'),
path=dict(required=True, type='path'), path=dict(required=True, type='path'),
privatekey_path=dict(type='path'), privatekey_path=dict(type='path'),
format=dict(type='str', choices=['PEM', 'OpenSSH'], default='PEM'),
), ),
supports_check_mode = True, supports_check_mode = True,
add_file_common_args = True, add_file_common_args = True,

Loading…
Cancel
Save