|
|
@ -19,9 +19,9 @@ short_description: Generate OpenSSL private keys
|
|
|
|
description:
|
|
|
|
description:
|
|
|
|
- This module allows one to (re)generate OpenSSL private keys.
|
|
|
|
- This module allows one to (re)generate OpenSSL private keys.
|
|
|
|
- One can generate L(RSA,https://en.wikipedia.org/wiki/RSA_(cryptosystem)),
|
|
|
|
- One can generate L(RSA,https://en.wikipedia.org/wiki/RSA_(cryptosystem)),
|
|
|
|
L(DSA,https://en.wikipedia.org/wiki/Digital_Signature_Algorithm) or
|
|
|
|
L(DSA,https://en.wikipedia.org/wiki/Digital_Signature_Algorithm),
|
|
|
|
L(ECC,https://en.wikipedia.org/wiki/Elliptic-curve_cryptography)
|
|
|
|
L(ECC,https://en.wikipedia.org/wiki/Elliptic-curve_cryptography) or
|
|
|
|
private keys.
|
|
|
|
L(EdDSA,https://en.wikipedia.org/wiki/EdDSA) private keys.
|
|
|
|
- Keys are generated in PEM format.
|
|
|
|
- Keys are generated in PEM format.
|
|
|
|
- "Please note that the module regenerates private keys if they don't match
|
|
|
|
- "Please note that the module regenerates private keys if they don't match
|
|
|
|
the module's options. In particular, if you provide another passphrase
|
|
|
|
the module's options. In particular, if you provide another passphrase
|
|
|
@ -52,12 +52,13 @@ options:
|
|
|
|
type:
|
|
|
|
type:
|
|
|
|
description:
|
|
|
|
description:
|
|
|
|
- The algorithm used to generate the TLS/SSL private key.
|
|
|
|
- The algorithm used to generate the TLS/SSL private key.
|
|
|
|
- Note that C(ECC) requires the C(cryptography) backend.
|
|
|
|
- Note that C(ECC), C(X25519), C(X448), C(Ed25519) and C(Ed448) require the C(cryptography) backend.
|
|
|
|
- Depending on the curve, you need a newer version of the cryptography backend.
|
|
|
|
C(X25519) needs cryptography 2.5 or newer, while C(X448), C(Ed25519) and C(Ed448) require
|
|
|
|
|
|
|
|
cryptography 2.6 or newer. For C(ECC), the minimal cryptography version required depends on the
|
|
|
|
|
|
|
|
I(curve) option.
|
|
|
|
type: str
|
|
|
|
type: str
|
|
|
|
default: RSA
|
|
|
|
default: RSA
|
|
|
|
#choices: [ DSA, ECC, RSA, X448, X25519, Ed448, Ed25519 ]
|
|
|
|
choices: [ DSA, ECC, Ed25519, Ed448, RSA, X25519, X448 ]
|
|
|
|
choices: [ DSA, ECC, RSA ]
|
|
|
|
|
|
|
|
curve:
|
|
|
|
curve:
|
|
|
|
description:
|
|
|
|
description:
|
|
|
|
- Note that not all curves are supported by all versions of C(cryptography).
|
|
|
|
- Note that not all curves are supported by all versions of C(cryptography).
|
|
|
@ -239,8 +240,14 @@ else:
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
import cryptography.hazmat.primitives.asymmetric.x25519
|
|
|
|
import cryptography.hazmat.primitives.asymmetric.x25519
|
|
|
|
CRYPTOGRAPHY_HAS_X25519 = True
|
|
|
|
CRYPTOGRAPHY_HAS_X25519 = True
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.private_bytes
|
|
|
|
|
|
|
|
CRYPTOGRAPHY_HAS_X25519_FULL = True
|
|
|
|
|
|
|
|
except AttributeError:
|
|
|
|
|
|
|
|
CRYPTOGRAPHY_HAS_X25519_FULL = False
|
|
|
|
except ImportError:
|
|
|
|
except ImportError:
|
|
|
|
CRYPTOGRAPHY_HAS_X25519 = False
|
|
|
|
CRYPTOGRAPHY_HAS_X25519 = False
|
|
|
|
|
|
|
|
CRYPTOGRAPHY_HAS_X25519_FULL = False
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
import cryptography.hazmat.primitives.asymmetric.x448
|
|
|
|
import cryptography.hazmat.primitives.asymmetric.x448
|
|
|
|
CRYPTOGRAPHY_HAS_X448 = True
|
|
|
|
CRYPTOGRAPHY_HAS_X448 = True
|
|
|
@ -467,6 +474,8 @@ class PrivateKeyCryptography(PrivateKeyBase):
|
|
|
|
self.curve = module.params['curve']
|
|
|
|
self.curve = module.params['curve']
|
|
|
|
if not CRYPTOGRAPHY_HAS_X25519 and self.type == 'X25519':
|
|
|
|
if not CRYPTOGRAPHY_HAS_X25519 and self.type == 'X25519':
|
|
|
|
self.module.fail_json(msg='Your cryptography version does not support X25519')
|
|
|
|
self.module.fail_json(msg='Your cryptography version does not support X25519')
|
|
|
|
|
|
|
|
if not CRYPTOGRAPHY_HAS_X25519_FULL and self.type == 'X25519':
|
|
|
|
|
|
|
|
self.module.fail_json(msg='Your cryptography version does not support X25519 serialization')
|
|
|
|
if not CRYPTOGRAPHY_HAS_X448 and self.type == 'X448':
|
|
|
|
if not CRYPTOGRAPHY_HAS_X448 and self.type == 'X448':
|
|
|
|
self.module.fail_json(msg='Your cryptography version does not support X448')
|
|
|
|
self.module.fail_json(msg='Your cryptography version does not support X448')
|
|
|
|
if not CRYPTOGRAPHY_HAS_ED25519 and self.type == 'Ed25519':
|
|
|
|
if not CRYPTOGRAPHY_HAS_ED25519 and self.type == 'Ed25519':
|
|
|
@ -475,6 +484,7 @@ class PrivateKeyCryptography(PrivateKeyBase):
|
|
|
|
self.module.fail_json(msg='Your cryptography version does not support Ed448')
|
|
|
|
self.module.fail_json(msg='Your cryptography version does not support Ed448')
|
|
|
|
|
|
|
|
|
|
|
|
def _generate_private_key_data(self):
|
|
|
|
def _generate_private_key_data(self):
|
|
|
|
|
|
|
|
format = cryptography.hazmat.primitives.serialization.PrivateFormat.TraditionalOpenSSL
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
if self.type == 'RSA':
|
|
|
|
if self.type == 'RSA':
|
|
|
|
self.privatekey = cryptography.hazmat.primitives.asymmetric.rsa.generate_private_key(
|
|
|
|
self.privatekey = cryptography.hazmat.primitives.asymmetric.rsa.generate_private_key(
|
|
|
@ -487,14 +497,18 @@ class PrivateKeyCryptography(PrivateKeyBase):
|
|
|
|
key_size=self.size,
|
|
|
|
key_size=self.size,
|
|
|
|
backend=self.cryptography_backend
|
|
|
|
backend=self.cryptography_backend
|
|
|
|
)
|
|
|
|
)
|
|
|
|
if CRYPTOGRAPHY_HAS_X25519 and self.type == 'X25519':
|
|
|
|
if CRYPTOGRAPHY_HAS_X25519_FULL and self.type == 'X25519':
|
|
|
|
self.privatekey = cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.generate()
|
|
|
|
self.privatekey = cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.generate()
|
|
|
|
|
|
|
|
format = cryptography.hazmat.primitives.serialization.PrivateFormat.PKCS8
|
|
|
|
if CRYPTOGRAPHY_HAS_X448 and self.type == 'X448':
|
|
|
|
if CRYPTOGRAPHY_HAS_X448 and self.type == 'X448':
|
|
|
|
self.privatekey = cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey.generate()
|
|
|
|
self.privatekey = cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey.generate()
|
|
|
|
|
|
|
|
format = cryptography.hazmat.primitives.serialization.PrivateFormat.PKCS8
|
|
|
|
if CRYPTOGRAPHY_HAS_ED25519 and self.type == 'Ed25519':
|
|
|
|
if CRYPTOGRAPHY_HAS_ED25519 and self.type == 'Ed25519':
|
|
|
|
self.privatekey = cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.generate()
|
|
|
|
self.privatekey = cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.generate()
|
|
|
|
|
|
|
|
format = cryptography.hazmat.primitives.serialization.PrivateFormat.PKCS8
|
|
|
|
if CRYPTOGRAPHY_HAS_ED448 and self.type == 'Ed448':
|
|
|
|
if CRYPTOGRAPHY_HAS_ED448 and self.type == 'Ed448':
|
|
|
|
self.privatekey = cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey.generate()
|
|
|
|
self.privatekey = cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey.generate()
|
|
|
|
|
|
|
|
format = cryptography.hazmat.primitives.serialization.PrivateFormat.PKCS8
|
|
|
|
if self.type == 'ECC' and self.curve in self.curves:
|
|
|
|
if self.type == 'ECC' and self.curve in self.curves:
|
|
|
|
if self.curves[self.curve]['deprecated']:
|
|
|
|
if self.curves[self.curve]['deprecated']:
|
|
|
|
self.module.warn('Elliptic curves of type {0} should not be used for new keys!'.format(self.curve))
|
|
|
|
self.module.warn('Elliptic curves of type {0} should not be used for new keys!'.format(self.curve))
|
|
|
@ -516,7 +530,7 @@ class PrivateKeyCryptography(PrivateKeyBase):
|
|
|
|
# Serialize key
|
|
|
|
# Serialize key
|
|
|
|
return self.privatekey.private_bytes(
|
|
|
|
return self.privatekey.private_bytes(
|
|
|
|
encoding=cryptography.hazmat.primitives.serialization.Encoding.PEM,
|
|
|
|
encoding=cryptography.hazmat.primitives.serialization.Encoding.PEM,
|
|
|
|
format=cryptography.hazmat.primitives.serialization.PrivateFormat.TraditionalOpenSSL,
|
|
|
|
format=format,
|
|
|
|
encryption_algorithm=encryption_algorithm
|
|
|
|
encryption_algorithm=encryption_algorithm
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
@ -565,6 +579,10 @@ class PrivateKeyCryptography(PrivateKeyBase):
|
|
|
|
return self.type == 'X25519'
|
|
|
|
return self.type == 'X25519'
|
|
|
|
if CRYPTOGRAPHY_HAS_X448 and isinstance(privatekey, cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey):
|
|
|
|
if CRYPTOGRAPHY_HAS_X448 and isinstance(privatekey, cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey):
|
|
|
|
return self.type == 'X448'
|
|
|
|
return self.type == 'X448'
|
|
|
|
|
|
|
|
if CRYPTOGRAPHY_HAS_ED25519 and isinstance(privatekey, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey):
|
|
|
|
|
|
|
|
return self.type == 'Ed25519'
|
|
|
|
|
|
|
|
if CRYPTOGRAPHY_HAS_ED448 and isinstance(privatekey, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey):
|
|
|
|
|
|
|
|
return self.type == 'Ed448'
|
|
|
|
if isinstance(privatekey, cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey):
|
|
|
|
if isinstance(privatekey, cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey):
|
|
|
|
if self.type != 'ECC':
|
|
|
|
if self.type != 'ECC':
|
|
|
|
return False
|
|
|
|
return False
|
|
|
@ -590,10 +608,7 @@ def main():
|
|
|
|
state=dict(type='str', default='present', choices=['present', 'absent']),
|
|
|
|
state=dict(type='str', default='present', choices=['present', 'absent']),
|
|
|
|
size=dict(type='int', default=4096),
|
|
|
|
size=dict(type='int', default=4096),
|
|
|
|
type=dict(type='str', default='RSA', choices=[
|
|
|
|
type=dict(type='str', default='RSA', choices=[
|
|
|
|
'RSA', 'DSA', 'ECC',
|
|
|
|
'DSA', 'ECC', 'Ed25519', 'Ed448', 'RSA', 'X25519', 'X448'
|
|
|
|
# FIXME: NO LONGER TRUE: x25519 is missing serialization functions: https://github.com/pyca/cryptography/issues/4386
|
|
|
|
|
|
|
|
# FIXME: NO LONGER TRUE: x448 is also missing it: https://github.com/pyca/cryptography/pull/4580#issuecomment-437913340
|
|
|
|
|
|
|
|
# 'X448', 'X25519', 'Ed448', 'Ed25519'
|
|
|
|
|
|
|
|
]),
|
|
|
|
]),
|
|
|
|
curve=dict(type='str', choices=[
|
|
|
|
curve=dict(type='str', choices=[
|
|
|
|
'secp384r1', 'secp521r1', 'secp224r1', 'secp192r1', 'secp256k1',
|
|
|
|
'secp384r1', 'secp521r1', 'secp224r1', 'secp192r1', 'secp256k1',
|
|
|
|