diff options
| -rw-r--r-- | interface-definitions/vpn_openconnect.xml.in | 2 | ||||
| -rw-r--r-- | python/vyos/ifconfig/macsec.py | 2 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_interfaces_macsec.py | 8 | ||||
| -rwxr-xr-x | src/conf_mode/interfaces_macsec.py | 10 | ||||
| -rwxr-xr-x | src/conf_mode/pki.py | 2 | ||||
| -rwxr-xr-x | src/conf_mode/vpn_openconnect.py | 43 | ||||
| -rwxr-xr-x | src/op_mode/pki.py | 22 | 
7 files changed, 57 insertions, 32 deletions
diff --git a/interface-definitions/vpn_openconnect.xml.in b/interface-definitions/vpn_openconnect.xml.in index 7849d6886..a2f040b2f 100644 --- a/interface-definitions/vpn_openconnect.xml.in +++ b/interface-definitions/vpn_openconnect.xml.in @@ -275,7 +275,7 @@                <help>SSL Certificate, SSL Key and CA</help>              </properties>              <children> -              #include <include/pki/ca-certificate.xml.i> +              #include <include/pki/ca-certificate-multi.xml.i>                #include <include/pki/certificate-key.xml.i>              </children>            </node> diff --git a/python/vyos/ifconfig/macsec.py b/python/vyos/ifconfig/macsec.py index bde1d9aec..383905814 100644 --- a/python/vyos/ifconfig/macsec.py +++ b/python/vyos/ifconfig/macsec.py @@ -66,7 +66,7 @@ class MACsecIf(Interface):                  cmd = 'ip macsec add {ifname} rx port 1 address'.format(**self.config)                  cmd += f' {peer_config["mac"]}'                  self._cmd(cmd) -                # Add the rx-key to the address +                # Add the encryption key to the address                  cmd += f' sa 0 pn 1 on key 01 {peer_config["key"]}'                  self._cmd(cmd) diff --git a/smoketest/scripts/cli/test_interfaces_macsec.py b/smoketest/scripts/cli/test_interfaces_macsec.py index a4e6840ca..d73895b7f 100755 --- a/smoketest/scripts/cli/test_interfaces_macsec.py +++ b/smoketest/scripts/cli/test_interfaces_macsec.py @@ -225,11 +225,11 @@ class MACsecInterfaceTest(BasicInterfaceTest.TestCase):              self.cli_commit()          self.cli_delete(self._base_path + [interface, 'security', 'mka']) -        # check validate() - tx-key required +        # check validate() - key required          with self.assertRaises(ConfigSessionError):              self.cli_commit() -        # check validate() - tx-key length must match cipher +        # check validate() - key length must match cipher          self.cli_set(self._base_path + [interface, 'security', 'static', 'key', tx_key_2])          with self.assertRaises(ConfigSessionError):              self.cli_commit() @@ -239,7 +239,7 @@ class MACsecInterfaceTest(BasicInterfaceTest.TestCase):          with self.assertRaises(ConfigSessionError):              self.cli_commit() -        # check validate() - enabled peer must have both rx-key and MAC defined +        # check validate() - enabled peer must have both key and MAC defined          self.cli_set(self._base_path + [interface, 'security', 'static', 'peer', 'TESTPEER'])          with self.assertRaises(ConfigSessionError):              self.cli_commit() @@ -252,7 +252,7 @@ class MACsecInterfaceTest(BasicInterfaceTest.TestCase):              self.cli_commit()          self.cli_set(self._base_path + [interface, 'security', 'static', 'peer', 'TESTPEER', 'mac', peer_mac]) -        # check validate() - peer rx-key length must match cipher +        # check validate() - peer key length must match cipher          self.cli_set(self._base_path + [interface, 'security', 'cipher', cipher2])          self.cli_set(self._base_path + [interface, 'security', 'static', 'key', tx_key_2])          with self.assertRaises(ConfigSessionError): diff --git a/src/conf_mode/interfaces_macsec.py b/src/conf_mode/interfaces_macsec.py index eb0ca9a8b..3ede4377a 100755 --- a/src/conf_mode/interfaces_macsec.py +++ b/src/conf_mode/interfaces_macsec.py @@ -103,9 +103,9 @@ def verify(macsec):          # Logic to check static configuration          if dict_search('security.static', macsec) != None: -            # tx-key must be defined +            # key must be defined              if dict_search('security.static.key', macsec) == None: -                raise ConfigError('Static MACsec tx-key must be defined.') +                raise ConfigError('Static MACsec key must be defined.')              tx_len = len(dict_search('security.static.key', macsec)) @@ -119,12 +119,12 @@ def verify(macsec):              if 'peer' not in macsec['security']['static']:                  raise ConfigError('Must have at least one peer defined for static MACsec') -            # For every enabled peer, make sure a MAC and rx-key is defined +            # For every enabled peer, make sure a MAC and key is defined              for peer, peer_config in macsec['security']['static']['peer'].items():                  if 'disable' not in peer_config and ('mac' not in peer_config or 'key' not in peer_config): -                    raise ConfigError('Every enabled MACsec static peer must have a MAC address and rx-key defined.') +                    raise ConfigError('Every enabled MACsec static peer must have a MAC address and key defined!') -                # check rx-key length against cipher suite +                # check key length against cipher suite                  rx_len = len(peer_config['key'])                  if dict_search('security.cipher', macsec) == 'gcm-aes-128' and rx_len != GCM_AES_128_LEN: diff --git a/src/conf_mode/pki.py b/src/conf_mode/pki.py index f37cac524..4a0e86f32 100755 --- a/src/conf_mode/pki.py +++ b/src/conf_mode/pki.py @@ -232,7 +232,7 @@ def get_config(config=None):                          path = search['path']                          path_str = ' '.join(path + found_path) -                        print(f'PKI: Updating config: {path_str} {item_name}') +                        #print(f'PKI: Updating config: {path_str} {item_name}')                          if path[0] == 'interfaces':                              ifname = found_path[0] diff --git a/src/conf_mode/vpn_openconnect.py b/src/conf_mode/vpn_openconnect.py index 8159fedea..42785134f 100755 --- a/src/conf_mode/vpn_openconnect.py +++ b/src/conf_mode/vpn_openconnect.py @@ -21,14 +21,17 @@ from vyos.base import Warning  from vyos.config import Config  from vyos.configverify import verify_pki_certificate  from vyos.configverify import verify_pki_ca_certificate -from vyos.pki import wrap_certificate +from vyos.pki import find_chain +from vyos.pki import encode_certificate +from vyos.pki import load_certificate  from vyos.pki import wrap_private_key  from vyos.template import render -from vyos.utils.process import call +from vyos.utils.dict import dict_search +from vyos.utils.file import write_file  from vyos.utils.network import check_port_availability -from vyos.utils.process import is_systemd_service_running  from vyos.utils.network import is_listen_port_bind_service -from vyos.utils.dict import dict_search +from vyos.utils.process import call +from vyos.utils.process import is_systemd_service_running  from vyos import ConfigError  from passlib.hash import sha512_crypt  from time import sleep @@ -142,7 +145,8 @@ def verify(ocserv):      verify_pki_certificate(ocserv, ocserv['ssl']['certificate'])      if 'ca_certificate' in ocserv['ssl']: -        verify_pki_ca_certificate(ocserv, ocserv['ssl']['ca_certificate']) +        for ca_cert in ocserv['ssl']['ca_certificate']: +            verify_pki_ca_certificate(ocserv, ca_cert)      # Check network settings      if "network_settings" in ocserv: @@ -219,25 +223,36 @@ def generate(ocserv):      if "ssl" in ocserv:          cert_file_path = os.path.join(cfg_dir, 'cert.pem')          cert_key_path = os.path.join(cfg_dir, 'cert.key') -        ca_cert_file_path = os.path.join(cfg_dir, 'ca.pem') +          if 'certificate' in ocserv['ssl']:              cert_name = ocserv['ssl']['certificate']              pki_cert = ocserv['pki']['certificate'][cert_name] -            with open(cert_file_path, 'w') as f: -                f.write(wrap_certificate(pki_cert['certificate'])) +            loaded_pki_cert = load_certificate(pki_cert['certificate']) +            loaded_ca_certs = {load_certificate(c['certificate']) +                for c in ocserv['pki']['ca'].values()} if 'ca' in ocserv['pki'] else {} + +            cert_full_chain = find_chain(loaded_pki_cert, loaded_ca_certs) + +            write_file(cert_file_path, +                '\n'.join(encode_certificate(c) for c in cert_full_chain))              if 'private' in pki_cert and 'key' in pki_cert['private']: -                with open(cert_key_path, 'w') as f: -                    f.write(wrap_private_key(pki_cert['private']['key'])) +                write_file(cert_key_path, wrap_private_key(pki_cert['private']['key']))          if 'ca_certificate' in ocserv['ssl']: -            ca_name = ocserv['ssl']['ca_certificate'] -            pki_ca_cert = ocserv['pki']['ca'][ca_name] +            ca_cert_file_path = os.path.join(cfg_dir, 'ca.pem') +            ca_chains = [] + +            for ca_name in ocserv['ssl']['ca_certificate']: +                pki_ca_cert = ocserv['pki']['ca'][ca_name] +                loaded_ca_cert = load_certificate(pki_ca_cert['certificate']) +                ca_full_chain = find_chain(loaded_ca_cert, loaded_ca_certs) +                ca_chains.append( +                    '\n'.join(encode_certificate(c) for c in ca_full_chain)) -            with open(ca_cert_file_path, 'w') as f: -                f.write(wrap_certificate(pki_ca_cert['certificate'])) +            write_file(ca_cert_file_path, '\n'.join(ca_chains))      # Render config      render(ocserv_conf, 'ocserv/ocserv_config.j2', ocserv) diff --git a/src/op_mode/pki.py b/src/op_mode/pki.py index 361b60e0e..9ce166c7d 100755 --- a/src/op_mode/pki.py +++ b/src/op_mode/pki.py @@ -426,11 +426,15 @@ def generate_ca_certificate_sign(name, ca_name, install=False, file=False):          return None      cert = generate_certificate(cert_req, ca_cert, ca_private_key, is_ca=True, is_sub_ca=True) -    passphrase = ask_passphrase() + +    passphrase = None +    if private_key is not None: +        passphrase = ask_passphrase()      if not install and not file:          print(encode_certificate(cert)) -        print(encode_private_key(private_key, passphrase=passphrase)) +        if private_key is not None: +            print(encode_private_key(private_key, passphrase=passphrase))          return None      if install: @@ -438,7 +442,8 @@ def generate_ca_certificate_sign(name, ca_name, install=False, file=False):      if file:          write_file(f'{name}.pem', encode_certificate(cert)) -        write_file(f'{name}.key', encode_private_key(private_key, passphrase=passphrase)) +        if private_key is not None: +            write_file(f'{name}.key', encode_private_key(private_key, passphrase=passphrase))  def generate_certificate_sign(name, ca_name, install=False, file=False):      ca_dict = get_config_ca_certificate(ca_name) @@ -492,11 +497,15 @@ def generate_certificate_sign(name, ca_name, install=False, file=False):          return None      cert = generate_certificate(cert_req, ca_cert, ca_private_key, is_ca=False) -    passphrase = ask_passphrase() +     +    passphrase = None +    if private_key is not None: +        passphrase = ask_passphrase()      if not install and not file:          print(encode_certificate(cert)) -        print(encode_private_key(private_key, passphrase=passphrase)) +        if private_key is not None: +            print(encode_private_key(private_key, passphrase=passphrase))          return None      if install: @@ -504,7 +513,8 @@ def generate_certificate_sign(name, ca_name, install=False, file=False):      if file:          write_file(f'{name}.pem', encode_certificate(cert)) -        write_file(f'{name}.key', encode_private_key(private_key, passphrase=passphrase)) +        if private_key is not None: +            write_file(f'{name}.key', encode_private_key(private_key, passphrase=passphrase))  def generate_certificate_selfsign(name, install=False, file=False):      private_key, key_type = generate_private_key()  | 
