diff options
| author | Daniil Baturin <daniil@vyos.io> | 2026-06-15 18:02:24 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-06-15 18:02:24 +0100 |
| commit | 4fb32bc179127691f40c8e93c55877aa76f10416 (patch) | |
| tree | 306baf3c01a538328c1a2d0508002f37c79637cd /src | |
| parent | 62e5ca63f15809408bfcb8f10332d5b771622a4e (diff) | |
| parent | b27b74433a594a3c3b799b31db208da5bac8dd80 (diff) | |
| download | vyos-1x-4fb32bc179127691f40c8e93c55877aa76f10416.tar.gz vyos-1x-4fb32bc179127691f40c8e93c55877aa76f10416.zip | |
Merge pull request #5225 from indrajitr/T8165-pki-private-bundle
pki: T8165: Add ability to show certificate full chain in pem format
Diffstat (limited to 'src')
| -rwxr-xr-x | src/op_mode/pki.py | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/src/op_mode/pki.py b/src/op_mode/pki.py index bf8bba657..482dc91af 100755 --- a/src/op_mode/pki.py +++ b/src/op_mode/pki.py @@ -33,6 +33,7 @@ from vyos.pki import encode_certificate from vyos.pki import encode_public_key from vyos.pki import encode_private_key from vyos.pki import encode_dh_parameters +from vyos.pki import find_chain from vyos.pki import get_certificate_fingerprint from vyos.pki import create_certificate from vyos.pki import create_certificate_request @@ -84,6 +85,23 @@ def _verify(target): return _verify_target +def _encode_certificate_chain(cert, ca_certs): + """Encode a certificate together with its parent CA hierarchy into a single + PEM-encoded buffer ordered beginning with the end entity (leaf) certificate, + followed by the issuer certificates. + """ + loaded_ca_certs = [] + if ca_certs: + for ca_dict in ca_certs.values(): + if 'certificate' not in ca_dict: + continue + ca_cert = load_certificate(ca_dict['certificate']) + if ca_cert: + loaded_ca_certs.append(ca_cert) + + return ''.join(encode_certificate(c) for c in find_chain(cert, loaded_ca_certs)) + + def get_default_values(): # Fetch default x509 values base = ['pki', 'x509', 'default'] @@ -1192,7 +1210,10 @@ def import_pki( @_verify('ca') def show_certificate_authority( - raw: bool, name: typing.Optional[str] = None, pem: typing.Optional[bool] = False + raw: bool, + name: typing.Optional[str] = None, + pem: typing.Optional[bool] = False, + full_chain: typing.Optional[bool] = False, ): headers = [ 'Name', @@ -1214,8 +1235,14 @@ def show_certificate_authority( cert = load_certificate(cert_dict['certificate']) + if not cert: + continue + if name and pem: - print(encode_certificate(cert)) + if full_chain: + print(_encode_certificate_chain(cert, certs)) + else: + print(encode_certificate(cert)) return parent_ca_name = get_certificate_ca(cert, certs) @@ -1224,9 +1251,6 @@ def show_certificate_authority( if not parent_ca_name or parent_ca_name == cert_name: parent_ca_name = 'N/A' - if not cert: - continue - have_private = ( 'Yes' if 'private' in cert_dict and 'key' in cert_dict['private'] @@ -1254,6 +1278,7 @@ def show_certificate( name: typing.Optional[str] = None, private: typing.Optional[bool] = False, pem: typing.Optional[bool] = False, + full_chain: typing.Optional[bool] = False, fingerprint: typing.Optional[ArgsFingerprint] = None, ): headers = [ @@ -1284,7 +1309,10 @@ def show_certificate( continue if name and pem and not (private or fingerprint): - print(encode_certificate(cert)) + if full_chain: + print(_encode_certificate_chain(cert, ca_certs)) + else: + print(encode_certificate(cert)) return elif name and fingerprint and not private: print(get_certificate_fingerprint(cert, fingerprint)) @@ -1298,13 +1326,19 @@ def show_certificate( wrap_tags=True, ) if private_key: - print(encode_private_key(private_key, passphrase=None)) + priv_pem = encode_private_key(private_key, passphrase=None) + if pem and full_chain: + print(_encode_certificate_chain(cert, ca_certs) + priv_pem) + else: + print(priv_pem) + return else: if protected: print(f'Private key for certificate "{cert_name}" is ' 'password-protected and cannot be displayed') else: - print(f'Failed to load private key for certificate "{cert_name}"') + print('Failed to load private key for certificate ' + f'"{cert_name}"') else: print(f'No private key found for certificate "{cert_name}"') return @@ -1394,6 +1428,7 @@ def show_all(raw: bool): print('\n') show_crl(raw) + def renew_certbot(raw: bool, force: typing.Optional[bool] = False): from vyos.defaults import directories @@ -1406,7 +1441,7 @@ def renew_certbot(raw: bool, force: typing.Optional[bool] = False): # Re-run CLI PKI helper to initially request certificates via ACME # again. This should never be the case - but sometimes the universe has # a bad time - Warning(f'Directory "{certbot_config}" missing. Reinitializing PKI ' \ + Warning(f'Directory "{certbot_config}" missing. Reinitializing PKI ' 'subsystem...\n\n') out = cmd(f'sudo sg vyattacfg -c "{vyos_conf_scripts_dir}/pki.py"') elif force: @@ -1416,6 +1451,7 @@ def renew_certbot(raw: bool, force: typing.Optional[bool] = False): print(out) + if __name__ == '__main__': try: res = vyos.opmode.run(sys.modules[__name__]) |
