summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsarthurdev <965089+sarthurdev@users.noreply.github.com>2022-06-29 02:28:00 +0200
committersarthurdev <965089+sarthurdev@users.noreply.github.com>2022-06-29 17:13:53 +0200
commitefd956f912b84c8df8902d56e16f22cbd90efdd0 (patch)
treebba35e415994343ebd7fec756417fb5176fa88c2
parent0d5ac59894ae7c10bd9d69047fa7098de66f835f (diff)
downloadvyos-1x-efd956f912b84c8df8902d56e16f22cbd90efdd0.tar.gz
vyos-1x-efd956f912b84c8df8902d56e16f22cbd90efdd0.zip
openvpn: T4485: Update PKI migrator to handle full CA chain migration
* Also determines and maps to correct CA for migrated CRL
-rw-r--r--python/vyos/pki.py29
-rw-r--r--smoketest/configs/dialup-router-medium-vpn4
-rwxr-xr-xsrc/migration-scripts/interfaces/24-to-2537
3 files changed, 58 insertions, 12 deletions
diff --git a/python/vyos/pki.py b/python/vyos/pki.py
index 648064a3a..cd15e3878 100644
--- a/python/vyos/pki.py
+++ b/python/vyos/pki.py
@@ -332,6 +332,35 @@ def verify_certificate(cert, ca_cert):
except InvalidSignature:
return False
+def verify_crl(crl, ca_cert):
+ # Verify CRL was signed by specified CA
+ if ca_cert.subject != crl.issuer:
+ return False
+
+ ca_public_key = ca_cert.public_key()
+ try:
+ if isinstance(ca_public_key, rsa.RSAPublicKeyWithSerialization):
+ ca_public_key.verify(
+ crl.signature,
+ crl.tbs_certlist_bytes,
+ padding=padding.PKCS1v15(),
+ algorithm=crl.signature_hash_algorithm)
+ elif isinstance(ca_public_key, dsa.DSAPublicKeyWithSerialization):
+ ca_public_key.verify(
+ crl.signature,
+ crl.tbs_certlist_bytes,
+ algorithm=crl.signature_hash_algorithm)
+ elif isinstance(ca_public_key, ec.EllipticCurvePublicKeyWithSerialization):
+ ca_public_key.verify(
+ crl.signature,
+ crl.tbs_certlist_bytes,
+ signature_algorithm=ec.ECDSA(crl.signature_hash_algorithm))
+ else:
+ return False # We cannot verify it
+ return True
+ except InvalidSignature:
+ return False
+
def verify_ca_chain(sorted_names, pki_node):
if len(sorted_names) == 1: # Single cert, no chain
return True
diff --git a/smoketest/configs/dialup-router-medium-vpn b/smoketest/configs/dialup-router-medium-vpn
index 63d955738..fb8ed2714 100644
--- a/smoketest/configs/dialup-router-medium-vpn
+++ b/smoketest/configs/dialup-router-medium-vpn
@@ -120,7 +120,7 @@ interfaces {
persistent-tunnel
remote-host 192.0.2.10
tls {
- ca-cert-file /config/auth/ovpn_test_ca.pem
+ ca-cert-file /config/auth/ovpn_test_chain.pem
cert-file /config/auth/ovpn_test_server.pem
key-file /config/auth/ovpn_test_server.key
auth-file /config/auth/ovpn_test_tls_auth.key
@@ -152,7 +152,7 @@ interfaces {
remote-host 01.foo.com
remote-port 1194
tls {
- ca-cert-file /config/auth/ovpn_test_ca.pem
+ ca-cert-file /config/auth/ovpn_test_chain.pem
auth-file /config/auth/ovpn_test_tls_auth.key
}
}
diff --git a/src/migration-scripts/interfaces/24-to-25 b/src/migration-scripts/interfaces/24-to-25
index 93ce9215f..4095f2a3e 100755
--- a/src/migration-scripts/interfaces/24-to-25
+++ b/src/migration-scripts/interfaces/24-to-25
@@ -20,6 +20,7 @@
import os
import sys
from vyos.configtree import ConfigTree
+from vyos.pki import CERT_BEGIN
from vyos.pki import load_certificate
from vyos.pki import load_crl
from vyos.pki import load_dh_parameters
@@ -27,6 +28,7 @@ from vyos.pki import load_private_key
from vyos.pki import encode_certificate
from vyos.pki import encode_dh_parameters
from vyos.pki import encode_private_key
+from vyos.pki import verify_crl
from vyos.util import run
def wrapped_pem_to_config_value(pem):
@@ -129,6 +131,8 @@ if config.exists(base):
config.delete(base + [interface, 'tls', 'crypt-file'])
+ ca_certs = {}
+
if config.exists(x509_base + ['ca-cert-file']):
if not config.exists(pki_base + ['ca']):
config.set(pki_base + ['ca'])
@@ -136,20 +140,27 @@ if config.exists(base):
cert_file = config.return_value(x509_base + ['ca-cert-file'])
cert_path = os.path.join(AUTH_DIR, cert_file)
- cert = None
if os.path.isfile(cert_path):
if not os.access(cert_path, os.R_OK):
run(f'sudo chmod 644 {cert_path}')
with open(cert_path, 'r') as f:
- cert_data = f.read()
- cert = load_certificate(cert_data, wrap_tags=False)
-
- if cert:
- cert_pem = encode_certificate(cert)
- config.set(pki_base + ['ca', pki_name, 'certificate'], value=wrapped_pem_to_config_value(cert_pem))
- config.set(x509_base + ['ca-certificate'], value=pki_name)
+ certs_str = f.read()
+ certs_data = certs_str.split(CERT_BEGIN)
+ index = 1
+ for cert_data in certs_data[1:]:
+ cert = load_certificate(CERT_BEGIN + cert_data, wrap_tags=False)
+
+ if cert:
+ ca_certs[f'{pki_name}_{index}'] = cert
+ cert_pem = encode_certificate(cert)
+ config.set(pki_base + ['ca', f'{pki_name}_{index}', 'certificate'], value=wrapped_pem_to_config_value(cert_pem))
+ config.set(x509_base + ['ca-certificate'], value=f'{pki_name}_{index}', replace=False)
+ else:
+ print(f'Failed to migrate CA certificate on openvpn interface {interface}')
+
+ index += 1
else:
print(f'Failed to migrate CA certificate on openvpn interface {interface}')
@@ -163,6 +174,7 @@ if config.exists(base):
crl_file = config.return_value(x509_base + ['crl-file'])
crl_path = os.path.join(AUTH_DIR, crl_file)
crl = None
+ crl_ca_name = None
if os.path.isfile(crl_path):
if not os.access(crl_path, os.R_OK):
@@ -172,9 +184,14 @@ if config.exists(base):
crl_data = f.read()
crl = load_crl(crl_data, wrap_tags=False)
- if crl:
+ for ca_name, ca_cert in ca_certs.items():
+ if verify_crl(crl, ca_cert):
+ crl_ca_name = ca_name
+ break
+
+ if crl and crl_ca_name:
crl_pem = encode_certificate(crl)
- config.set(pki_base + ['ca', pki_name, 'crl'], value=wrapped_pem_to_config_value(crl_pem))
+ config.set(pki_base + ['ca', crl_ca_name, 'crl'], value=wrapped_pem_to_config_value(crl_pem))
else:
print(f'Failed to migrate CRL on openvpn interface {interface}')