mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2026-08-11 13:34:50 -05:00
server install: fix KDC certificate validation in CA-less
Verify that the provided certificate has the extended key usage and subject alternative name required for KDC. https://pagure.io/freeipa/issue/6831 https://pagure.io/freeipa/issue/6869 Reviewed-By: Stanislav Laznicka <slaznick@redhat.com> Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
This commit is contained in:
committed by
Martin Basti
parent
cc572378a6
commit
3b5dbf7cdb
@@ -24,6 +24,7 @@ import pwd
|
||||
import grp
|
||||
import re
|
||||
import tempfile
|
||||
from tempfile import NamedTemporaryFile
|
||||
import shutil
|
||||
import base64
|
||||
|
||||
@@ -32,6 +33,7 @@ import cryptography.x509
|
||||
|
||||
from ipapython.dn import DN
|
||||
from ipapython.ipa_log_manager import root_logger
|
||||
from ipapython.kerberos import Principal
|
||||
from ipapython import ipautil
|
||||
from ipalib import x509 # pylint: disable=ipa-forbidden-import
|
||||
|
||||
@@ -179,6 +181,38 @@ def unparse_trust_flags(trust_flags):
|
||||
return trust_flags
|
||||
|
||||
|
||||
def verify_kdc_cert_validity(kdc_cert, ca_certs, realm):
|
||||
pem_kdc_cert = kdc_cert.public_bytes(serialization.Encoding.PEM)
|
||||
pem_ca_certs = '\n'.join(
|
||||
cert.public_bytes(serialization.Encoding.PEM) for cert in ca_certs)
|
||||
|
||||
with NamedTemporaryFile() as kdc_file, NamedTemporaryFile() as ca_file:
|
||||
kdc_file.write(pem_kdc_cert)
|
||||
kdc_file.flush()
|
||||
ca_file.write(pem_ca_certs)
|
||||
ca_file.flush()
|
||||
|
||||
try:
|
||||
ipautil.run(
|
||||
[OPENSSL, 'verify', '-CAfile', ca_file.name, kdc_file.name])
|
||||
eku = kdc_cert.extensions.get_extension_for_class(
|
||||
cryptography.x509.ExtendedKeyUsage)
|
||||
list(eku.value).index(
|
||||
cryptography.x509.ObjectIdentifier(x509.EKU_PKINIT_KDC))
|
||||
except (ipautil.CalledProcessError,
|
||||
cryptography.x509.ExtensionNotFound,
|
||||
ValueError):
|
||||
raise ValueError("invalid for a KDC")
|
||||
|
||||
principal = str(Principal(['krbtgt', realm], realm))
|
||||
gns = x509.process_othernames(x509.get_san_general_names(kdc_cert))
|
||||
for gn in gns:
|
||||
if isinstance(gn, x509.KRB5PrincipalName) and gn.name == principal:
|
||||
break
|
||||
else:
|
||||
raise ValueError("invalid for realm %s" % realm)
|
||||
|
||||
|
||||
class NSSDatabase(object):
|
||||
"""A general-purpose wrapper around a NSS cert database
|
||||
|
||||
@@ -692,3 +726,10 @@ class NSSDatabase(object):
|
||||
if msg == BAD_USAGE_ERR:
|
||||
msg = 'invalid for a CA.'
|
||||
raise ValueError(msg)
|
||||
|
||||
def verify_kdc_cert_validity(self, nickname, realm):
|
||||
nicknames = self.get_trust_chain(nickname)
|
||||
certs = [self.get_cert(nickname) for nickname in nicknames]
|
||||
certs = [x509.load_certificate(cert, x509.DER) for cert in certs]
|
||||
|
||||
verify_kdc_cert_validity(certs[-1], certs[:-1], realm)
|
||||
|
||||
Reference in New Issue
Block a user