From 966daec84416487f8c2115f83cd1a844675d136c Mon Sep 17 00:00:00 2001 From: Jarno Elonen Date: Tue, 24 Sep 2024 13:52:52 +0300 Subject: [PATCH] Remove hostname from 'sign-dc-cert' command, use from .csr --- hsm_secrets/piv/__init__.py | 14 ++++++-------- hsm_secrets/piv/piv_cert_checks.py | 2 +- hsm_secrets/x509/cert_builder.py | 3 ++- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/hsm_secrets/piv/__init__.py b/hsm_secrets/piv/__init__.py index 524f858..f1cfff0 100644 --- a/hsm_secrets/piv/__init__.py +++ b/hsm_secrets/piv/__init__.py @@ -42,10 +42,12 @@ def cmd_piv_yubikey(): @click.option('--ca', '-c', required=False, help="CA ID (hex) or label, default: from config") @click.option('--out', '-o', required=False, type=click.Path(exists=False, dir_okay=False, resolve_path=True, allow_dash=False), help="Output filename, default: deduced from input") @click.option('--san', multiple=True, help="Additional (GeneralName) SANs") -@click.option('--hostname', '-n', required=True, help="Hostname (CommonName) for the DC certificate") @click.option('--template', '-t', required=False, help="Template label, default: first template") -def sign_dc_cert(ctx: HsmSecretsCtx, csr: click.File, validity: int, ca: str, out: str|None, san: list[str], hostname: str, template: str|None): - """Sign a DC Kerberos PKINIT certificate for PIV""" +def sign_dc_cert(ctx: HsmSecretsCtx, csr: click.File, validity: int, ca: str, out: str|None, san: list[str], template: str|None): + """Sign a DC Kerberos PKINIT certificate for PIV + + Usage: create a PKINIT CSR on the Domain Controller first, then sign it with this command. + """ csr_path = Path(csr.name) with csr_path.open('rb') as f: csr_obj: x509.CertificateSigningRequest = x509.load_pem_x509_csr(f.read()) @@ -82,12 +84,8 @@ def sign_dc_cert(ctx: HsmSecretsCtx, csr: click.File, validity: int, ca: str, ou raise click.ClickException(f"Provided '{san_type.lower()}' is not a supported X509NameType") x509_info.subject_alt_name.names.setdefault(san_type_lower, []).append(san_value) # type: ignore [arg-type] - # Add hostname to DNS SANs if not already there - if hostname not in (x509_info.subject_alt_name.names.get('dns') or []): - x509_info.subject_alt_name.names['dns'] = [hostname] + list(x509_info.subject_alt_name.names.get('dns') or []) - # Create X509CertBuilder - cert_builder = X509CertBuilder(ctx.conf, x509_info, csr_obj, dn_subject_override=f'CN={hostname}') + cert_builder = X509CertBuilder(ctx.conf, x509_info, csr_obj) # Sign the certificate with open_hsm_session(ctx) as ses: diff --git a/hsm_secrets/piv/piv_cert_checks.py b/hsm_secrets/piv/piv_cert_checks.py index 03fb155..90a84b5 100644 --- a/hsm_secrets/piv/piv_cert_checks.py +++ b/hsm_secrets/piv/piv_cert_checks.py @@ -15,7 +15,7 @@ def _check_specific_key_usage(self, key_usage: x509.KeyUsage): def _check_specific_extended_key_usage(self, ext_key_usage: x509.ExtendedKeyUsage): if ExtendedKeyUsageOID.SERVER_AUTH not in ext_key_usage: - self._add_issue("ExtendedKeyUsage does not include serverAuth", IssueSeverity.ERROR) + self._add_issue("ExtendedKeyUsage does not include serverAuth - this certificate won't be usable for TLS (e.g. LDAPS). Make sure this is intentional.", IssueSeverity.WARNING) if ExtendedKeyUsageOID.KERBEROS_PKINIT_KDC not in ext_key_usage: self._add_issue("ExtendedKeyUsage does not include KerberosKDC (PKINIT)", IssueSeverity.ERROR) diff --git a/hsm_secrets/x509/cert_builder.py b/hsm_secrets/x509/cert_builder.py index 22a8eba..3d8e9ee 100644 --- a/hsm_secrets/x509/cert_builder.py +++ b/hsm_secrets/x509/cert_builder.py @@ -145,7 +145,8 @@ def amend_and_sign_csr( assert self.csr, "No CSR available for amendment" assert amend_subject != CsrAmendMode.ADD, "Amend mode ADD not supported for subject" - subject = self.csr.subject if amend_subject==CsrAmendMode.KEEP else self._mk_name_attribs() + explicit_cn_is_set = self.dn_subject_override or (self.cert_def_info.attribs and self.cert_def_info.attribs.common_name) + subject = self.csr.subject if (amend_subject==CsrAmendMode.KEEP or not explicit_cn_is_set) else self._mk_name_attribs() validity = self.cert_def_info.validity_days or validity_days assert validity, "Validity days not set in either CSR or X509Info"