x509_certificate: check existing certificate's signature for selfsigned and ownca provider (#407)
* Verify whether signature matches. * Add changelog fragment. * Forgot imports. * Fix wrong name. * Check whether the CA private key fits to the CA certificate. Use correct key in tests. * Refactor code.pull/408/head
parent
3ebc132c03
commit
28729657ac
|
@ -0,0 +1,4 @@
|
||||||
|
bugfixes:
|
||||||
|
- "x509_certificate - for the ``ownca`` provider, check whether the CA private key actually belongs to the CA certificate (https://github.com/ansible-collections/community.crypto/pull/407)."
|
||||||
|
- "x509_certificate - regenerate certificate when the CA's public key changes for ``provider=ownca`` (https://github.com/ansible-collections/community.crypto/pull/407)."
|
||||||
|
- "x509_certificate - regenerate certificate when the private key changes for ``provider=selfsigned`` (https://github.com/ansible-collections/community.crypto/pull/407)."
|
|
@ -32,13 +32,36 @@ from ansible_collections.community.crypto.plugins.module_utils.version import Lo
|
||||||
try:
|
try:
|
||||||
import cryptography
|
import cryptography
|
||||||
from cryptography import x509
|
from cryptography import x509
|
||||||
|
from cryptography.exceptions import InvalidSignature
|
||||||
from cryptography.hazmat.backends import default_backend
|
from cryptography.hazmat.backends import default_backend
|
||||||
from cryptography.hazmat.primitives import serialization
|
from cryptography.hazmat.primitives import serialization
|
||||||
|
from cryptography.hazmat.primitives.asymmetric import padding
|
||||||
import ipaddress
|
import ipaddress
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# Error handled in the calling module.
|
# Error handled in the calling module.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
import cryptography.hazmat.primitives.asymmetric.rsa
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
import cryptography.hazmat.primitives.asymmetric.ec
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
import cryptography.hazmat.primitives.asymmetric.dsa
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
import cryptography.hazmat.primitives.asymmetric.ed25519
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
import cryptography.hazmat.primitives.asymmetric.ed448
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# This is a separate try/except since this is only present in cryptography 2.5 or newer
|
# This is a separate try/except since this is only present in cryptography 2.5 or newer
|
||||||
from cryptography.hazmat.primitives.serialization.pkcs12 import (
|
from cryptography.hazmat.primitives.serialization.pkcs12 import (
|
||||||
|
@ -58,8 +81,13 @@ except ImportError:
|
||||||
_load_pkcs12 = None
|
_load_pkcs12 = None
|
||||||
|
|
||||||
from .basic import (
|
from .basic import (
|
||||||
|
CRYPTOGRAPHY_HAS_DSA_SIGN,
|
||||||
|
CRYPTOGRAPHY_HAS_EC_SIGN,
|
||||||
CRYPTOGRAPHY_HAS_ED25519,
|
CRYPTOGRAPHY_HAS_ED25519,
|
||||||
|
CRYPTOGRAPHY_HAS_ED25519_SIGN,
|
||||||
CRYPTOGRAPHY_HAS_ED448,
|
CRYPTOGRAPHY_HAS_ED448,
|
||||||
|
CRYPTOGRAPHY_HAS_ED448_SIGN,
|
||||||
|
CRYPTOGRAPHY_HAS_RSA_SIGN,
|
||||||
CRYPTOGRAPHY_HAS_X25519,
|
CRYPTOGRAPHY_HAS_X25519,
|
||||||
CRYPTOGRAPHY_HAS_X25519_FULL,
|
CRYPTOGRAPHY_HAS_X25519_FULL,
|
||||||
CRYPTOGRAPHY_HAS_X448,
|
CRYPTOGRAPHY_HAS_X448,
|
||||||
|
@ -664,3 +692,40 @@ def _parse_pkcs12_legacy(pkcs12_bytes, passphrase=None):
|
||||||
if maybe_name != backend._ffi.NULL:
|
if maybe_name != backend._ffi.NULL:
|
||||||
friendly_name = backend._ffi.string(maybe_name)
|
friendly_name = backend._ffi.string(maybe_name)
|
||||||
return private_key, certificate, additional_certificates, friendly_name
|
return private_key, certificate, additional_certificates, friendly_name
|
||||||
|
|
||||||
|
|
||||||
|
def cryptography_verify_signature(signature, data, hash_algorithm, signer_public_key):
|
||||||
|
'''
|
||||||
|
Check whether the given signature of the given data was signed by the given public key object.
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
if CRYPTOGRAPHY_HAS_RSA_SIGN and isinstance(signer_public_key, cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey):
|
||||||
|
signer_public_key.verify(signature, data, padding.PKCS1v15(), hash_algorithm)
|
||||||
|
return True
|
||||||
|
if CRYPTOGRAPHY_HAS_EC_SIGN and isinstance(signer_public_key, cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey):
|
||||||
|
signer_public_key.verify(signature, data, cryptography.hazmat.primitives.asymmetric.ec.ECDSA(hash_algorithm))
|
||||||
|
return True
|
||||||
|
if CRYPTOGRAPHY_HAS_DSA_SIGN and isinstance(signer_public_key, cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey):
|
||||||
|
signer_public_key.verify(signature, data, hash_algorithm)
|
||||||
|
return True
|
||||||
|
if CRYPTOGRAPHY_HAS_ED25519_SIGN and isinstance(signer_public_key, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey):
|
||||||
|
signer_public_key.verify(signature, data)
|
||||||
|
return True
|
||||||
|
if CRYPTOGRAPHY_HAS_ED448_SIGN and isinstance(signer_public_key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey):
|
||||||
|
signer_public_key.verify(signature, data)
|
||||||
|
return True
|
||||||
|
raise OpenSSLObjectError(u'Unsupported public key type {0}'.format(type(signer_public_key)))
|
||||||
|
except InvalidSignature:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def cryptography_verify_certificate_signature(certificate, signer_public_key):
|
||||||
|
'''
|
||||||
|
Check whether the given X509 certificate object was signed by the given public key object.
|
||||||
|
'''
|
||||||
|
return cryptography_verify_signature(
|
||||||
|
certificate.signature,
|
||||||
|
certificate.tbs_certificate_bytes,
|
||||||
|
certificate.signature_hash_algorithm,
|
||||||
|
signer_public_key
|
||||||
|
)
|
||||||
|
|
|
@ -28,8 +28,10 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.support im
|
||||||
)
|
)
|
||||||
|
|
||||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
||||||
|
cryptography_compare_public_keys,
|
||||||
cryptography_key_needs_digest_for_signing,
|
cryptography_key_needs_digest_for_signing,
|
||||||
cryptography_serial_number_of_cert,
|
cryptography_serial_number_of_cert,
|
||||||
|
cryptography_verify_certificate_signature,
|
||||||
)
|
)
|
||||||
|
|
||||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.certificate import (
|
from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.certificate import (
|
||||||
|
@ -107,6 +109,9 @@ class OwnCACertificateBackendCryptography(CertificateBackend):
|
||||||
except OpenSSLBadPassphraseError as exc:
|
except OpenSSLBadPassphraseError as exc:
|
||||||
module.fail_json(msg=str(exc))
|
module.fail_json(msg=str(exc))
|
||||||
|
|
||||||
|
if not cryptography_compare_public_keys(self.ca_cert.public_key(), self.ca_private_key.public_key()):
|
||||||
|
raise CertificateError('The CA private key does not belong to the CA certificate')
|
||||||
|
|
||||||
if cryptography_key_needs_digest_for_signing(self.ca_private_key):
|
if cryptography_key_needs_digest_for_signing(self.ca_private_key):
|
||||||
if self.digest is None:
|
if self.digest is None:
|
||||||
raise CertificateError(
|
raise CertificateError(
|
||||||
|
@ -175,6 +180,10 @@ class OwnCACertificateBackendCryptography(CertificateBackend):
|
||||||
|
|
||||||
self._ensure_existing_certificate_loaded()
|
self._ensure_existing_certificate_loaded()
|
||||||
|
|
||||||
|
# Check whether certificate is signed by CA certificate
|
||||||
|
if not cryptography_verify_certificate_signature(self.existing_certificate, self.ca_cert.public_key()):
|
||||||
|
return True
|
||||||
|
|
||||||
# Check subject
|
# Check subject
|
||||||
if self.ca_cert.subject != self.existing_certificate.issuer:
|
if self.ca_cert.subject != self.existing_certificate.issuer:
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -22,6 +22,7 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.support im
|
||||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
||||||
cryptography_key_needs_digest_for_signing,
|
cryptography_key_needs_digest_for_signing,
|
||||||
cryptography_serial_number_of_cert,
|
cryptography_serial_number_of_cert,
|
||||||
|
cryptography_verify_certificate_signature,
|
||||||
)
|
)
|
||||||
|
|
||||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.certificate import (
|
from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.certificate import (
|
||||||
|
@ -135,8 +136,16 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend):
|
||||||
return self.cert.public_bytes(Encoding.PEM)
|
return self.cert.public_bytes(Encoding.PEM)
|
||||||
|
|
||||||
def needs_regeneration(self):
|
def needs_regeneration(self):
|
||||||
return super(SelfSignedCertificateBackendCryptography, self).needs_regeneration(
|
if super(SelfSignedCertificateBackendCryptography, self).needs_regeneration(not_before=self.notBefore, not_after=self.notAfter):
|
||||||
not_before=self.notBefore, not_after=self.notAfter)
|
return True
|
||||||
|
|
||||||
|
self._ensure_existing_certificate_loaded()
|
||||||
|
|
||||||
|
# Check whether certificate is signed by private key
|
||||||
|
if not cryptography_verify_certificate_signature(self.existing_certificate, self.privatekey.public_key()):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def dump(self, include_certificate):
|
def dump(self, include_certificate):
|
||||||
result = super(SelfSignedCertificateBackendCryptography, self).dump(include_certificate)
|
result = super(SelfSignedCertificateBackendCryptography, self).dump(include_certificate)
|
||||||
|
|
|
@ -344,7 +344,7 @@
|
||||||
path: '{{ remote_tmp_dir }}/ownca_cert_backup.pem'
|
path: '{{ remote_tmp_dir }}/ownca_cert_backup.pem'
|
||||||
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
||||||
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
||||||
ownca_privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
ownca_privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey.pem'
|
||||||
provider: ownca
|
provider: ownca
|
||||||
ownca_digest: sha256
|
ownca_digest: sha256
|
||||||
backup: yes
|
backup: yes
|
||||||
|
@ -355,7 +355,7 @@
|
||||||
path: '{{ remote_tmp_dir }}/ownca_cert_backup.pem'
|
path: '{{ remote_tmp_dir }}/ownca_cert_backup.pem'
|
||||||
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
||||||
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
||||||
ownca_privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
ownca_privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey.pem'
|
||||||
provider: ownca
|
provider: ownca
|
||||||
ownca_digest: sha256
|
ownca_digest: sha256
|
||||||
backup: yes
|
backup: yes
|
||||||
|
@ -366,7 +366,7 @@
|
||||||
path: '{{ remote_tmp_dir }}/ownca_cert_backup.pem'
|
path: '{{ remote_tmp_dir }}/ownca_cert_backup.pem'
|
||||||
csr_path: '{{ remote_tmp_dir }}/csr.csr'
|
csr_path: '{{ remote_tmp_dir }}/csr.csr'
|
||||||
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
||||||
ownca_privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
ownca_privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey.pem'
|
||||||
provider: ownca
|
provider: ownca
|
||||||
ownca_digest: sha256
|
ownca_digest: sha256
|
||||||
backup: yes
|
backup: yes
|
||||||
|
@ -394,7 +394,7 @@
|
||||||
path: '{{ remote_tmp_dir }}/ownca_cert_ski.pem'
|
path: '{{ remote_tmp_dir }}/ownca_cert_ski.pem'
|
||||||
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
||||||
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
||||||
ownca_privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
ownca_privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey.pem'
|
||||||
provider: ownca
|
provider: ownca
|
||||||
ownca_digest: sha256
|
ownca_digest: sha256
|
||||||
ownca_create_subject_key_identifier: always_create
|
ownca_create_subject_key_identifier: always_create
|
||||||
|
@ -406,7 +406,7 @@
|
||||||
path: '{{ remote_tmp_dir }}/ownca_cert_ski.pem'
|
path: '{{ remote_tmp_dir }}/ownca_cert_ski.pem'
|
||||||
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
||||||
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
||||||
ownca_privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
ownca_privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey.pem'
|
||||||
provider: ownca
|
provider: ownca
|
||||||
ownca_digest: sha256
|
ownca_digest: sha256
|
||||||
ownca_create_subject_key_identifier: always_create
|
ownca_create_subject_key_identifier: always_create
|
||||||
|
@ -418,7 +418,7 @@
|
||||||
path: '{{ remote_tmp_dir }}/ownca_cert_ski.pem'
|
path: '{{ remote_tmp_dir }}/ownca_cert_ski.pem'
|
||||||
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
||||||
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
||||||
ownca_privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
ownca_privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey.pem'
|
||||||
provider: ownca
|
provider: ownca
|
||||||
ownca_digest: sha256
|
ownca_digest: sha256
|
||||||
ownca_create_subject_key_identifier: never_create
|
ownca_create_subject_key_identifier: never_create
|
||||||
|
@ -430,7 +430,7 @@
|
||||||
path: '{{ remote_tmp_dir }}/ownca_cert_ski.pem'
|
path: '{{ remote_tmp_dir }}/ownca_cert_ski.pem'
|
||||||
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
||||||
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
||||||
ownca_privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
ownca_privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey.pem'
|
||||||
provider: ownca
|
provider: ownca
|
||||||
ownca_digest: sha256
|
ownca_digest: sha256
|
||||||
ownca_create_subject_key_identifier: never_create
|
ownca_create_subject_key_identifier: never_create
|
||||||
|
@ -442,7 +442,7 @@
|
||||||
path: '{{ remote_tmp_dir }}/ownca_cert_ski.pem'
|
path: '{{ remote_tmp_dir }}/ownca_cert_ski.pem'
|
||||||
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
||||||
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
||||||
ownca_privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
ownca_privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey.pem'
|
||||||
provider: ownca
|
provider: ownca
|
||||||
ownca_digest: sha256
|
ownca_digest: sha256
|
||||||
ownca_create_subject_key_identifier: always_create
|
ownca_create_subject_key_identifier: always_create
|
||||||
|
@ -454,7 +454,7 @@
|
||||||
path: '{{ remote_tmp_dir }}/ownca_cert_aki.pem'
|
path: '{{ remote_tmp_dir }}/ownca_cert_aki.pem'
|
||||||
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
||||||
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
||||||
ownca_privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
ownca_privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey.pem'
|
||||||
provider: ownca
|
provider: ownca
|
||||||
ownca_digest: sha256
|
ownca_digest: sha256
|
||||||
ownca_create_authority_key_identifier: yes
|
ownca_create_authority_key_identifier: yes
|
||||||
|
@ -466,7 +466,7 @@
|
||||||
path: '{{ remote_tmp_dir }}/ownca_cert_aki.pem'
|
path: '{{ remote_tmp_dir }}/ownca_cert_aki.pem'
|
||||||
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
||||||
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
||||||
ownca_privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
ownca_privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey.pem'
|
||||||
provider: ownca
|
provider: ownca
|
||||||
ownca_digest: sha256
|
ownca_digest: sha256
|
||||||
ownca_create_authority_key_identifier: yes
|
ownca_create_authority_key_identifier: yes
|
||||||
|
@ -478,7 +478,7 @@
|
||||||
path: '{{ remote_tmp_dir }}/ownca_cert_aki.pem'
|
path: '{{ remote_tmp_dir }}/ownca_cert_aki.pem'
|
||||||
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
||||||
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
||||||
ownca_privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
ownca_privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey.pem'
|
||||||
provider: ownca
|
provider: ownca
|
||||||
ownca_digest: sha256
|
ownca_digest: sha256
|
||||||
ownca_create_authority_key_identifier: no
|
ownca_create_authority_key_identifier: no
|
||||||
|
@ -490,7 +490,7 @@
|
||||||
path: '{{ remote_tmp_dir }}/ownca_cert_aki.pem'
|
path: '{{ remote_tmp_dir }}/ownca_cert_aki.pem'
|
||||||
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
||||||
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
||||||
ownca_privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
ownca_privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey.pem'
|
||||||
provider: ownca
|
provider: ownca
|
||||||
ownca_digest: sha256
|
ownca_digest: sha256
|
||||||
ownca_create_authority_key_identifier: no
|
ownca_create_authority_key_identifier: no
|
||||||
|
@ -502,7 +502,7 @@
|
||||||
path: '{{ remote_tmp_dir }}/ownca_cert_aki.pem'
|
path: '{{ remote_tmp_dir }}/ownca_cert_aki.pem'
|
||||||
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
csr_path: '{{ remote_tmp_dir }}/csr_ecc.csr'
|
||||||
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
ownca_path: '{{ remote_tmp_dir }}/ca_cert.pem'
|
||||||
ownca_privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
|
ownca_privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey.pem'
|
||||||
provider: ownca
|
provider: ownca
|
||||||
ownca_digest: sha256
|
ownca_digest: sha256
|
||||||
ownca_create_authority_key_identifier: yes
|
ownca_create_authority_key_identifier: yes
|
||||||
|
|
Loading…
Reference in New Issue