Skip to content

Commit

Permalink
Add an option to keep the CA cert
Browse files Browse the repository at this point in the history
This still isn't designed to trust the CA cert directly, but syslog-ng
seems to support EE cert pinning only in conjuction with CA-based
verification.
  • Loading branch information
dseomn committed May 26, 2024
1 parent 047e160 commit 513cc08
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 6 deletions.
20 changes: 15 additions & 5 deletions salt/file/crypto/x509/boilerplate_certificate.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@
self-signed CA certificate with a single child EE certificate, which seems to
better match how PKIX and TLS are designed.
The CA certificate and its key are immediately discarded, leaving the EE
certificate and its key for use with TLS software that can be configured to
trust an EE certificate directly. If this script ever needs to be used with TLS
software that requires a CA to trust, it should be re-reviewed for that purpose,
and it would probably need some security improvements:
The CA certificate and its key are immediately discarded by default, leaving the
EE certificate and its key for use with TLS software that can be configured to
trust an EE certificate directly. The option to keep the CA certificate is
designed for software that can pin EE certificates but still needs the CA
certificate too. If this script ever needs to be used with TLS software that
requires a CA to trust without EE certificate pinning, it should be re-reviewed
for that purpose, and it would probably need some security improvements:
The exposure surface of the CA's private key should be minimized to avoid an
attacker surreptitiously creating new EE certs. mlockall(2) looks useful, though
Expand All @@ -55,6 +57,7 @@
import argparse
from collections.abc import Sequence
import pathlib
import shutil
import subprocess
import tempfile
import textwrap
Expand All @@ -69,6 +72,11 @@ def _args():
required=True,
help="DNS name for the EE certificate.",
)
parser.add_argument(
"--ca-cert",
type=pathlib.Path,
help="Path to write the CA certificate to.",
)
parser.add_argument(
"--key",
type=pathlib.Path,
Expand Down Expand Up @@ -183,6 +191,8 @@ def main() -> None:
input=ca_private_key,
check=True,
)
if args.ca_cert is not None:
shutil.copyfile(tempdir.joinpath("ca-cert.pem"), args.ca_cert)

subprocess.run(
("openssl", "genpkey", *genpkey_args, "-out", str(args.key)),
Expand Down
33 changes: 32 additions & 1 deletion salt/file/crypto/x509/map.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
name,
warning_on_change,
dir_name=none,
group='root') %}
group='root',
keep_ca_cert=false) %}
{% if dir_name is none %}
{% set dir_name = name %}
{% endif %}
Expand All @@ -36,19 +37,33 @@ boilerplate_certificate_{{ dir_name }}:
&&
{{ common.local_bin }}/boilerplate-certificate
--name={{ name }}
{%- if keep_ca_cert %}
--ca-cert={{ common.local_etc }}/x509/{{ dir_name }}/cacert.pem
{%- endif %}
--key={{ common.local_etc }}/x509/{{ dir_name }}/privkey.pem
--cert={{ common.local_etc }}/x509/{{ dir_name }}/cert.pem
--key-algorithm={{ crypto.openssl.strict_key_algorithm }}
{%- for key_option in crypto.openssl.strict_key_options %}
--key-option={{ key_option }}
{%- endfor %}
--days={{ crypto.secret_validity_period_days }}
{%- if keep_ca_cert %}
&&
echo CA:
&&
cat {{ common.local_etc }}/x509/{{ dir_name }}/cacert.pem
{%- endif %}
&&
echo EE:
&&
openssl x509
-in {{ common.local_etc }}/x509/{{ dir_name }}/cert.pem
-{{ crypto.openssl.digest }}
-fingerprint
- creates:
{%- if keep_ca_cert %}
- {{ common.local_etc }}/x509/{{ dir_name }}/cacert.pem
{%- endif %}
- {{ common.local_etc }}/x509/{{ dir_name }}/privkey.pem
- {{ common.local_etc }}/x509/{{ dir_name }}/cert.pem
- require:
Expand All @@ -59,6 +74,22 @@ boilerplate_certificate_{{ dir_name }}:
- onchanges:
- cmd: boilerplate_certificate_{{ dir_name }}

{% if keep_ca_cert %}
{{ common.local_etc }}/x509/{{ dir_name }}/cacert.pem:
file.exists:
- require:
- boilerplate_certificate_{{ dir_name }}
{{ common.local_etc }}/x509/{{ dir_name }}/cacert.pem should be rotated:
file.accumulated:
- name: boilerplate certificates
- filename: {{ common.local_sbin }}/monitor-x509-validity-period
- text: {{ common.local_etc }}/x509/{{ dir_name }}/cacert.pem
- require:
- {{ common.local_etc }}/x509/{{ dir_name }}/cacert.pem
- require_in:
- file: {{ common.local_sbin }}/monitor-x509-validity-period
{% endif %}

{{ common.local_etc }}/x509/{{ dir_name }}/privkey.pem:
file.managed:
- create: false
Expand Down

0 comments on commit 513cc08

Please sign in to comment.