mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Allow custom validity dates over new X509 certificates (#53149)
* Ported unit test for fix to new Salt master branch. * Ported fixes to allow not_before and not_after to master branch. * Removed CSR tests as they are not available in master. * Fixed test to ensure a string is passed to the write method. * Lint fixes. * Changed salt version. * Removed unused variable detected by lint * Code formatting changes. * Added integration tests for x509 state covering new functionality. * Removed deprecated options from documentation.
This commit is contained in:
parent
7c37be44eb
commit
ff4fd1eb3a
7 changed files with 612 additions and 187 deletions
|
@ -1378,6 +1378,18 @@ def create_certificate(path=None, text=False, overwrite=True, ca_server=None, **
|
|||
|
||||
The above signing policy can be invoked with ``signing_policy=www``
|
||||
|
||||
not_before:
|
||||
Initial validity date for the certificate. This date must be specified
|
||||
in the format '%Y-%m-%d %H:%M:%S'.
|
||||
|
||||
.. versionadded:: Sodium
|
||||
|
||||
not_after:
|
||||
Final validity date for the certificate. This date must be specified in
|
||||
the format '%Y-%m-%d %H:%M:%S'.
|
||||
|
||||
.. versionadded:: Sodium
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
@ -1493,12 +1505,58 @@ def create_certificate(path=None, text=False, overwrite=True, ca_server=None, **
|
|||
serial_number -= int(serial_number / sys.maxsize) * sys.maxsize
|
||||
cert.set_serial_number(serial_number)
|
||||
|
||||
# Handle not_before and not_after dates for custom certificate validity
|
||||
fmt = "%Y-%m-%d %H:%M:%S"
|
||||
if "not_before" in kwargs:
|
||||
try:
|
||||
time = datetime.datetime.strptime(kwargs["not_before"], fmt)
|
||||
except:
|
||||
raise salt.exceptions.SaltInvocationError(
|
||||
"not_before: {0} is not in required format {1}".format(
|
||||
kwargs["not_before"], fmt
|
||||
)
|
||||
)
|
||||
|
||||
# If we do not set an explicit timezone to this naive datetime object,
|
||||
# the M2Crypto code will assume it is from the local machine timezone
|
||||
# and will try to adjust the time shift.
|
||||
time = time.replace(tzinfo=M2Crypto.ASN1.UTC)
|
||||
asn1_not_before = M2Crypto.ASN1.ASN1_UTCTIME()
|
||||
asn1_not_before.set_datetime(time)
|
||||
cert.set_not_before(asn1_not_before)
|
||||
|
||||
if "not_after" in kwargs:
|
||||
try:
|
||||
time = datetime.datetime.strptime(kwargs["not_after"], fmt)
|
||||
except:
|
||||
raise salt.exceptions.SaltInvocationError(
|
||||
"not_after: {0} is not in required format {1}".format(
|
||||
kwargs["not_after"], fmt
|
||||
)
|
||||
)
|
||||
|
||||
# Forcing the datetime to have an explicit tzinfo here as well.
|
||||
time = time.replace(tzinfo=M2Crypto.ASN1.UTC)
|
||||
asn1_not_after = M2Crypto.ASN1.ASN1_UTCTIME()
|
||||
asn1_not_after.set_datetime(time)
|
||||
cert.set_not_after(asn1_not_after)
|
||||
|
||||
# Set validity dates
|
||||
# pylint: disable=no-member
|
||||
|
||||
# if no 'not_before' or 'not_after' dates are setup, both of the following
|
||||
# dates will be the date of today. then the days_valid offset makes sense.
|
||||
|
||||
not_before = M2Crypto.m2.x509_get_not_before(cert.x509)
|
||||
not_after = M2Crypto.m2.x509_get_not_after(cert.x509)
|
||||
M2Crypto.m2.x509_gmtime_adj(not_before, 0)
|
||||
M2Crypto.m2.x509_gmtime_adj(not_after, 60 * 60 * 24 * kwargs["days_valid"])
|
||||
|
||||
# Only process the dynamic dates if start and end are not specified.
|
||||
if "not_before" not in kwargs:
|
||||
M2Crypto.m2.x509_gmtime_adj(not_before, 0)
|
||||
if "not_after" not in kwargs:
|
||||
valid_seconds = 60 * 60 * 24 * kwargs["days_valid"] # 60s * 60m * 24 * days
|
||||
M2Crypto.m2.x509_gmtime_adj(not_after, valid_seconds)
|
||||
|
||||
# pylint: enable=no-member
|
||||
|
||||
# If neither public_key or csr are included, this cert is self-signed
|
||||
|
|
|
@ -150,6 +150,25 @@ This state creates a private key then requests a certificate signed by ca accord
|
|||
- CN: www.example.com
|
||||
- days_remaining: 30
|
||||
- backup: True
|
||||
|
||||
This other state creates a private key then requests a certificate signed by ca
|
||||
according to the www policy but adds a strict date range for the certificate to
|
||||
be considered valid.
|
||||
|
||||
/srv/salt/www-time-limited.sls
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
/etc/pki/www-time-limited.crt:
|
||||
x509.certificate_managed:
|
||||
- ca_server: ca
|
||||
- signing_policy: www
|
||||
- public_key: /etc/pki/www-time-limited.key
|
||||
- CN: www.example.com
|
||||
- not_before: 2019-05-05 00:00:00
|
||||
- not_after: 2020-05-05 14:30:00
|
||||
- backup: True
|
||||
|
||||
"""
|
||||
|
||||
# Import Python Libs
|
||||
|
@ -530,6 +549,17 @@ def certificate_managed(
|
|||
<salt.modules.x509.create_certificate>` or :py:func:`file.managed
|
||||
<salt.states.file.managed>` are supported.
|
||||
|
||||
not_before:
|
||||
Initial validity date for the certificate. This date must be specified
|
||||
in the format '%Y-%m-%d %H:%M:%S'.
|
||||
|
||||
.. versionadded:: Sodium
|
||||
not_after:
|
||||
Final validity date for the certificate. This date must be specified in
|
||||
the format '%Y-%m-%d %H:%M:%S'.
|
||||
|
||||
.. versionadded:: Sodium
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
|
66
tests/integration/files/file/base/test_cert_not_after.sls
Normal file
66
tests/integration/files/file/base/test_cert_not_after.sls
Normal file
|
@ -0,0 +1,66 @@
|
|||
{% set tmp_dir = pillar['tmp_dir'] %}
|
||||
|
||||
{{ tmp_dir }}/pki:
|
||||
file.directory
|
||||
|
||||
{{ tmp_dir }}/pki/issued_certs:
|
||||
file.directory
|
||||
|
||||
{{ tmp_dir }}/pki/ca.key:
|
||||
x509.private_key_managed:
|
||||
- bits: 4096
|
||||
- require:
|
||||
- file: {{ tmp_dir }}/pki
|
||||
|
||||
{{ tmp_dir }}/pki/ca.crt:
|
||||
x509.certificate_managed:
|
||||
- signing_private_key: {{ tmp_dir }}/pki/ca.key
|
||||
- CN: ca.example.com
|
||||
- C: US
|
||||
- ST: Utah
|
||||
- L: Salt Lake City
|
||||
- basicConstraints: "critical CA:true"
|
||||
- keyUsage: "critical cRLSign, keyCertSign"
|
||||
- subjectKeyIdentifier: hash
|
||||
- authorityKeyIdentifier: keyid,issuer:always
|
||||
- days_valid: 3650
|
||||
- days_remaining: 0
|
||||
- backup: True
|
||||
- managed_private_key:
|
||||
name: {{ tmp_dir }}/pki/ca.key
|
||||
bits: 4096
|
||||
backup: True
|
||||
- require:
|
||||
- file: {{ tmp_dir }}/pki
|
||||
- {{ tmp_dir }}/pki/ca.key
|
||||
|
||||
mine.send:
|
||||
module.run:
|
||||
- func: x509.get_pem_entries
|
||||
- kwargs:
|
||||
glob_path: {{ tmp_dir }}/pki/ca.crt
|
||||
- onchanges:
|
||||
- x509: {{ tmp_dir }}/pki/ca.crt
|
||||
|
||||
{{ tmp_dir }}/pki/test.key:
|
||||
x509.private_key_managed:
|
||||
- bits: 4096
|
||||
- backup: True
|
||||
|
||||
test_crt:
|
||||
x509.certificate_managed:
|
||||
- name: {{ tmp_dir }}/pki/test.crt
|
||||
- ca_server: minion
|
||||
- signing_policy: ca_policy
|
||||
- public_key: {{ tmp_dir }}/pki/test.key
|
||||
- CN: minion
|
||||
- days_remaining: 30
|
||||
- not_after: 2020-05-05 14:30:00
|
||||
- backup: True
|
||||
- managed_private_key:
|
||||
name: {{ tmp_dir }}/pki/test.key
|
||||
bits: 4096
|
||||
backup: True
|
||||
- require:
|
||||
- {{ tmp_dir }}/pki/ca.crt
|
||||
- {{ tmp_dir }}/pki/test.key
|
66
tests/integration/files/file/base/test_cert_not_before.sls
Normal file
66
tests/integration/files/file/base/test_cert_not_before.sls
Normal file
|
@ -0,0 +1,66 @@
|
|||
{% set tmp_dir = pillar['tmp_dir'] %}
|
||||
|
||||
{{ tmp_dir }}/pki:
|
||||
file.directory
|
||||
|
||||
{{ tmp_dir }}/pki/issued_certs:
|
||||
file.directory
|
||||
|
||||
{{ tmp_dir }}/pki/ca.key:
|
||||
x509.private_key_managed:
|
||||
- bits: 4096
|
||||
- require:
|
||||
- file: {{ tmp_dir }}/pki
|
||||
|
||||
{{ tmp_dir }}/pki/ca.crt:
|
||||
x509.certificate_managed:
|
||||
- signing_private_key: {{ tmp_dir }}/pki/ca.key
|
||||
- CN: ca.example.com
|
||||
- C: US
|
||||
- ST: Utah
|
||||
- L: Salt Lake City
|
||||
- basicConstraints: "critical CA:true"
|
||||
- keyUsage: "critical cRLSign, keyCertSign"
|
||||
- subjectKeyIdentifier: hash
|
||||
- authorityKeyIdentifier: keyid,issuer:always
|
||||
- days_valid: 3650
|
||||
- days_remaining: 0
|
||||
- backup: True
|
||||
- managed_private_key:
|
||||
name: {{ tmp_dir }}/pki/ca.key
|
||||
bits: 4096
|
||||
backup: True
|
||||
- require:
|
||||
- file: {{ tmp_dir }}/pki
|
||||
- {{ tmp_dir }}/pki/ca.key
|
||||
|
||||
mine.send:
|
||||
module.run:
|
||||
- func: x509.get_pem_entries
|
||||
- kwargs:
|
||||
glob_path: {{ tmp_dir }}/pki/ca.crt
|
||||
- onchanges:
|
||||
- x509: {{ tmp_dir }}/pki/ca.crt
|
||||
|
||||
{{ tmp_dir }}/pki/test.key:
|
||||
x509.private_key_managed:
|
||||
- bits: 4096
|
||||
- backup: True
|
||||
|
||||
test_crt:
|
||||
x509.certificate_managed:
|
||||
- name: {{ tmp_dir }}/pki/test.crt
|
||||
- ca_server: minion
|
||||
- signing_policy: ca_policy
|
||||
- public_key: {{ tmp_dir }}/pki/test.key
|
||||
- CN: minion
|
||||
- days_remaining: 30
|
||||
- not_before: 2019-05-05 00:00:00
|
||||
- backup: True
|
||||
- managed_private_key:
|
||||
name: {{ tmp_dir }}/pki/test.key
|
||||
bits: 4096
|
||||
backup: True
|
||||
- require:
|
||||
- {{ tmp_dir }}/pki/ca.crt
|
||||
- {{ tmp_dir }}/pki/test.key
|
|
@ -0,0 +1,67 @@
|
|||
{% set tmp_dir = pillar['tmp_dir'] %}
|
||||
|
||||
{{ tmp_dir }}/pki:
|
||||
file.directory
|
||||
|
||||
{{ tmp_dir }}/pki/issued_certs:
|
||||
file.directory
|
||||
|
||||
{{ tmp_dir }}/pki/ca.key:
|
||||
x509.private_key_managed:
|
||||
- bits: 4096
|
||||
- require:
|
||||
- file: {{ tmp_dir }}/pki
|
||||
|
||||
{{ tmp_dir }}/pki/ca.crt:
|
||||
x509.certificate_managed:
|
||||
- signing_private_key: {{ tmp_dir }}/pki/ca.key
|
||||
- CN: ca.example.com
|
||||
- C: US
|
||||
- ST: Utah
|
||||
- L: Salt Lake City
|
||||
- basicConstraints: "critical CA:true"
|
||||
- keyUsage: "critical cRLSign, keyCertSign"
|
||||
- subjectKeyIdentifier: hash
|
||||
- authorityKeyIdentifier: keyid,issuer:always
|
||||
- days_valid: 3650
|
||||
- days_remaining: 0
|
||||
- backup: True
|
||||
- managed_private_key:
|
||||
name: {{ tmp_dir }}/pki/ca.key
|
||||
bits: 4096
|
||||
backup: True
|
||||
- require:
|
||||
- file: {{ tmp_dir }}/pki
|
||||
- {{ tmp_dir }}/pki/ca.key
|
||||
|
||||
mine.send:
|
||||
module.run:
|
||||
- func: x509.get_pem_entries
|
||||
- kwargs:
|
||||
glob_path: {{ tmp_dir }}/pki/ca.crt
|
||||
- onchanges:
|
||||
- x509: {{ tmp_dir }}/pki/ca.crt
|
||||
|
||||
{{ tmp_dir }}/pki/test.key:
|
||||
x509.private_key_managed:
|
||||
- bits: 4096
|
||||
- backup: True
|
||||
|
||||
test_crt:
|
||||
x509.certificate_managed:
|
||||
- name: {{ tmp_dir }}/pki/test.crt
|
||||
- ca_server: minion
|
||||
- signing_policy: ca_policy
|
||||
- public_key: {{ tmp_dir }}/pki/test.key
|
||||
- CN: minion
|
||||
- days_remaining: 30
|
||||
- not_before: 2019-05-05 00:00:00
|
||||
- not_after: 2020-05-05 14:30:00
|
||||
- backup: True
|
||||
- managed_private_key:
|
||||
name: {{ tmp_dir }}/pki/test.key
|
||||
bits: 4096
|
||||
backup: True
|
||||
- require:
|
||||
- {{ tmp_dir }}/pki/ca.crt
|
||||
- {{ tmp_dir }}/pki/test.key
|
|
@ -115,6 +115,60 @@ class x509Test(ModuleCase, SaltReturnAssertsMixin):
|
|||
assert "Certificate" in ret[key]["changes"]
|
||||
assert "New" in ret[key]["changes"]["Certificate"]
|
||||
|
||||
def test_cert_issue_not_before_not_after(self):
|
||||
ret = self.run_function(
|
||||
"state.apply",
|
||||
["test_cert_not_before_not_after"],
|
||||
pillar={"tmp_dir": RUNTIME_VARS.TMP},
|
||||
)
|
||||
key = "x509_|-test_crt_|-{}/pki/test.crt_|-certificate_managed".format(
|
||||
RUNTIME_VARS.TMP
|
||||
)
|
||||
assert key in ret
|
||||
assert "changes" in ret[key]
|
||||
assert "Certificate" in ret[key]["changes"]
|
||||
assert "New" in ret[key]["changes"]["Certificate"]
|
||||
assert "Not Before" in ret[key]["changes"]["Certificate"]["New"]
|
||||
assert "Not After" in ret[key]["changes"]["Certificate"]["New"]
|
||||
not_before = ret[key]["changes"]["Certificate"]["New"]["Not Before"]
|
||||
not_after = ret[key]["changes"]["Certificate"]["New"]["Not After"]
|
||||
assert not_before == "2019-05-05 00:00:00"
|
||||
assert not_after == "2020-05-05 14:30:00"
|
||||
|
||||
def test_cert_issue_not_before(self):
|
||||
ret = self.run_function(
|
||||
"state.apply",
|
||||
["test_cert_not_before"],
|
||||
pillar={"tmp_dir": RUNTIME_VARS.TMP},
|
||||
)
|
||||
key = "x509_|-test_crt_|-{}/pki/test.crt_|-certificate_managed".format(
|
||||
RUNTIME_VARS.TMP
|
||||
)
|
||||
assert key in ret
|
||||
assert "changes" in ret[key]
|
||||
assert "Certificate" in ret[key]["changes"]
|
||||
assert "New" in ret[key]["changes"]["Certificate"]
|
||||
assert "Not Before" in ret[key]["changes"]["Certificate"]["New"]
|
||||
assert "Not After" in ret[key]["changes"]["Certificate"]["New"]
|
||||
not_before = ret[key]["changes"]["Certificate"]["New"]["Not Before"]
|
||||
assert not_before == "2019-05-05 00:00:00"
|
||||
|
||||
def test_cert_issue_not_after(self):
|
||||
ret = self.run_function(
|
||||
"state.apply", ["test_cert_not_after"], pillar={"tmp_dir": RUNTIME_VARS.TMP}
|
||||
)
|
||||
key = "x509_|-test_crt_|-{}/pki/test.crt_|-certificate_managed".format(
|
||||
RUNTIME_VARS.TMP
|
||||
)
|
||||
assert key in ret
|
||||
assert "changes" in ret[key]
|
||||
assert "Certificate" in ret[key]["changes"]
|
||||
assert "New" in ret[key]["changes"]["Certificate"]
|
||||
assert "Not Before" in ret[key]["changes"]["Certificate"]["New"]
|
||||
assert "Not After" in ret[key]["changes"]["Certificate"]["New"]
|
||||
not_after = ret[key]["changes"]["Certificate"]["New"]["Not After"]
|
||||
assert not_after == "2020-05-05 14:30:00"
|
||||
|
||||
@with_tempfile(suffix=".crt", create=False)
|
||||
@with_tempfile(suffix=".key", create=False)
|
||||
def test_self_signed_cert(self, keyfile, crtfile):
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
# Import Salt Testing Libs
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
|
@ -42,6 +43,62 @@ except ImportError:
|
|||
HAS_M2CRYPTO = False
|
||||
|
||||
|
||||
default_values = {
|
||||
"ca_key": b"""-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICWwIBAAKBgQCjdjbgL4kQ8Lu73xeRRM1q3C3K3ptfCLpyfw38LRnymxaoJ6ls
|
||||
pNSx2dU1uJ89YKFlYLo1QcEk4rJ2fdIjarV0kuNCY3rC8jYUp9BpAU5Z6p9HKeT1
|
||||
2rTPH81JyjbQDR5PyfCyzYOQtpwpB4zIUUK/Go7tTm409xGKbbUFugJNgQIDAQAB
|
||||
AoGAF24we34U1ZrMLifSRv5nu3OIFNZHyx2DLDpOFOGaII5edwgIXwxZeIzS5Ppr
|
||||
yO568/8jcdLVDqZ4EkgCwRTgoXRq3a1GLHGFmBdDNvWjSTTMLoozuM0t2zjRmIsH
|
||||
hUd7tnai9Lf1Bp5HlBEhBU2gZWk+SXqLvxXe74/+BDAj7gECQQDRw1OPsrgTvs3R
|
||||
3MNwX6W8+iBYMTGjn6f/6rvEzUs/k6rwJluV7n8ISNUIAxoPy5g5vEYK6Ln/Ttc7
|
||||
u0K1KNlRAkEAx34qcxjuswavL3biNGE+8LpDJnJx1jaNWoH+ObuzYCCVMusdT2gy
|
||||
kKuq9ytTDgXd2qwZpIDNmscvReFy10glMQJAXebMz3U4Bk7SIHJtYy7OKQzn0dMj
|
||||
35WnRV81c2Jbnzhhu2PQeAvt/i1sgEuzLQL9QEtSJ6wLJ4mJvImV0TdaIQJAAYyk
|
||||
TcKK0A8kOy0kMp3yvDHmJZ1L7wr7bBGIZPBlQ0Ddh8i1sJExm1gJ+uN2QKyg/XrK
|
||||
tDFf52zWnCdVGgDwcQJALW/WcbSEK+JVV6KDJYpwCzWpKIKpBI0F6fdCr1G7Xcwj
|
||||
c9bcgp7D7xD+TxWWNj4CSXEccJgGr91StV+gFg4ARQ==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
""",
|
||||
"x509_args_ca": {
|
||||
"text": True,
|
||||
"CN": "Redacted Root CA",
|
||||
"O": "Redacted",
|
||||
"C": "BE",
|
||||
"ST": "Antwerp",
|
||||
"L": "Local Town",
|
||||
"Email": "certadm@example.org",
|
||||
"basicConstraints": "critical CA:true",
|
||||
"keyUsage": "critical cRLSign, keyCertSign",
|
||||
"subjectKeyIdentifier": "hash",
|
||||
"authorityKeyIdentifier": "keyid,issuer:always",
|
||||
"days_valid": 3650,
|
||||
"days_remaining": 0,
|
||||
},
|
||||
"x509_args_cert": {
|
||||
"text": True,
|
||||
"CN": "Redacted Normal Certificate",
|
||||
"O": "Redacted",
|
||||
"C": "BE",
|
||||
"ST": "Antwerp",
|
||||
"L": "Local Town",
|
||||
"Email": "certadm@example.org",
|
||||
"basicConstraints": "critical CA:false",
|
||||
"keyUsage": "critical keyEncipherment",
|
||||
"subjectKeyIdentifier": "hash",
|
||||
"authorityKeyIdentifier": "keyid,issuer:always",
|
||||
},
|
||||
"crl_args": {
|
||||
"text": False,
|
||||
"signing_private_key_passphrase": None,
|
||||
"revoked": None,
|
||||
"include_expired": False,
|
||||
"days_valid": 100,
|
||||
"digest": "sha512",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@skipIf(not bool(pytest), False)
|
||||
class X509TestCase(TestCase, LoaderModuleMockMixin):
|
||||
def setup_loader_modules(self):
|
||||
|
@ -74,60 +131,27 @@ class X509TestCase(TestCase, LoaderModuleMockMixin):
|
|||
assert x509.log.trace.call_args[0][1] == list(subj.nid.keys())[0]
|
||||
assert isinstance(x509.log.trace.call_args[0][2], TypeError)
|
||||
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailble")
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailable")
|
||||
def test_get_pem_entry(self):
|
||||
"""
|
||||
Test private function _parse_subject(subject) it handles a missing fields
|
||||
:return:
|
||||
"""
|
||||
ca_key = b"""-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICWwIBAAKBgQCjdjbgL4kQ8Lu73xeRRM1q3C3K3ptfCLpyfw38LRnymxaoJ6ls
|
||||
pNSx2dU1uJ89YKFlYLo1QcEk4rJ2fdIjarV0kuNCY3rC8jYUp9BpAU5Z6p9HKeT1
|
||||
2rTPH81JyjbQDR5PyfCyzYOQtpwpB4zIUUK/Go7tTm409xGKbbUFugJNgQIDAQAB
|
||||
AoGAF24we34U1ZrMLifSRv5nu3OIFNZHyx2DLDpOFOGaII5edwgIXwxZeIzS5Ppr
|
||||
yO568/8jcdLVDqZ4EkgCwRTgoXRq3a1GLHGFmBdDNvWjSTTMLoozuM0t2zjRmIsH
|
||||
hUd7tnai9Lf1Bp5HlBEhBU2gZWk+SXqLvxXe74/+BDAj7gECQQDRw1OPsrgTvs3R
|
||||
3MNwX6W8+iBYMTGjn6f/6rvEzUs/k6rwJluV7n8ISNUIAxoPy5g5vEYK6Ln/Ttc7
|
||||
u0K1KNlRAkEAx34qcxjuswavL3biNGE+8LpDJnJx1jaNWoH+ObuzYCCVMusdT2gy
|
||||
kKuq9ytTDgXd2qwZpIDNmscvReFy10glMQJAXebMz3U4Bk7SIHJtYy7OKQzn0dMj
|
||||
35WnRV81c2Jbnzhhu2PQeAvt/i1sgEuzLQL9QEtSJ6wLJ4mJvImV0TdaIQJAAYyk
|
||||
TcKK0A8kOy0kMp3yvDHmJZ1L7wr7bBGIZPBlQ0Ddh8i1sJExm1gJ+uN2QKyg/XrK
|
||||
tDFf52zWnCdVGgDwcQJALW/WcbSEK+JVV6KDJYpwCzWpKIKpBI0F6fdCr1G7Xcwj
|
||||
c9bcgp7D7xD+TxWWNj4CSXEccJgGr91StV+gFg4ARQ==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
"""
|
||||
|
||||
ca_key = default_values["ca_key"]
|
||||
ret = x509.get_pem_entry(ca_key)
|
||||
self.assertEqual(ret, ca_key)
|
||||
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailble")
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailable")
|
||||
def test_get_private_key_size(self):
|
||||
"""
|
||||
Test private function _parse_subject(subject) it handles a missing fields
|
||||
:return:
|
||||
"""
|
||||
ca_key = """
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICWwIBAAKBgQCjdjbgL4kQ8Lu73xeRRM1q3C3K3ptfCLpyfw38LRnymxaoJ6ls
|
||||
pNSx2dU1uJ89YKFlYLo1QcEk4rJ2fdIjarV0kuNCY3rC8jYUp9BpAU5Z6p9HKeT1
|
||||
2rTPH81JyjbQDR5PyfCyzYOQtpwpB4zIUUK/Go7tTm409xGKbbUFugJNgQIDAQAB
|
||||
AoGAF24we34U1ZrMLifSRv5nu3OIFNZHyx2DLDpOFOGaII5edwgIXwxZeIzS5Ppr
|
||||
yO568/8jcdLVDqZ4EkgCwRTgoXRq3a1GLHGFmBdDNvWjSTTMLoozuM0t2zjRmIsH
|
||||
hUd7tnai9Lf1Bp5HlBEhBU2gZWk+SXqLvxXe74/+BDAj7gECQQDRw1OPsrgTvs3R
|
||||
3MNwX6W8+iBYMTGjn6f/6rvEzUs/k6rwJluV7n8ISNUIAxoPy5g5vEYK6Ln/Ttc7
|
||||
u0K1KNlRAkEAx34qcxjuswavL3biNGE+8LpDJnJx1jaNWoH+ObuzYCCVMusdT2gy
|
||||
kKuq9ytTDgXd2qwZpIDNmscvReFy10glMQJAXebMz3U4Bk7SIHJtYy7OKQzn0dMj
|
||||
35WnRV81c2Jbnzhhu2PQeAvt/i1sgEuzLQL9QEtSJ6wLJ4mJvImV0TdaIQJAAYyk
|
||||
TcKK0A8kOy0kMp3yvDHmJZ1L7wr7bBGIZPBlQ0Ddh8i1sJExm1gJ+uN2QKyg/XrK
|
||||
tDFf52zWnCdVGgDwcQJALW/WcbSEK+JVV6KDJYpwCzWpKIKpBI0F6fdCr1G7Xcwj
|
||||
c9bcgp7D7xD+TxWWNj4CSXEccJgGr91StV+gFg4ARQ==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
"""
|
||||
|
||||
ca_key = default_values["ca_key"]
|
||||
ret = x509.get_private_key_size(ca_key)
|
||||
self.assertEqual(ret, 1024)
|
||||
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailble")
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailable")
|
||||
def test_create_key(self):
|
||||
"""
|
||||
Test that x509.create_key returns a private key
|
||||
|
@ -136,87 +160,197 @@ c9bcgp7D7xD+TxWWNj4CSXEccJgGr91StV+gFg4ARQ==
|
|||
ret = x509.create_private_key(text=True, passphrase="super_secret_passphrase")
|
||||
self.assertIn("BEGIN RSA PRIVATE KEY", ret)
|
||||
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailble")
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailable")
|
||||
def test_create_certificate(self):
|
||||
"""
|
||||
Test private function _parse_subject(subject) it handles a missing fields
|
||||
:return:
|
||||
"""
|
||||
ca_key = """
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICWwIBAAKBgQCjdjbgL4kQ8Lu73xeRRM1q3C3K3ptfCLpyfw38LRnymxaoJ6ls
|
||||
pNSx2dU1uJ89YKFlYLo1QcEk4rJ2fdIjarV0kuNCY3rC8jYUp9BpAU5Z6p9HKeT1
|
||||
2rTPH81JyjbQDR5PyfCyzYOQtpwpB4zIUUK/Go7tTm409xGKbbUFugJNgQIDAQAB
|
||||
AoGAF24we34U1ZrMLifSRv5nu3OIFNZHyx2DLDpOFOGaII5edwgIXwxZeIzS5Ppr
|
||||
yO568/8jcdLVDqZ4EkgCwRTgoXRq3a1GLHGFmBdDNvWjSTTMLoozuM0t2zjRmIsH
|
||||
hUd7tnai9Lf1Bp5HlBEhBU2gZWk+SXqLvxXe74/+BDAj7gECQQDRw1OPsrgTvs3R
|
||||
3MNwX6W8+iBYMTGjn6f/6rvEzUs/k6rwJluV7n8ISNUIAxoPy5g5vEYK6Ln/Ttc7
|
||||
u0K1KNlRAkEAx34qcxjuswavL3biNGE+8LpDJnJx1jaNWoH+ObuzYCCVMusdT2gy
|
||||
kKuq9ytTDgXd2qwZpIDNmscvReFy10glMQJAXebMz3U4Bk7SIHJtYy7OKQzn0dMj
|
||||
35WnRV81c2Jbnzhhu2PQeAvt/i1sgEuzLQL9QEtSJ6wLJ4mJvImV0TdaIQJAAYyk
|
||||
TcKK0A8kOy0kMp3yvDHmJZ1L7wr7bBGIZPBlQ0Ddh8i1sJExm1gJ+uN2QKyg/XrK
|
||||
tDFf52zWnCdVGgDwcQJALW/WcbSEK+JVV6KDJYpwCzWpKIKpBI0F6fdCr1G7Xcwj
|
||||
c9bcgp7D7xD+TxWWNj4CSXEccJgGr91StV+gFg4ARQ==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
"""
|
||||
|
||||
ret = x509.create_certificate(
|
||||
text=True,
|
||||
signing_private_key=ca_key,
|
||||
CN="Redacted Root CA",
|
||||
O="Redacted",
|
||||
C="BE",
|
||||
ST="Antwerp",
|
||||
L="Local Town",
|
||||
Email="certadm@example.org",
|
||||
basicConstraints="critical CA:true",
|
||||
keyUsage="critical cRLSign, keyCertSign",
|
||||
subjectKeyIdentifier="hash",
|
||||
authorityKeyIdentifier="keyid,issuer:always",
|
||||
days_valid=3650,
|
||||
days_remaining=0,
|
||||
)
|
||||
ca_key = default_values["ca_key"]
|
||||
ca_kwargs = default_values["x509_args_ca"].copy()
|
||||
ca_kwargs["signing_private_key"] = ca_key
|
||||
ret = x509.create_certificate(**ca_kwargs)
|
||||
self.assertIn("BEGIN CERTIFICATE", ret)
|
||||
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailble")
|
||||
def test_create_crl(self):
|
||||
ca_key = """
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICWwIBAAKBgQCjdjbgL4kQ8Lu73xeRRM1q3C3K3ptfCLpyfw38LRnymxaoJ6ls
|
||||
pNSx2dU1uJ89YKFlYLo1QcEk4rJ2fdIjarV0kuNCY3rC8jYUp9BpAU5Z6p9HKeT1
|
||||
2rTPH81JyjbQDR5PyfCyzYOQtpwpB4zIUUK/Go7tTm409xGKbbUFugJNgQIDAQAB
|
||||
AoGAF24we34U1ZrMLifSRv5nu3OIFNZHyx2DLDpOFOGaII5edwgIXwxZeIzS5Ppr
|
||||
yO568/8jcdLVDqZ4EkgCwRTgoXRq3a1GLHGFmBdDNvWjSTTMLoozuM0t2zjRmIsH
|
||||
hUd7tnai9Lf1Bp5HlBEhBU2gZWk+SXqLvxXe74/+BDAj7gECQQDRw1OPsrgTvs3R
|
||||
3MNwX6W8+iBYMTGjn6f/6rvEzUs/k6rwJluV7n8ISNUIAxoPy5g5vEYK6Ln/Ttc7
|
||||
u0K1KNlRAkEAx34qcxjuswavL3biNGE+8LpDJnJx1jaNWoH+ObuzYCCVMusdT2gy
|
||||
kKuq9ytTDgXd2qwZpIDNmscvReFy10glMQJAXebMz3U4Bk7SIHJtYy7OKQzn0dMj
|
||||
35WnRV81c2Jbnzhhu2PQeAvt/i1sgEuzLQL9QEtSJ6wLJ4mJvImV0TdaIQJAAYyk
|
||||
TcKK0A8kOy0kMp3yvDHmJZ1L7wr7bBGIZPBlQ0Ddh8i1sJExm1gJ+uN2QKyg/XrK
|
||||
tDFf52zWnCdVGgDwcQJALW/WcbSEK+JVV6KDJYpwCzWpKIKpBI0F6fdCr1G7Xcwj
|
||||
c9bcgp7D7xD+TxWWNj4CSXEccJgGr91StV+gFg4ARQ==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
"""
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailable")
|
||||
def test_create_certificate_with_not_after(self):
|
||||
ca_key = default_values["ca_key"]
|
||||
ca_kwargs = default_values["x509_args_ca"].copy()
|
||||
ca_kwargs["signing_private_key"] = ca_key
|
||||
|
||||
ca_cert = x509.create_certificate(
|
||||
text=True,
|
||||
signing_private_key=ca_key,
|
||||
CN="Redacted Root CA",
|
||||
O="Redacted",
|
||||
C="BE",
|
||||
ST="Antwerp",
|
||||
L="Local Town",
|
||||
Email="certadm@example.org",
|
||||
basicConstraints="critical CA:true",
|
||||
keyUsage="critical cRLSign, keyCertSign",
|
||||
subjectKeyIdentifier="hash",
|
||||
authorityKeyIdentifier="keyid,issuer:always",
|
||||
days_valid=3650,
|
||||
days_remaining=0,
|
||||
)
|
||||
# Issue the CA certificate (self-signed)
|
||||
ca_cert = x509.create_certificate(**ca_kwargs)
|
||||
|
||||
fmt = "%Y-%m-%d %H:%M:%S"
|
||||
# We also gonna use the current date in UTC format for verification
|
||||
not_after = datetime.datetime.utcnow()
|
||||
# And set the UTC timezone to the naive datetime resulting from parsing
|
||||
not_after = not_after.replace(tzinfo=M2Crypto.ASN1.UTC)
|
||||
not_after_str = datetime.datetime.strftime(not_after, fmt)
|
||||
|
||||
# Sign a new server certificate with the CA
|
||||
ca_key = default_values["ca_key"]
|
||||
cert_kwargs = default_values["x509_args_cert"].copy()
|
||||
cert_kwargs["signing_private_key"] = ca_key
|
||||
cert_kwargs["signing_cert"] = ca_cert
|
||||
cert_kwargs["not_after"] = not_after_str
|
||||
server_cert = x509.create_certificate(**cert_kwargs)
|
||||
|
||||
not_after_from_cert = ""
|
||||
# Save server certificate to disk so we can check its properties
|
||||
with tempfile.NamedTemporaryFile("w+") as server_cert_file:
|
||||
server_cert_file.write(salt.utils.stringutils.to_str(server_cert))
|
||||
server_cert_file.flush()
|
||||
|
||||
# Retrieve not_after property from server certificate
|
||||
server_cert_details = x509.read_certificate(server_cert_file.name)
|
||||
not_after_from_cert = server_cert_details["Not After"]
|
||||
|
||||
# Check if property is the one we've added to the certificate. The
|
||||
# property from the certificate will come as a string with no timezone
|
||||
# information in it.
|
||||
self.assertIn(not_after_str, not_after_from_cert)
|
||||
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailable")
|
||||
def test_create_certificate_with_not_before(self):
|
||||
ca_key = default_values["ca_key"]
|
||||
ca_kwargs = default_values.get("x509_args_ca").copy()
|
||||
ca_kwargs["signing_private_key"] = ca_key
|
||||
|
||||
# Issue the CA certificate (self-signed)
|
||||
ca_cert = x509.create_certificate(**ca_kwargs)
|
||||
|
||||
fmt = "%Y-%m-%d %H:%M:%S"
|
||||
# We also gonna use the current date in UTC format for verification
|
||||
not_before = datetime.datetime.utcnow()
|
||||
# And set the UTC timezone to the naive datetime resulting from parsing
|
||||
not_before = not_before.replace(tzinfo=M2Crypto.ASN1.UTC)
|
||||
not_before_str = datetime.datetime.strftime(not_before, fmt)
|
||||
|
||||
# Sign a new server certificate with the CA
|
||||
ca_key = default_values["ca_key"]
|
||||
cert_kwargs = default_values["x509_args_cert"].copy()
|
||||
cert_kwargs["signing_private_key"] = ca_key
|
||||
cert_kwargs["signing_cert"] = ca_cert
|
||||
cert_kwargs["not_before"] = not_before_str
|
||||
server_cert = x509.create_certificate(**cert_kwargs)
|
||||
|
||||
not_before_from_cert = ""
|
||||
# Save server certificate to disk so we can check its properties
|
||||
with tempfile.NamedTemporaryFile("w+") as server_cert_file:
|
||||
server_cert_file.write(salt.utils.stringutils.to_str(server_cert))
|
||||
server_cert_file.flush()
|
||||
# Retrieve not_after property from server certificate
|
||||
server_cert_details = x509.read_certificate(server_cert_file.name)
|
||||
not_before_from_cert = server_cert_details["Not Before"]
|
||||
|
||||
# Check if property is the one we've added to the certificate. The
|
||||
# property will come from the certificate as a string with no timezone
|
||||
# information in it.
|
||||
self.assertIn(not_before_str, not_before_from_cert)
|
||||
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailable")
|
||||
def test_create_certificate_with_not_before_wrong_date(self):
|
||||
ca_key = default_values["ca_key"]
|
||||
ca_kwargs = default_values.get("x509_args_ca").copy()
|
||||
ca_kwargs["signing_private_key"] = ca_key
|
||||
|
||||
# Issue the CA certificate (self-signed)
|
||||
ca_cert = x509.create_certificate(**ca_kwargs)
|
||||
|
||||
not_before_str = "this is an intentionally wrong format"
|
||||
|
||||
# Try to sign a new server certificate with the wrong date
|
||||
msg = "not_before: this is an intentionally wrong format is not in required format %Y-%m-%d %H:%M:%S"
|
||||
with self.assertRaisesRegex(salt.exceptions.SaltInvocationError, msg):
|
||||
ca_key = default_values["ca_key"]
|
||||
cert_kwargs = default_values["x509_args_cert"].copy()
|
||||
cert_kwargs["signing_private_key"] = ca_key
|
||||
cert_kwargs["signing_cert"] = ca_cert
|
||||
cert_kwargs["not_before"] = not_before_str
|
||||
x509.create_certificate(**cert_kwargs)
|
||||
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailable")
|
||||
def test_create_certificate_with_not_after_wrong_date(self):
|
||||
ca_key = default_values["ca_key"]
|
||||
ca_kwargs = default_values.get("x509_args_ca").copy()
|
||||
ca_kwargs["signing_private_key"] = ca_key
|
||||
|
||||
# Issue the CA certificate (self-signed)
|
||||
ca_cert = x509.create_certificate(**ca_kwargs)
|
||||
|
||||
not_after_str = "this is an intentionally wrong format"
|
||||
|
||||
# Try to sign a new server certificate with the wrong date
|
||||
msg = "not_after: this is an intentionally wrong format is not in required format %Y-%m-%d %H:%M:%S"
|
||||
with self.assertRaisesRegex(salt.exceptions.SaltInvocationError, msg):
|
||||
ca_key = default_values["ca_key"]
|
||||
cert_kwargs = default_values["x509_args_cert"].copy()
|
||||
cert_kwargs["signing_private_key"] = ca_key
|
||||
cert_kwargs["signing_cert"] = ca_cert
|
||||
cert_kwargs["not_after"] = not_after_str
|
||||
x509.create_certificate(**cert_kwargs)
|
||||
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailable")
|
||||
def test_create_certificate_with_not_before_and_not_after(self):
|
||||
ca_key = default_values["ca_key"]
|
||||
ca_kwargs = default_values.get("x509_args_ca").copy()
|
||||
ca_kwargs["signing_private_key"] = ca_key
|
||||
|
||||
# Issue the CA certificate (self-signed)
|
||||
ca_cert = x509.create_certificate(**ca_kwargs)
|
||||
|
||||
fmt = "%Y-%m-%d %H:%M:%S"
|
||||
# Here we gonna use the current date as the not_before date
|
||||
# First we again take the UTC for verification
|
||||
not_before = datetime.datetime.utcnow()
|
||||
# And set the UTC timezone to the naive datetime resulting from parsing
|
||||
not_before = not_before.replace(tzinfo=M2Crypto.ASN1.UTC)
|
||||
not_before_str = datetime.datetime.strftime(not_before, fmt)
|
||||
# And we use the same logic to generate a not_after 5 days in the
|
||||
# future
|
||||
not_after = not_before + datetime.timedelta(days=5)
|
||||
# And set the UTC timezone to the naive datetime resulting from parsing
|
||||
not_after = not_after.replace(tzinfo=M2Crypto.ASN1.UTC)
|
||||
not_after_str = datetime.datetime.strftime(not_after, fmt)
|
||||
|
||||
# Sign a new server certificate with the CA
|
||||
ca_key = default_values["ca_key"]
|
||||
cert_kwargs = default_values["x509_args_cert"].copy()
|
||||
cert_kwargs["signing_private_key"] = ca_key
|
||||
cert_kwargs["signing_cert"] = ca_cert
|
||||
cert_kwargs["not_after"] = not_after_str
|
||||
cert_kwargs["not_before"] = not_before_str
|
||||
server_cert = x509.create_certificate(**cert_kwargs)
|
||||
|
||||
not_after_from_cert = ""
|
||||
not_before_from_cert = ""
|
||||
# Save server certificate to disk so we can check its properties
|
||||
with tempfile.NamedTemporaryFile("w+") as server_cert_file:
|
||||
server_cert_file.write(salt.utils.stringutils.to_str(server_cert))
|
||||
server_cert_file.flush()
|
||||
|
||||
# Retrieve not_after property from server certificate
|
||||
server_cert_details = x509.read_certificate(server_cert_file.name)
|
||||
not_before_from_cert = server_cert_details["Not Before"]
|
||||
not_after_from_cert = server_cert_details["Not After"]
|
||||
|
||||
# Check if property values are the ones we've added to the certificate.
|
||||
# The values will come as strings containing no timezone information in
|
||||
# them.
|
||||
self.assertIn(not_before_str, not_before_from_cert)
|
||||
self.assertIn(not_after_str, not_after_from_cert)
|
||||
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailable")
|
||||
def test_create_crl(self):
|
||||
ca_key = default_values["ca_key"]
|
||||
ca_kwargs = default_values.get("x509_args_ca").copy()
|
||||
ca_kwargs["signing_private_key"] = ca_key
|
||||
|
||||
ca_cert = x509.create_certificate(**ca_kwargs)
|
||||
|
||||
with tempfile.NamedTemporaryFile("w+", delete=False) as ca_key_file:
|
||||
ca_key_file.write(ca_key)
|
||||
ca_key_file.write(salt.utils.stringutils.to_str(ca_key))
|
||||
ca_key_file.flush()
|
||||
|
||||
with tempfile.NamedTemporaryFile("w+", delete=False) as ca_cert_file:
|
||||
|
@ -224,17 +358,11 @@ c9bcgp7D7xD+TxWWNj4CSXEccJgGr91StV+gFg4ARQ==
|
|||
ca_cert_file.flush()
|
||||
|
||||
with tempfile.NamedTemporaryFile("w+", delete=False) as ca_crl_file:
|
||||
x509.create_crl(
|
||||
path=ca_crl_file.name,
|
||||
text=False,
|
||||
signing_private_key=ca_key_file.name,
|
||||
signing_private_key_passphrase=None,
|
||||
signing_cert=ca_cert_file.name,
|
||||
revoked=None,
|
||||
include_expired=False,
|
||||
days_valid=100,
|
||||
digest="sha512",
|
||||
)
|
||||
crl_kwargs = default_values.get("crl_args").copy()
|
||||
crl_kwargs["path"] = ca_crl_file.name
|
||||
crl_kwargs["signing_private_key"] = ca_key_file.name
|
||||
crl_kwargs["signing_cert"] = ca_cert_file.name
|
||||
x509.create_crl(**crl_kwargs)
|
||||
|
||||
with salt.utils.files.fopen(ca_crl_file.name, "r") as crl_file:
|
||||
crl = crl_file.read()
|
||||
|
@ -246,65 +374,25 @@ c9bcgp7D7xD+TxWWNj4CSXEccJgGr91StV+gFg4ARQ==
|
|||
# Ensure that a CRL was actually created
|
||||
self.assertIn("BEGIN X509 CRL", crl)
|
||||
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailble")
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailable")
|
||||
def test_revoke_certificate_with_crl(self):
|
||||
ca_key = """
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICWwIBAAKBgQCjdjbgL4kQ8Lu73xeRRM1q3C3K3ptfCLpyfw38LRnymxaoJ6ls
|
||||
pNSx2dU1uJ89YKFlYLo1QcEk4rJ2fdIjarV0kuNCY3rC8jYUp9BpAU5Z6p9HKeT1
|
||||
2rTPH81JyjbQDR5PyfCyzYOQtpwpB4zIUUK/Go7tTm409xGKbbUFugJNgQIDAQAB
|
||||
AoGAF24we34U1ZrMLifSRv5nu3OIFNZHyx2DLDpOFOGaII5edwgIXwxZeIzS5Ppr
|
||||
yO568/8jcdLVDqZ4EkgCwRTgoXRq3a1GLHGFmBdDNvWjSTTMLoozuM0t2zjRmIsH
|
||||
hUd7tnai9Lf1Bp5HlBEhBU2gZWk+SXqLvxXe74/+BDAj7gECQQDRw1OPsrgTvs3R
|
||||
3MNwX6W8+iBYMTGjn6f/6rvEzUs/k6rwJluV7n8ISNUIAxoPy5g5vEYK6Ln/Ttc7
|
||||
u0K1KNlRAkEAx34qcxjuswavL3biNGE+8LpDJnJx1jaNWoH+ObuzYCCVMusdT2gy
|
||||
kKuq9ytTDgXd2qwZpIDNmscvReFy10glMQJAXebMz3U4Bk7SIHJtYy7OKQzn0dMj
|
||||
35WnRV81c2Jbnzhhu2PQeAvt/i1sgEuzLQL9QEtSJ6wLJ4mJvImV0TdaIQJAAYyk
|
||||
TcKK0A8kOy0kMp3yvDHmJZ1L7wr7bBGIZPBlQ0Ddh8i1sJExm1gJ+uN2QKyg/XrK
|
||||
tDFf52zWnCdVGgDwcQJALW/WcbSEK+JVV6KDJYpwCzWpKIKpBI0F6fdCr1G7Xcwj
|
||||
c9bcgp7D7xD+TxWWNj4CSXEccJgGr91StV+gFg4ARQ==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
"""
|
||||
# Issue the CA certificate (self-signed)
|
||||
ca_cert = x509.create_certificate(
|
||||
text=True,
|
||||
signing_private_key=ca_key,
|
||||
CN="Redacted Root CA",
|
||||
O="Redacted",
|
||||
C="BE",
|
||||
ST="Antwerp",
|
||||
L="Local Town",
|
||||
Email="certadm@example.org",
|
||||
basicConstraints="critical CA:true",
|
||||
keyUsage="critical cRLSign, keyCertSign",
|
||||
subjectKeyIdentifier="hash",
|
||||
authorityKeyIdentifier="keyid,issuer:always",
|
||||
days_valid=3650,
|
||||
days_remaining=0,
|
||||
)
|
||||
ca_key = default_values["ca_key"]
|
||||
ca_kwargs = default_values.get("x509_args_ca").copy()
|
||||
ca_kwargs["signing_private_key"] = ca_key
|
||||
|
||||
# Sign a client certificate with the CA
|
||||
server_cert = x509.create_certificate(
|
||||
text=True,
|
||||
signing_private_key=ca_key,
|
||||
signing_cert=ca_cert,
|
||||
CN="Redacted Normal Certificate",
|
||||
O="Redacted",
|
||||
C="BE",
|
||||
ST="Antwerp",
|
||||
L="Local Town",
|
||||
Email="certadm@example.org",
|
||||
basicConstraints="critical CA:false",
|
||||
keyUsage="critical keyEncipherment",
|
||||
subjectKeyIdentifier="hash",
|
||||
authorityKeyIdentifier="keyid,issuer:always",
|
||||
days_valid=365,
|
||||
days_remaining=0,
|
||||
)
|
||||
# Issue the CA certificate (self-signed)
|
||||
ca_cert = x509.create_certificate(**ca_kwargs)
|
||||
|
||||
# Sign a new server certificate with the CA
|
||||
ca_key = default_values["ca_key"]
|
||||
cert_kwargs = default_values["x509_args_cert"].copy()
|
||||
cert_kwargs["signing_private_key"] = ca_key
|
||||
cert_kwargs["signing_cert"] = ca_cert
|
||||
server_cert = x509.create_certificate(**cert_kwargs)
|
||||
|
||||
# Save CA cert + key and server cert to disk as PEM files
|
||||
with tempfile.NamedTemporaryFile("w+", delete=False) as ca_key_file:
|
||||
ca_key_file.write(ca_key)
|
||||
ca_key_file.write(salt.utils.stringutils.to_str(ca_key))
|
||||
ca_key_file.flush()
|
||||
|
||||
with tempfile.NamedTemporaryFile("w+", delete=False) as ca_cert_file:
|
||||
|
@ -323,17 +411,13 @@ c9bcgp7D7xD+TxWWNj4CSXEccJgGr91StV+gFg4ARQ==
|
|||
}
|
||||
]
|
||||
with tempfile.NamedTemporaryFile("w+", delete=False) as ca_crl_file:
|
||||
x509.create_crl(
|
||||
path=ca_crl_file.name,
|
||||
text=False,
|
||||
signing_private_key=ca_key_file.name,
|
||||
signing_private_key_passphrase=None,
|
||||
signing_cert=ca_cert_file.name,
|
||||
revoked=revoked,
|
||||
include_expired=False,
|
||||
days_valid=100,
|
||||
digest="sha512",
|
||||
)
|
||||
crl_kwargs = default_values.get("crl_args").copy()
|
||||
crl_kwargs["path"] = ca_crl_file.name
|
||||
crl_kwargs["signing_private_key"] = ca_key_file.name
|
||||
crl_kwargs["signing_cert"] = ca_cert_file.name
|
||||
# Add list of revoked certificates
|
||||
crl_kwargs["revoked"] = revoked
|
||||
x509.create_crl(**crl_kwargs)
|
||||
|
||||
# Retrieve serial number from server certificate
|
||||
server_cert_details = x509.read_certificate(server_cert_file.name)
|
||||
|
|
Loading…
Add table
Reference in a new issue