Source code for cert_chain_resolver.cli

import argparse
import ssl
import sys
from typing import Optional
from cert_chain_resolver.resolver import resolve
from cert_chain_resolver import __is_py3__
from cert_chain_resolver.castore.file_system import FileSystemStore

try:
    from typing import Optional
    from cert_chain_resolver.castore.base_store import CAStore
except ImportError:  # pragma: no cover
    pass


def _print_chain_details(chain, include_root):
    for index, cert in enumerate(chain, 1):
        print("== Certificate #{0} ==".format(index))
        print("Subject:".ljust(20) + cert.subject)
        print("Issuer:".ljust(20) + cert.issuer)
        print("NotBefore:".ljust(20) + cert.not_valid_before.isoformat())
        print("NotAfter:".ljust(20) + cert.not_valid_after.isoformat())
        print("Serial:".ljust(20) + str(cert.serial))
        print("Sha256Fingeprint:".ljust(20) + str(cert.fingerprint))
        print(
            "CAIssuerLoc:".ljust(20) + cert.ca_issuer_access_location
            if cert.ca_issuer_access_location
            else ""
        )
        print("Is root:".ljust(20) + repr(cert.is_root))
        print("Is CA:".ljust(20) + repr(cert.is_ca))
        print("Domains:")
        print("  Common name:".ljust(20) + cert.common_name)
        if cert.subject_alternative_names:
            print("  SANExtensions:")
            for domain in cert.subject_alternative_names:
                print("    " + domain)
        print("")

    if include_root and not chain.root:
        sys.stderr.write("WARNING: Root certificate was requested, but not found!\n")


[docs] def cli(file_bytes, show_details=False, include_root=False, root_ca_store=None): # type: (bytes, bool, bool, Optional[CAStore]) -> None chain = resolve(file_bytes, root_ca_store=root_ca_store) if show_details: _print_chain_details(chain, include_root=include_root) else: root = [chain.root] if chain.root and include_root else [] for c in [chain.leaf] + list(chain.intermediates) + root: sys.stdout.write(c.export()) for i, c in enumerate([chain.leaf] + list(chain.intermediates) + root, 1): sys.stderr.write(str(i) + ". " + repr(c) + "\n") if not root and include_root: sys.stderr.write( str(i + 1) + ". Root certificate was requested, but not found!\n" ) if not root_ca_store: sys.stderr.write( "Consider running the CLI with --use-certifi-store to find the matching root CA\n" )
[docs] def parse_args(): parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=""" Resolve / obtain the certificate intermediates of given x509 certificate. This tool writes the full bundle to stdout. Examples: Using a file: $ cert_chain_resolver certificate.crt > bundle.crt Using stdin: $ cat certificate.crt | cert_chain_resolver > bundle.crt """, ) parser.add_argument( "file_name", nargs="?", default="-", type=str, help="file formatted as PEM", ) parser.add_argument( "-i", "--info", action="store_true", help="Print chain derived information" ) parser.add_argument( "--include-root", action="store_true", help="Include root certificate in the chain if available", ) parser.add_argument( "--ca-bundle-path", type=str, default=None, help="Use a custom CA bundle for completing the chain", ) return parser.parse_args()
[docs] def main(): if sys.stdin.isatty() and len(sys.argv) == 1: sys.argv += ["-h"] args = parse_args() cli_args = { "file_bytes": None, "show_details": args.info, "include_root": args.include_root, } cli_args["root_ca_store"] = FileSystemStore(args.ca_bundle_path) if args.file_name == "-": source = None if __is_py3__: source = sys.stdin.buffer else: source = sys.stdin cli_args["file_bytes"] = source.read() else: with open(args.file_name, "rb") as f: cli_args["file_bytes"] = f.read() cli(**cli_args)
if __name__ == "__main__": # pragma: no cover main()