Fix Linux CA trust detection

This commit is contained in:
PK3NZO
2026-04-21 16:41:48 +03:30
parent 9f587da40f
commit 04f8d44435
+55 -15
View File
@@ -250,28 +250,68 @@ def _install_linux(cert_path: str, cert_name: str) -> bool:
return installed
def _is_trusted_linux(cert_path: str) -> bool:
"""Check if our cert thumbprint is in the system's OpenSSL trust bundle."""
thumbprint = _cert_thumbprint(cert_path)
if not thumbprint:
def _is_trusted_linux(cert_path: str, cert_name: str = CERT_NAME) -> bool:
"""Check whether the cert appears in common Linux trust stores."""
try:
from cryptography import x509 as _x509
from cryptography.hazmat.primitives import hashes as _hashes
except Exception:
return False
bundle_paths = [
"/etc/ssl/certs/ca-certificates.crt", # Debian/Ubuntu
"/etc/pki/tls/certs/ca-bundle.crt", # RHEL/Fedora
"/etc/ssl/ca-bundle.pem", # OpenSUSE
"/etc/ca-certificates/ca-certificates.crt",
]
# A fast heuristic: check if our CA cert file was copied to known dirs
try:
with open(cert_path, "rb") as f:
target_cert = _x509.load_pem_x509_certificate(f.read())
target_fp = target_cert.fingerprint(_hashes.SHA1())
except Exception:
return False
# First check the common anchor locations used by the installer.
expected_name = f"{cert_name.replace(' ', '_')}.crt"
anchor_dirs = [
"/usr/local/share/ca-certificates",
"/etc/pki/ca-trust/source/anchors",
"/etc/ca-certificates/trust-source/anchors",
]
for d in anchor_dirs:
if os.path.isdir(d):
for f in os.listdir(d):
if "DomainFront" in f or "domainfront" in f.lower():
try:
if not os.path.isdir(d):
continue
if expected_name in os.listdir(d):
return True
except OSError:
pass
# Fall back to scanning the system bundle files directly.
bundle_paths = [
"/etc/ssl/certs/ca-certificates.crt", # Debian/Ubuntu
"/etc/pki/tls/certs/ca-bundle.crt", # RHEL/Fedora
"/etc/ssl/ca-bundle.pem", # OpenSUSE
"/etc/ca-certificates/ca-certificates.crt",
]
begin = b"-----BEGIN CERTIFICATE-----"
end = b"-----END CERTIFICATE-----"
for bundle in bundle_paths:
try:
with open(bundle, "rb") as f:
data = f.read()
except OSError:
continue
for chunk in data.split(begin):
if end not in chunk:
continue
pem = begin + chunk.split(end, 1)[0] + end + b"\n"
try:
cert = _x509.load_pem_x509_certificate(pem)
except Exception:
continue
try:
if cert.fingerprint(_hashes.SHA1()) == target_fp:
return True
except Exception:
continue
return False
@@ -330,7 +370,7 @@ def is_ca_trusted(cert_path: str) -> bool:
return _is_trusted_windows(cert_path)
if system == "Darwin":
return _is_trusted_macos(CERT_NAME)
return _is_trusted_linux(cert_path)
return _is_trusted_linux(cert_path, CERT_NAME)
except Exception:
return False