summaryrefslogtreecommitdiff
path: root/python/vyos/pki.py
diff options
context:
space:
mode:
authorAndrew Gunnerson <chillermillerlong@hotmail.com>2022-02-16 17:46:06 -0500
committerAndrew Gunnerson <chillermillerlong@hotmail.com>2022-02-17 19:00:25 -0500
commit3d1b34bf715e594aa4a013d409bfcc5a4c4ad99c (patch)
tree9f8602dde6c4f7112e96f779d788a77a5d799852 /python/vyos/pki.py
parent9e626ce7bad2bd846826822a3622fedf2d937e09 (diff)
downloadvyos-1x-3d1b34bf715e594aa4a013d409bfcc5a4c4ad99c.tar.gz
vyos-1x-3d1b34bf715e594aa4a013d409bfcc5a4c4ad99c.zip
pki: eapol: T4245: Add full CA and client cert chains to wpa_supplicant PEM files
This commit updates the eapol code so that it writes the full certificate chains for both the specified CA and the client certificate to `<iface>_ca.pem` and `<iface>_cert.pem`, respectively. The full CA chain is necessary for validating the incoming server certificate when it is signed by an intermediate CA and the intermediate CA cert is not included in the EAP-TLS ServerHello. In this scenario, wpa_supplicant needs to have both the intermediate CA and the root CA in its `ca_file`. Similarly, the full client certificate chain is needed when the ISP expects/requires that the client (wpa_supplicant) sends the client cert + the intermediate CA (or even + the root CA) as part of the EAP-TLS ClientHello. Signed-off-by: Andrew Gunnerson <chillermillerlong@hotmail.com>
Diffstat (limited to 'python/vyos/pki.py')
-rw-r--r--python/vyos/pki.py26
1 files changed, 26 insertions, 0 deletions
diff --git a/python/vyos/pki.py b/python/vyos/pki.py
index 68ad73bf2..0b916eaae 100644
--- a/python/vyos/pki.py
+++ b/python/vyos/pki.py
@@ -331,3 +331,29 @@ def verify_certificate(cert, ca_cert):
return True
except InvalidSignature:
return False
+
+# Certificate chain
+
+def find_parent(cert, ca_certs):
+ for ca_cert in ca_certs:
+ if verify_certificate(cert, ca_cert):
+ return ca_cert
+ return None
+
+def find_chain(cert, ca_certs):
+ remaining = ca_certs.copy()
+ chain = [cert]
+
+ while remaining:
+ parent = find_parent(chain[-1], remaining)
+ if parent is None:
+ # No parent in the list of remaining certificates or there's a circular dependency
+ break
+ elif parent == chain[-1]:
+ # Self-signed: must be root CA (end of chain)
+ break
+ else:
+ remaining.remove(parent)
+ chain.append(parent)
+
+ return chain