From 13bf2285aa7217c97b3e6d48c225e43ea37f5f2a Mon Sep 17 00:00:00 2001 From: Remco Koopmans Date: Thu, 1 Aug 2024 18:25:20 +0200 Subject: [PATCH] Update docs --- CHANGELOG.md | 21 +++++++++-------- README.md | 40 ++++++++++++++++++++------------- cert_chain_resolver/api.py | 1 + cert_chain_resolver/resolver.py | 2 +- docs/api.rst | 17 +++++++++----- docs/cert_chain_resolver.rst | 13 ----------- docs/cli_usage.rst | 8 +++---- requirements_dev.txt | 3 +-- 8 files changed, 52 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f33e76..18d52da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,17 +3,16 @@ ## 1.3.0 New feature and sane defaults. for the CLI the root is now by default excluded, at first it would include it if it found one, but not all certificate authorities provide a link to their root in their certs. This resulted in sometimes a root to be included and othertimes not. - -### cli -* Root certificate is excluded by default -* Display a warning when root is requested, but not available -* New flags - * --include-root (for including the root in the output IF AVAILABLE) - * --use-store-certifi (Find the matching root certificate using the [certifi](https://github.com/certifi/python-certifi) library) - -### API -* New option for the resolve() api, it can now find the root certificate using the certifi library - resolve(cert_pem, use_ca_store=CertifiStore()) +* CLI + * Root certificate is excluded by default + * Display a warning when root is requested, but not available + * New flags + * --include-root (for including the root in the output IF AVAILABLE) + * --ca-bundle-path (Find the matching root certificate using a custom path) + +* API + * New option for the resolve() api, it can now find the root certificate using a file system bundle + resolve(cert_pem, root_ca_store=FileSystemStore('/optional/path/to/bundle.pem')) ## 1.2.1 * prevent infinite recursion caused by certificate self-referencing in ca_issuer_access_location (Thanks @trgalho) diff --git a/README.md b/README.md index 80be833..44b9f1d 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,27 @@ Resolve / obtain the certificate intermediates and root of a x509 certificate using the CLI or python API. The CLI provides easy access to a certificate bundle and its metadata while the Python API can be used to inspect, iterate and complete certificate bundles. + +## Minimal shell + +Read more about the shell usage on [read the docs](https://certificate-resolver.readthedocs.io/en/latest/cli_usage.html) + +``` + $ cert_chain_resolver certificate.crt > bundle.crt + 1. + 2. + 3. +``` + +## Minimal python + +Read more regarding the python API on [read the docs](https://certificate-resolver.readthedocs.io/en/latest/api.html) ``` from cert_chain_resolver.api import resolve -from cert_chain_resolver.root.certifi import CertifiStore with open('cert.pem', 'rb') as f: fb = f.read() - chain = resolve(fb, include_root=True, root_ca_store=CertifiStore()) + chain = resolve(fb) >>> for cert in chain: print(cert) @@ -26,36 +40,26 @@ for cert in chain: ``` +## + ## Support * PKCS7, PEM and DER formats * LetsEncrypt certificates -* Resolving the root certificate through a CA Bundle +* Resolving the root certificate through an auto detected OR chosen CA bundle ## Dependencies * cryptography -## Documentation - -Read more on [readthedocs](https://certificate-resolver.readthedocs.io/en/latest/) - ## Install [Pypi](https://pypi.org/project/cert-chain-resolver/) - - Core package $ pip install cert-chain-resolver - -With certifi support for finding the matching root certificate - - $ pip install cert-chain-resolver[certifi] - - ## Usage ### Installed using PIP @@ -66,7 +70,11 @@ Resolve without helpers, just the leaf and intermediates: Resolve complete chain up to the root: - $ cert_chain_resolver certificate.crt --include-root --use-store-certifi > bundle.crt + $ cert_chain_resolver certificate.crt --include-root > bundle.crt + +Resolve complete chain with your own root bundle: + + $ cert_chain_resolver certificate.crt --include-root --ca-bundle-path /path/to/bundle.pem > bundle.crt Or read from stdin diff --git a/cert_chain_resolver/api.py b/cert_chain_resolver/api.py index 4cc3687..a8aabb0 100644 --- a/cert_chain_resolver/api.py +++ b/cert_chain_resolver/api.py @@ -1,2 +1,3 @@ from cert_chain_resolver.resolver import resolve from cert_chain_resolver.models import CertificateChain, Cert +from cert_chain_resolver.castore.file_system import FileSystemStore diff --git a/cert_chain_resolver/resolver.py b/cert_chain_resolver/resolver.py index 0717347..33c3a43 100644 --- a/cert_chain_resolver/resolver.py +++ b/cert_chain_resolver/resolver.py @@ -34,7 +34,7 @@ def resolve(bytes_cert, _chain=None, root_ca_store=None): Args: bytes_cert: A DER/PKCS7/PEM certificate _chain: Chain to complete. Defaults to None. - use_ca_store: A CAStore to use for completing the chain with a root certificate in case + root_ca_store: A CAStore to use for completing the chain with a root certificate in case the intermediates do not provide a location Returns: diff --git a/docs/api.rst b/docs/api.rst index 0a78a10..6ac6c25 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -41,21 +41,28 @@ This will print each certificate in the chain, starting with the leaf and ending Advanced Usage ============== -Using the certifi CA Store for resolving root certs +Using the System CA Store or own bundle for resolving root certs --------------------------------------------------- -Not all intermediates provide a resolvable path, but we can create the path by matching it with our own CA bundle +Not all CA intermediates provide a web traversable path to the root certificate. Therefore we need to find the root ourselves if we want to have the complete chain of trust. .. code-block:: python - from cert_chain_resolver.api import resolve - from cert_chain_resolver.root.certifi import CertifiStore + from cert_chain_resolver.api import resolve, FileSystemStore # Load your certificate with open('cert.pem', 'rb') as f: file_bytes = f.read() - chain = resolve(file_bytes, root_ca_store=CertifiStore()) + # Will try to find the root bundle on your systemm will raise if it cannot be found + chain = resolve(file_bytes, root_ca_store=FileSystemStore()) + + # We set our own bundle location + chain = resolve(file_bytes, root_ca_store=FileSystemStore('/etc/cabundles/mine.pem')) + + # We leverage certifi for a trusted root bundle + import certifi + chain = resolve(file_bytes, root_ca_store=FileSystemStore(certifi.where())) for cert in chain: print(cert) diff --git a/docs/cert_chain_resolver.rst b/docs/cert_chain_resolver.rst index 64f8c13..bc815d4 100644 --- a/docs/cert_chain_resolver.rst +++ b/docs/cert_chain_resolver.rst @@ -29,19 +29,6 @@ cert\_chain\_resolver.utils module :undoc-members: :show-inheritance: -cert\_chain\_resolver.root module ----------------------------------- - -.. automodule:: cert_chain_resolver.root.base_store - :members: - :undoc-members: - :show-inheritance: - -.. automodule:: cert_chain_resolver.root.certifi - :members: - :undoc-members: - :show-inheritance: - cert\_chain\_resolver.cli module -------------------------------- diff --git a/docs/cli_usage.rst b/docs/cli_usage.rst index ee62a2e..6ac6c1d 100644 --- a/docs/cli_usage.rst +++ b/docs/cli_usage.rst @@ -40,7 +40,7 @@ The `cert_chain_resolver` CLI supports several options to customize its behavior - ``-i``, ``--info``: Print detailed information about each certificate in the chain. - ``--include-root``: Include the root certificate in the output if it is available in the chain. -- ``--use-store-certifi``: Use the Certifi package's CA bundle as the root certificate store for completing the chain. +- ``--ca-bundle-path CA_BUNDLE_PATH``: Use your own CA bundle as the root certificate store for completing the chain. By default this tries to pick your system CA bundle. Each option can be combined to tailor the output to your specific needs. @@ -63,10 +63,8 @@ Examples with Options If the root certificate is available, it will be included in the output file. -3. **Use Certifi CA Store**: +3. **Use System CA Store**: .. code-block:: bash - $ cert_chain_resolver --include-root --use-store-certifi certificate.crt > bundle.crt - - This uses the widely trusted `Certifi `_ python package that contains a curated list of trusted CA's. This is needed when an intermediate certificate does not contain information on where to retrieve the certificate. + $ cert_chain_resolver --include-root --ca-bundle-path /path/to/own/bundle.pem certificate.crt > bundle.crt diff --git a/requirements_dev.txt b/requirements_dev.txt index ee10999..849eed9 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -3,5 +3,4 @@ twine pytest-mock pytest pytest-xdist -pytest-cov -black \ No newline at end of file +pytest-cov \ No newline at end of file