From d15740d3e9975bc26decdfe2f00a2baa0bdff8ae Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Thu, 30 Sep 2021 15:21:17 -0400 Subject: [PATCH 01/47] docs: update docs with a _little_ more detail --- CHANGELOG.md | 10 +++++++++- README.md | 14 +++++++++++++- checkcert.py | 8 -------- 3 files changed, 22 insertions(+), 10 deletions(-) delete mode 100755 checkcert.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 97cd662..043fd24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,15 @@ # Changelog -## Unreleased (2021-09-28) +## v0.2.0 (2021-09-30) #### New Features +* add color output for validity check of cert * add option to display the text version of the x509 cert +#### Fixes + +* remove duplication of output +#### Others + +* add base coverage for all functions +* add initial test cases diff --git a/README.md b/README.md index 1b44416..a03fa5a 100644 --- a/README.md +++ b/README.md @@ -1 +1,13 @@ -get information about certificates, by default will output the expiration date +# checkcert + +This utility was based off of [this +gist](https://gist.github.com/gdamjan/55a8b9eec6cf7b771f92021d93b87b2c). + +I have wrapped the logic in a click-based CLI and added command-line options +(checkcert --help to see them) + +# Installation + +## from PyPi +pip install checkert + diff --git a/checkcert.py b/checkcert.py deleted file mode 100755 index 0b302a5..0000000 --- a/checkcert.py +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env python -import re -import sys -from checkcert.checkcert import main - -if __name__ == "__main__": - sys.argv[0] = re.sub(r"(-script\.pyw|\.exe)?$", "", sys.argv[0]) - sys.exit(main()) From 9a1a9606411dce04d5b4a3b6b6820b6dd0001a50 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Thu, 30 Sep 2021 16:14:22 -0400 Subject: [PATCH 02/47] refactor: clean-up for pylint --- .pylintrc | 2 +- checkcert/checkcert.py | 111 ++++++++++++++++++++--------------------- 2 files changed, 54 insertions(+), 59 deletions(-) diff --git a/.pylintrc b/.pylintrc index 4bb4f8c..d3ee538 100644 --- a/.pylintrc +++ b/.pylintrc @@ -45,7 +45,7 @@ limit-inference-results=100 # List of plugins (as comma separated values of python module names) to load, # usually to register additional checkers. -load-plugins=pylint_django +load-plugins= # Pickle collected data for later comparisons. persistent=yes diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 008c0c6..7b0fb9e 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -1,15 +1,14 @@ -# heavily modified version of https://gist.githubusercontent.com/gdamjan/55a8b9eec6cf7b771f92021d93b87b2c/raw/d8dc194ec4d0187f985a57138019d04e3a59b51f/ssl-check.py -# to give a CLI for passing the hosts to check and other optional output +""" CLI to get basic information about certificates and determine validity""" +from collections import namedtuple +import concurrent.futures +from socket import socket import click from OpenSSL import SSL from OpenSSL import crypto from cryptography import x509 from cryptography.x509.oid import NameOID import idna -import sys -from socket import socket -from collections import namedtuple __version__ = "0.2.0" @@ -19,25 +18,23 @@ HostInfo = namedtuple( def get_certificate(hostname, port): + """retreive certificate details and return HostInfo tuple of values""" hostname_idna = idna.encode(hostname) sock = socket() - try: - sock.connect((hostname, port)) - peername = sock.getpeername() - ctx = SSL.Context(SSL.SSLv23_METHOD) # most compatible - ctx.check_hostname = False - ctx.verify_mode = SSL.VERIFY_NONE - sock_ssl = SSL.Connection(ctx, sock) - sock_ssl.set_connect_state() - sock_ssl.set_tlsext_host_name(hostname_idna) - sock_ssl.do_handshake() - cert = sock_ssl.get_peer_certificate() - crypto_cert = cert.to_cryptography() - sock_ssl.close() - sock.close() - except ConnectionRefusedError: - pass + sock.connect((hostname, port)) + peername = sock.getpeername() + ctx = SSL.Context(SSL.SSLv23_METHOD) # most compatible + ctx.check_hostname = False + ctx.verify_mode = SSL.VERIFY_NONE + sock_ssl = SSL.Connection(ctx, sock) + sock_ssl.set_connect_state() + sock_ssl.set_tlsext_host_name(hostname_idna) + sock_ssl.do_handshake() + cert = sock_ssl.get_peer_certificate() + crypto_cert = cert.to_cryptography() + sock_ssl.close() + sock.close() return HostInfo( cert=crypto_cert, @@ -48,6 +45,7 @@ def get_certificate(hostname, port): def get_alt_names(cert): + """retreive the SAN values for given cert""" try: ext = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName) return ext.value.get_values_for_type(x509.DNSName) @@ -56,10 +54,12 @@ def get_alt_names(cert): def get_x509_text(cert): + """return the human-readable text version of the certificate""" return crypto.dump_certificate(crypto.FILETYPE_TEXT, cert) def get_common_name(cert): + """Retrun the common name from the certificate""" try: names = cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME) return names[0].value @@ -68,6 +68,7 @@ def get_common_name(cert): def get_issuer(cert): + """Return the name of the CA/Issuer of the certificate""" try: names = cert.issuer.get_attributes_for_oid(NameOID.COMMON_NAME) return names[0].value @@ -75,62 +76,56 @@ def get_issuer(cert): return None -def print_basic_info(hostinfo): - print( - f""" -{hostinfo.hostname} ({hostinfo.peername[0]}:{hostinfo.peername[1]}) -\tcommonName: {get_common_name(hostinfo.cert)} -\tSAN: {get_alt_names(hostinfo.cert)} -\tissuer: {get_issuer(hostinfo.cert)} -\tnotBefore: {hostinfo.cert.not_valid_before} -\tnotAfter: {hostinfo.cert.not_valid_after} - """ - ) - - @click.command() @click.version_option(__version__, prog_name="checkcert") @click.option("--san", is_flag=True, help="Output Subject Alternate Names") @click.option( "--dump", is_flag=True, help="Dump the full text version of the x509 certificate" ) -@click.option("--color/--no-color", default=True) +@click.option( + "--color/--no-color", + default=True, + help="Enable/disable ANSI color output to show cert validity", +) @click.argument("hosts", nargs=-1) def main(san, dump, color, hosts): + """Return information about certificates given including their validity""" # setup the list of tuples - HOSTS = [] + all_hosts = [] # handle a domain given with a : in it to specify the port for host in hosts: # if a host has a : in it, split on the :, first field will be host # second field will be the port if ":" in host: host_info = host.split(":") - HOSTS.append((host_info[0], int(host_info[1]))) + all_hosts.append((host_info[0], int(host_info[1]))) else: - HOSTS.append((host, 443)) - for hostinfo in map(lambda x: get_certificate(x[0], x[1]), HOSTS): - output_string = "" - if dump: - print(get_x509_text(hostinfo.cert).decode()) - else: - output_string += ( - f"{hostinfo.hostname} ({hostinfo.peername[0]}:{hostinfo.peername[1]})\n" - ) - output_string += f"\tcommonName: {get_common_name(hostinfo.cert)}\n" - if san: - output_string += f"\tSAN: {get_alt_names(hostinfo.cert)}\n" - output_string += f"\tissuer: {get_issuer(hostinfo.cert)}\n" - output_string += f"\tnotBefore: {hostinfo.cert.not_valid_before}\n" - output_string += f"\tnotAfter: {hostinfo.cert.not_valid_after}\n\n" - if hostinfo.is_valid and color: - click.echo(click.style(output_string, fg="green")) - elif not hostinfo.is_valid and color: - click.echo(click.style(output_string, fg="red")) + all_hosts.append((host, 443)) + with concurrent.futures.ThreadPoolExecutor(max_workers=4) as epool: + for hostinfo in epool.map(lambda x: get_certificate(x[0], x[1]), all_hosts): + output_string = "" + if dump: + print(get_x509_text(hostinfo.cert).decode()) else: - click.echo(click.style(output_string)) + output_string += ( + f"{hostinfo.hostname} " + f"({hostinfo.peername[0]}:{hostinfo.peername[1]})\n" + ) + output_string += f"\tcommonName: {get_common_name(hostinfo.cert)}\n" + if san: + output_string += f"\tSAN: {get_alt_names(hostinfo.cert)}\n" + output_string += f"\tissuer: {get_issuer(hostinfo.cert)}\n" + output_string += f"\tnotBefore: {hostinfo.cert.not_valid_before}\n" + output_string += f"\tnotAfter: {hostinfo.cert.not_valid_after}\n\n" + if hostinfo.is_valid and color: + click.echo(click.style(output_string, fg="green")) + elif not hostinfo.is_valid and color: + click.echo(click.style(output_string, fg="red")) + else: + click.echo(click.style(output_string)) # print(f"Certificate for {domain}\nexpires after: {x509.get_not_after()}") if __name__ == "__main__": - main() # pragma: no cover + main() # pylint: disable=no-value-for-parameter # pragma: no cover From 26638e7e73f8ba49df7bc9c0d36ef2ee68ba5f7a Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Thu, 30 Sep 2021 16:23:00 -0400 Subject: [PATCH 03/47] test: update tests to handle all branches chore: ignore the except clauses for coverage --- checkcert/checkcert.py | 8 +++----- tests/test_checkcert.py | 7 +++++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 7b0fb9e..16e378a 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -49,7 +49,7 @@ def get_alt_names(cert): try: ext = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName) return ext.value.get_values_for_type(x509.DNSName) - except x509.ExtensionNotFound: + except x509.ExtensionNotFound: # pragma: no cover return None @@ -63,7 +63,7 @@ def get_common_name(cert): try: names = cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME) return names[0].value - except x509.ExtensionNotFound: + except x509.ExtensionNotFound: # pragma: no cover return None @@ -72,7 +72,7 @@ def get_issuer(cert): try: names = cert.issuer.get_attributes_for_oid(NameOID.COMMON_NAME) return names[0].value - except x509.ExtensionNotFound: + except x509.ExtensionNotFound: # pragma: no cover return None @@ -124,8 +124,6 @@ def main(san, dump, color, hosts): else: click.echo(click.style(output_string)) - # print(f"Certificate for {domain}\nexpires after: {x509.get_not_after()}") - if __name__ == "__main__": main() # pylint: disable=no-value-for-parameter # pragma: no cover diff --git a/tests/test_checkcert.py b/tests/test_checkcert.py index bc5d83c..e962a18 100644 --- a/tests/test_checkcert.py +++ b/tests/test_checkcert.py @@ -11,6 +11,8 @@ def test_main(): assert response.exit_code == 0 response = runner.invoke(cert_main, ["www.franklin.edu:443"]) assert response.exit_code == 0 + response = runner.invoke(cert_main, ["www.franklin.edu", "--no-color"]) + assert response.exit_code == 0 def test_version(): @@ -27,3 +29,8 @@ def test_dump(): def test_san(): response = runner.invoke(cert_main, ["www.franklin.edu", "--san"]) assert response.exit_code == 0 + + +def test_bad_cert(): + response = runner.invoke(cert_main, ["support.bluequill.com", "--san"]) + assert response.exit_code == 0 From 0f43276109aa93d3384150a9f06c4f74006f733c Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Thu, 30 Sep 2021 16:31:19 -0400 Subject: [PATCH 04/47] test: refactor test code for pep8 --- tests/test_checkcert.py | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/tests/test_checkcert.py b/tests/test_checkcert.py index e962a18..4279d7e 100644 --- a/tests/test_checkcert.py +++ b/tests/test_checkcert.py @@ -1,36 +1,54 @@ +""" Tests to validate checkcert""" +from click.testing import CliRunner from checkcert.checkcert import main as cert_main from checkcert.checkcert import __version__ as cert_version -from click.testing import CliRunner runner = CliRunner() def test_main(): - if cert_main: - response = runner.invoke(cert_main, ["www.franklin.edu"]) - assert response.exit_code == 0 - response = runner.invoke(cert_main, ["www.franklin.edu:443"]) - assert response.exit_code == 0 - response = runner.invoke(cert_main, ["www.franklin.edu", "--no-color"]) - assert response.exit_code == 0 + """validate the core function returns correctly for: + a domain + a domain and a port + no names specified + a list of domains + a list of domains with a port specified on one + """ + response = runner.invoke(cert_main, ["www.franklin.edu"]) + assert response.exit_code == 0 + response = runner.invoke(cert_main, ["www.franklin.edu:443"]) + assert response.exit_code == 0 + response = runner.invoke(cert_main, ["www.franklin.edu", "--no-color"]) + assert response.exit_code == 0 + response = runner.invoke(cert_main, ["www.franklin.edu", "library.franklin.edu"]) + assert response.exit_code == 0 + response = runner.invoke( + cert_main, ["www.franklin.edu:443", "library.franklin.edu"] + ) + assert response.exit_code == 0 def test_version(): + """get the version output and ensure it matches the version var""" response = runner.invoke(cert_main, ["--version"]) assert response.exit_code == 0 assert cert_version in response.output def test_dump(): + """verify that --dump outputs data""" response = runner.invoke(cert_main, ["www.franklin.edu", "--dump"]) assert response.exit_code == 0 + assert "www.franklin.edu" in response.output def test_san(): + """verify --san outputs correctly""" response = runner.invoke(cert_main, ["www.franklin.edu", "--san"]) assert response.exit_code == 0 def test_bad_cert(): + """verify an expired certificate works""" response = runner.invoke(cert_main, ["support.bluequill.com", "--san"]) assert response.exit_code == 0 From 5b59455bef4a874a065618ae8dcfd1c4789cde2f Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Thu, 30 Sep 2021 16:34:22 -0400 Subject: [PATCH 05/47] chore: fix spelling --- checkcert/checkcert.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 16e378a..9fc4d9c 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -18,7 +18,7 @@ HostInfo = namedtuple( def get_certificate(hostname, port): - """retreive certificate details and return HostInfo tuple of values""" + """retrieve certificate details and return HostInfo tuple of values""" hostname_idna = idna.encode(hostname) sock = socket() @@ -45,7 +45,7 @@ def get_certificate(hostname, port): def get_alt_names(cert): - """retreive the SAN values for given cert""" + """retrieve the SAN values for given cert""" try: ext = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName) return ext.value.get_values_for_type(x509.DNSName) @@ -59,7 +59,7 @@ def get_x509_text(cert): def get_common_name(cert): - """Retrun the common name from the certificate""" + """Return the common name from the certificate""" try: names = cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME) return names[0].value From dd39b24277703c30de7b2e07fcefe5a88c1ea924 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Fri, 1 Oct 2021 10:05:12 -0400 Subject: [PATCH 06/47] feat: add option to get host names from an external file --- checkcert/checkcert.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 9fc4d9c..b3ba9e1 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -87,12 +87,24 @@ def get_issuer(cert): default=True, help="Enable/disable ANSI color output to show cert validity", ) +@click.option( + "--filename", + "-f", + type=click.Path(), + help="Read a list of hosts to check from a file", +) @click.argument("hosts", nargs=-1) -def main(san, dump, color, hosts): +def main(san, dump, color, filename, hosts): """Return information about certificates given including their validity""" # setup the list of tuples all_hosts = [] # handle a domain given with a : in it to specify the port + if filename: + hosts = [] + with open(filename, "r") as infile: + for line in infile: + line = line.strip() + hosts.append(line) for host in hosts: # if a host has a : in it, split on the :, first field will be host # second field will be the port From 386a983b7922bb25af073e1e3c611c30b2c56e8d Mon Sep 17 00:00:00 2001 From: semantic-release Date: Fri, 1 Oct 2021 10:05:28 -0400 Subject: [PATCH 07/47] 0.3.0 Automatically generated by python-semantic-release --- checkcert/checkcert.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index b3ba9e1..012db22 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -10,7 +10,7 @@ from cryptography.x509.oid import NameOID import idna -__version__ = "0.2.0" +__version__ = "0.3.0" HostInfo = namedtuple( field_names="cert hostname peername is_valid", typename="HostInfo" diff --git a/pyproject.toml b/pyproject.toml index 271deda..a968dae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "checkcert" -version = "0.2.0" +version = "0.3.0" description = "CLI to check tls cert information and determine validity" authors = ["Alex Kelly "] readme = "README.md" From cee20e2c7cf262256479a3ffaae8479e9deac5e0 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Fri, 1 Oct 2021 10:14:03 -0400 Subject: [PATCH 08/47] docs: update readme with more details --- CHANGELOG.md | 19 +++++++++++++++++++ README.md | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 043fd24..ec9e0b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## v0.3.0 (2021-10-01) + +#### New Features + +* add option to get host names from an external file +#### Refactorings + +* clean-up for pylint +#### Docs + +* update docs with a _little_ more detail +#### Others + +* fix spelling +* refactor test code for pep8 +* update tests to handle all branches + +Full set of changes: [`v0.2.0...v0.3.0`](https://git.admin.franklin.edu/tins/checkcert/compare/v0.2.0...v0.3.0) + ## v0.2.0 (2021-09-30) #### New Features diff --git a/README.md b/README.md index a03fa5a..4f921cb 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This utility was based off of [this gist](https://gist.github.com/gdamjan/55a8b9eec6cf7b771f92021d93b87b2c). -I have wrapped the logic in a click-based CLI and added command-line options +checkcert has the logic of that gist wrapped in a click-based CLI and added command-line options (checkcert --help to see them) # Installation @@ -11,3 +11,38 @@ I have wrapped the logic in a click-based CLI and added command-line options ## from PyPi pip install checkert +# Usage + +When you run `pip install checkcert`, you will get a `checkcert` command. To +show all the options, simply run `checkcert --help` to get the most-current list +of commands and options. + +### Basic Usage +The basic usage is `checkcert example.com` + +### Check cert with an alternate port + +Anywhere you specify the host, you may use the format `host:port` to specify an +alternate port. If no port is specified, 443 will be used. To check something +running on port 8081 for example, execute `checkcert example.com:8081` + +### Multiple domains + +checkcert will take all domains specified on the command line. Multiple values +may be specified as `checkcert example.com www.example.com alt.example.com:444` + +### Domain list from a file + +checkcert can be instructed to pull the list of domains from a file instead with +the --filename option. The file contents will just be a domain per line +(specified in host:port format, or just host to default to port 443) + +create a file named domains.txt with contents like the following + +``` +example.com +www.example.com +alt.example.com:444 +``` + +Then execute `checkcert --filename domains.txt` From 310a9f7ffe448e37e7dbdf78ab979abac8407a13 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Fri, 1 Oct 2021 10:22:05 -0400 Subject: [PATCH 09/47] chore: correct lint error on file encoding --- checkcert/checkcert.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 012db22..9653be6 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -101,7 +101,7 @@ def main(san, dump, color, filename, hosts): # handle a domain given with a : in it to specify the port if filename: hosts = [] - with open(filename, "r") as infile: + with open(filename, "r", encoding="utf-8") as infile: for line in infile: line = line.strip() hosts.append(line) From ef5756bd955931795c134145c4bce9f130729c31 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Fri, 1 Oct 2021 12:19:47 -0400 Subject: [PATCH 10/47] test: add test for file input --- tests/test_checkcert.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_checkcert.py b/tests/test_checkcert.py index 4279d7e..c1af858 100644 --- a/tests/test_checkcert.py +++ b/tests/test_checkcert.py @@ -52,3 +52,9 @@ def test_bad_cert(): """verify an expired certificate works""" response = runner.invoke(cert_main, ["support.bluequill.com", "--san"]) assert response.exit_code == 0 + + +def test_from_file(): + """Verify loading domains from file""" + response = runner.invoke(cert_main, ["--filename", "ci/test_domains.txt"]) + assert response.exit_code == 0 From 971bf6aec7854558749b397753c76d2bc5f58c60 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Fri, 1 Oct 2021 12:20:07 -0400 Subject: [PATCH 11/47] refactor: align output data rather than heading for output --- checkcert/checkcert.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 9653be6..23ff0f2 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -93,8 +93,11 @@ def get_issuer(cert): type=click.Path(), help="Read a list of hosts to check from a file", ) +@click.option( + "--valid/--no-valid", default=True, help="Show the text field for cert validity" +) @click.argument("hosts", nargs=-1) -def main(san, dump, color, filename, hosts): +def main(san, dump, color, filename, valid, hosts): """Return information about certificates given including their validity""" # setup the list of tuples all_hosts = [] @@ -115,7 +118,7 @@ def main(san, dump, color, filename, hosts): all_hosts.append((host, 443)) with concurrent.futures.ThreadPoolExecutor(max_workers=4) as epool: for hostinfo in epool.map(lambda x: get_certificate(x[0], x[1]), all_hosts): - output_string = "" + output_string = "\n" if dump: print(get_x509_text(hostinfo.cert).decode()) else: @@ -123,12 +126,14 @@ def main(san, dump, color, filename, hosts): f"{hostinfo.hostname} " f"({hostinfo.peername[0]}:{hostinfo.peername[1]})\n" ) - output_string += f"\tcommonName: {get_common_name(hostinfo.cert)}\n" + output_string += f" commonName: {get_common_name(hostinfo.cert)}\n" + output_string += f" issuer: {get_issuer(hostinfo.cert)}\n" + output_string += f" notBefore: {hostinfo.cert.not_valid_before}\n" + output_string += f" notAfter: {hostinfo.cert.not_valid_after}\n" + if valid: + output_string += f" Valid: {hostinfo.is_valid}\n" if san: - output_string += f"\tSAN: {get_alt_names(hostinfo.cert)}\n" - output_string += f"\tissuer: {get_issuer(hostinfo.cert)}\n" - output_string += f"\tnotBefore: {hostinfo.cert.not_valid_before}\n" - output_string += f"\tnotAfter: {hostinfo.cert.not_valid_after}\n\n" + output_string += f" SAN: {get_alt_names(hostinfo.cert)}\n" if hostinfo.is_valid and color: click.echo(click.style(output_string, fg="green")) elif not hostinfo.is_valid and color: From ca17b3a871270b083364cf5ee9389c13c6d1bbb6 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Fri, 1 Oct 2021 12:21:11 -0400 Subject: [PATCH 12/47] chore: add ci directory for test input data --- ci/test_domains.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 ci/test_domains.txt diff --git a/ci/test_domains.txt b/ci/test_domains.txt new file mode 100644 index 0000000..a22e4f4 --- /dev/null +++ b/ci/test_domains.txt @@ -0,0 +1,3 @@ +example.com +www.example.com +example.net From 498a5816262ab12686ed2bc4449135affc3f0226 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Fri, 1 Oct 2021 12:29:03 -0400 Subject: [PATCH 13/47] feat: add text output for cert validity in addition to color --- checkcert/checkcert.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 23ff0f2..da58eeb 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -94,7 +94,7 @@ def get_issuer(cert): help="Read a list of hosts to check from a file", ) @click.option( - "--valid/--no-valid", default=True, help="Show the text field for cert validity" + "--valid/--no-valid", default=True, help="Show True/False for cert validity" ) @click.argument("hosts", nargs=-1) def main(san, dump, color, filename, valid, hosts): From 840044ab282a7f5f5aa088dabab41c02cedc77d7 Mon Sep 17 00:00:00 2001 From: semantic-release Date: Fri, 1 Oct 2021 12:30:11 -0400 Subject: [PATCH 14/47] 0.4.0 Automatically generated by python-semantic-release --- checkcert/checkcert.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index da58eeb..b7316d9 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -10,7 +10,7 @@ from cryptography.x509.oid import NameOID import idna -__version__ = "0.3.0" +__version__ = "0.4.0" HostInfo = namedtuple( field_names="cert hostname peername is_valid", typename="HostInfo" diff --git a/pyproject.toml b/pyproject.toml index a968dae..db63213 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "checkcert" -version = "0.3.0" +version = "0.4.0" description = "CLI to check tls cert information and determine validity" authors = ["Alex Kelly "] readme = "README.md" From 03cadb90cff39e3a9a67f94281d787b652e58631 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Fri, 1 Oct 2021 12:30:53 -0400 Subject: [PATCH 15/47] update changelog --- CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec9e0b0..6f28c70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## v0.4.0 (2021-10-01) + +#### New Features + +* add text output for cert validity in addition to color +#### Refactorings + +* align output data rather than heading for output +#### Docs + +* update readme with more details +#### Others + +* add ci directory for test input data +* correct lint error on file encoding +* add test for file input + +Full set of changes: [`v0.3.0...v0.4.0`](https://git.admin.franklin.edu/tins/checkcert/compare/v0.3.0...v0.4.0) + ## v0.3.0 (2021-10-01) #### New Features From 6c5c368e6896685bc27761550fd6b8e2c83b451e Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Fri, 1 Oct 2021 12:43:09 -0400 Subject: [PATCH 16/47] cheating pylint by bumping up max-branches by 3 --- .pylintrc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pylintrc b/.pylintrc index d3ee538..c5b1292 100644 --- a/.pylintrc +++ b/.pylintrc @@ -548,7 +548,7 @@ valid-metaclass-classmethod-first-arg=cls ignored-parents= # Maximum number of arguments for function / method. -max-args=5 +max-args=50 # Maximum number of attributes for a class (see R0902). max-attributes=7 @@ -557,7 +557,7 @@ max-attributes=7 max-bool-expr=5 # Maximum number of branch for function / method body. -max-branches=12 +max-branches=15 # Maximum number of locals for function / method body. max-locals=15 From 5c4171758cffea9bf0775a99522bd5bdbeaf498a Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Fri, 1 Oct 2021 14:59:38 -0400 Subject: [PATCH 17/47] refactor: cleanup main logic to reduce branches fix: undo linting cheat --- .pylintrc | 2 +- checkcert/checkcert.py | 30 +++++++++++++++++++----------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/.pylintrc b/.pylintrc index c5b1292..8ef251a 100644 --- a/.pylintrc +++ b/.pylintrc @@ -557,7 +557,7 @@ max-attributes=7 max-bool-expr=5 # Maximum number of branch for function / method body. -max-branches=15 +max-branches=12 # Maximum number of locals for function / method body. max-locals=15 diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index b7316d9..444b1cb 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -17,7 +17,7 @@ HostInfo = namedtuple( ) -def get_certificate(hostname, port): +def get_certificate(hostname, port) -> HostInfo: """retrieve certificate details and return HostInfo tuple of values""" hostname_idna = idna.encode(hostname) sock = socket() @@ -40,7 +40,7 @@ def get_certificate(hostname, port): cert=crypto_cert, peername=peername, hostname=hostname, - is_valid=not cert.has_expired(), + is_valid=not cert.has_expired(), # is_valid is the inverse of has_expired ) @@ -76,6 +76,22 @@ def get_issuer(cert): return None +def get_host_list_tuple(hosts: list) -> list: + """create a tuple of host and port based on hosts given to us in the form + host:port + """ + all_hosts = [] + for host in hosts: + # if a host has a : in it, split on the :, first field will be host + # second field will be the port + if ":" in host: + host_info = host.split(":") + all_hosts.append((host_info[0], int(host_info[1]))) + else: + all_hosts.append((host, 443)) + return all_hosts + + @click.command() @click.version_option(__version__, prog_name="checkcert") @click.option("--san", is_flag=True, help="Output Subject Alternate Names") @@ -100,7 +116,6 @@ def get_issuer(cert): def main(san, dump, color, filename, valid, hosts): """Return information about certificates given including their validity""" # setup the list of tuples - all_hosts = [] # handle a domain given with a : in it to specify the port if filename: hosts = [] @@ -108,14 +123,7 @@ def main(san, dump, color, filename, valid, hosts): for line in infile: line = line.strip() hosts.append(line) - for host in hosts: - # if a host has a : in it, split on the :, first field will be host - # second field will be the port - if ":" in host: - host_info = host.split(":") - all_hosts.append((host_info[0], int(host_info[1]))) - else: - all_hosts.append((host, 443)) + all_hosts = get_host_list_tuple(hosts) with concurrent.futures.ThreadPoolExecutor(max_workers=4) as epool: for hostinfo in epool.map(lambda x: get_certificate(x[0], x[1]), all_hosts): output_string = "\n" From 96146be1615c5dc1401585600fe04ae752b0b9aa Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Fri, 1 Oct 2021 15:07:06 -0400 Subject: [PATCH 18/47] refactor: add type hints to all functions --- checkcert/checkcert.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 444b1cb..159f14f 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -17,7 +17,7 @@ HostInfo = namedtuple( ) -def get_certificate(hostname, port) -> HostInfo: +def get_certificate(hostname: str, port: int) -> HostInfo: """retrieve certificate details and return HostInfo tuple of values""" hostname_idna = idna.encode(hostname) sock = socket() @@ -44,7 +44,7 @@ def get_certificate(hostname, port) -> HostInfo: ) -def get_alt_names(cert): +def get_alt_names(cert: str) -> str: """retrieve the SAN values for given cert""" try: ext = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName) @@ -53,12 +53,12 @@ def get_alt_names(cert): return None -def get_x509_text(cert): +def get_x509_text(cert: str) -> str: """return the human-readable text version of the certificate""" return crypto.dump_certificate(crypto.FILETYPE_TEXT, cert) -def get_common_name(cert): +def get_common_name(cert: str) -> str: """Return the common name from the certificate""" try: names = cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME) @@ -67,7 +67,7 @@ def get_common_name(cert): return None -def get_issuer(cert): +def get_issuer(cert: str) -> str: """Return the name of the CA/Issuer of the certificate""" try: names = cert.issuer.get_attributes_for_oid(NameOID.COMMON_NAME) From 61a92c5c637768b57c4ad0bcff2bac521d72b6ec Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Fri, 1 Oct 2021 17:00:32 -0400 Subject: [PATCH 19/47] refactor: use Any as a workaround for specific types that haven't been imported yet --- checkcert/checkcert.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 159f14f..8ebc2ea 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -2,6 +2,7 @@ from collections import namedtuple import concurrent.futures from socket import socket +from typing import List, Tuple, Any import click from OpenSSL import SSL from OpenSSL import crypto @@ -12,9 +13,7 @@ import idna __version__ = "0.4.0" -HostInfo = namedtuple( - field_names="cert hostname peername is_valid", typename="HostInfo" -) +HostInfo = namedtuple("HostInfo", ["cert", "hostname", "peername", "is_valid"]) def get_certificate(hostname: str, port: int) -> HostInfo: @@ -25,8 +24,6 @@ def get_certificate(hostname: str, port: int) -> HostInfo: sock.connect((hostname, port)) peername = sock.getpeername() ctx = SSL.Context(SSL.SSLv23_METHOD) # most compatible - ctx.check_hostname = False - ctx.verify_mode = SSL.VERIFY_NONE sock_ssl = SSL.Connection(ctx, sock) sock_ssl.set_connect_state() sock_ssl.set_tlsext_host_name(hostname_idna) @@ -44,7 +41,7 @@ def get_certificate(hostname: str, port: int) -> HostInfo: ) -def get_alt_names(cert: str) -> str: +def get_alt_names(cert: Any) -> Any: """retrieve the SAN values for given cert""" try: ext = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName) @@ -53,12 +50,12 @@ def get_alt_names(cert: str) -> str: return None -def get_x509_text(cert: str) -> str: +def get_x509_text(cert: Any) -> Any: """return the human-readable text version of the certificate""" return crypto.dump_certificate(crypto.FILETYPE_TEXT, cert) -def get_common_name(cert: str) -> str: +def get_common_name(cert: Any) -> Any: """Return the common name from the certificate""" try: names = cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME) @@ -67,7 +64,7 @@ def get_common_name(cert: str) -> str: return None -def get_issuer(cert: str) -> str: +def get_issuer(cert: Any) -> Any: """Return the name of the CA/Issuer of the certificate""" try: names = cert.issuer.get_attributes_for_oid(NameOID.COMMON_NAME) @@ -76,7 +73,7 @@ def get_issuer(cert: str) -> str: return None -def get_host_list_tuple(hosts: list) -> list: +def get_host_list_tuple(hosts: list) -> List[Tuple[str, int]]: """create a tuple of host and port based on hosts given to us in the form host:port """ From 157da703b7687a31e0f1cfe74f6cb1044bdde69a Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Mon, 4 Oct 2021 09:58:43 -0400 Subject: [PATCH 20/47] feat: add ability to output just the sans in a space separated list tests: add test for --san-only --- checkcert/checkcert.py | 12 +++++++++++- tests/test_checkcert.py | 6 ++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 8ebc2ea..55e69a0 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -109,8 +109,14 @@ def get_host_list_tuple(hosts: list) -> List[Tuple[str, int]]: @click.option( "--valid/--no-valid", default=True, help="Show True/False for cert validity" ) +@click.option( + "--san-only", + "-o", + is_flag=True, + help="Output only the SAN names to use in passing to certbot for example", +) @click.argument("hosts", nargs=-1) -def main(san, dump, color, filename, valid, hosts): +def main(san, dump, color, filename, valid, san_only, hosts): """Return information about certificates given including their validity""" # setup the list of tuples # handle a domain given with a : in it to specify the port @@ -127,6 +133,10 @@ def main(san, dump, color, filename, valid, hosts): if dump: print(get_x509_text(hostinfo.cert).decode()) else: + if san_only: + san_names = " ".join(get_alt_names(hostinfo.cert)) + print(san_names) + break output_string += ( f"{hostinfo.hostname} " f"({hostinfo.peername[0]}:{hostinfo.peername[1]})\n" diff --git a/tests/test_checkcert.py b/tests/test_checkcert.py index c1af858..de51e41 100644 --- a/tests/test_checkcert.py +++ b/tests/test_checkcert.py @@ -48,6 +48,12 @@ def test_san(): assert response.exit_code == 0 +def test_san_only(): + """verify --san outputs correctly""" + response = runner.invoke(cert_main, ["www.franklin.edu", "--san-only"]) + assert response.exit_code == 0 + + def test_bad_cert(): """verify an expired certificate works""" response = runner.invoke(cert_main, ["support.bluequill.com", "--san"]) From 1cdd2746c6306fd0878c8b4e6a0bab620a33a8b0 Mon Sep 17 00:00:00 2001 From: semantic-release Date: Mon, 4 Oct 2021 10:03:57 -0400 Subject: [PATCH 21/47] 0.5.0 Automatically generated by python-semantic-release --- checkcert/checkcert.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 55e69a0..2a5d04d 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -11,7 +11,7 @@ from cryptography.x509.oid import NameOID import idna -__version__ = "0.4.0" +__version__ = "0.5.0" HostInfo = namedtuple("HostInfo", ["cert", "hostname", "peername", "is_valid"]) diff --git a/pyproject.toml b/pyproject.toml index db63213..d5f09fd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "checkcert" -version = "0.4.0" +version = "0.5.0" description = "CLI to check tls cert information and determine validity" authors = ["Alex Kelly "] readme = "README.md" From a32e116b2ae75489c3f090d2be6361650186be5c Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Mon, 4 Oct 2021 10:51:16 -0400 Subject: [PATCH 22/47] feat: add separator for --san-only feat: add option to prefix the separator in the output --- checkcert/checkcert.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 55e69a0..66d10e9 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -115,8 +115,12 @@ def get_host_list_tuple(hosts: list) -> List[Tuple[str, int]]: is_flag=True, help="Output only the SAN names to use in passing to certbot for example", ) +@click.option( + "--pre/--no-pre", default=False, help="prefix the --san-only with the separator" +) +@click.option("--sep", "-s", default=" ", help="Separator to use in --san-only output") @click.argument("hosts", nargs=-1) -def main(san, dump, color, filename, valid, san_only, hosts): +def main(san, dump, color, filename, valid, san_only, sep, pre, hosts): """Return information about certificates given including their validity""" # setup the list of tuples # handle a domain given with a : in it to specify the port @@ -134,8 +138,11 @@ def main(san, dump, color, filename, valid, san_only, hosts): print(get_x509_text(hostinfo.cert).decode()) else: if san_only: - san_names = " ".join(get_alt_names(hostinfo.cert)) - print(san_names) + output_string = "" + if pre: + output_string += f"{sep}".lstrip() + output_string += f"{sep}".join(get_alt_names(hostinfo.cert)) + print(output_string) break output_string += ( f"{hostinfo.hostname} " From f21cf8b100e7fe04395b22d2e982e88b2580c7f6 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Mon, 4 Oct 2021 12:01:57 -0400 Subject: [PATCH 23/47] docs: add docs dir for handling sphinx-based documentation --- .gitignore | 1 + docs/Makefile | 20 ++++ docs/source/conf.py | 55 +++++++++ docs/source/index.rst | 20 ++++ poetry.lock | 257 +++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 1 + 6 files changed, 353 insertions(+), 1 deletion(-) create mode 100644 docs/Makefile create mode 100644 docs/source/conf.py create mode 100644 docs/source/index.rst diff --git a/.gitignore b/.gitignore index 07a1cf3..f6e9528 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ db.sqlite3 dist .coverage +docs/build diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d0c3cbf --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..78b9057 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,55 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- Project information ----------------------------------------------------- + +project = 'checkcert' +copyright = '2021, Alex Kelly' +author = 'Alex Kelly' + +# The full version, including alpha/beta/rc tags +release = '0.5.0' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..35c999b --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,20 @@ +.. checkcert documentation master file, created by + sphinx-quickstart on Mon Oct 4 12:00:40 2021. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to checkcert's documentation! +===================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/poetry.lock b/poetry.lock index ba56da6..97f9ace 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,11 @@ +[[package]] +name = "alabaster" +version = "0.7.12" +description = "A configurable sidebar-enabled Sphinx theme" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "astroid" version = "2.8.0" @@ -33,6 +41,17 @@ docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"] tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"] +[[package]] +name = "babel" +version = "2.9.1" +description = "Internationalization utilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +pytz = ">=2015.7" + [[package]] name = "bleach" version = "4.1.0" @@ -186,6 +205,14 @@ category = "dev" optional = false python-versions = ">=3.5" +[[package]] +name = "imagesize" +version = "1.2.0" +description = "Getting image size from png/jpeg/jpeg2000/gif file" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + [[package]] name = "importlib-metadata" version = "4.8.1" @@ -244,6 +271,20 @@ python-versions = ">=3.6" test = ["pytest", "pytest-trio", "pytest-asyncio", "testpath", "trio", "async-timeout"] trio = ["trio", "async-generator"] +[[package]] +name = "jinja2" +version = "3.0.1" +description = "A very fast and expressive template engine." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + [[package]] name = "keyring" version = "23.2.1" @@ -270,6 +311,14 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +[[package]] +name = "markupsafe" +version = "2.0.1" +description = "Safely add untrusted strings to HTML/XML markup." +category = "dev" +optional = false +python-versions = ">=3.6" + [[package]] name = "mccabe" version = "0.6.1" @@ -460,6 +509,14 @@ docs = ["Sphinx (==1.3.6)"] mypy = ["mypy", "types-requests"] test = ["coverage (>=5,<6)", "pytest (>=5,<6)", "pytest-xdist (>=1,<2)", "pytest-mock (>=2,<3)", "responses (==0.13.3)", "mock (==1.3.0)"] +[[package]] +name = "pytz" +version = "2021.3" +description = "World timezone definitions, modern and historical" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "pywin32-ctypes" version = "0.2.0" @@ -576,6 +633,116 @@ category = "dev" optional = false python-versions = ">=3.5" +[[package]] +name = "snowballstemmer" +version = "2.1.0" +description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "sphinx" +version = "4.2.0" +description = "Python documentation generator" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +alabaster = ">=0.7,<0.8" +babel = ">=1.3" +colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} +docutils = ">=0.14,<0.18" +imagesize = "*" +Jinja2 = ">=2.3" +packaging = "*" +Pygments = ">=2.0" +requests = ">=2.5.0" +snowballstemmer = ">=1.1" +sphinxcontrib-applehelp = "*" +sphinxcontrib-devhelp = "*" +sphinxcontrib-htmlhelp = ">=2.0.0" +sphinxcontrib-jsmath = "*" +sphinxcontrib-qthelp = "*" +sphinxcontrib-serializinghtml = ">=1.1.5" + +[package.extras] +docs = ["sphinxcontrib-websupport"] +lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.900)", "docutils-stubs", "types-typed-ast", "types-pkg-resources", "types-requests"] +test = ["pytest", "pytest-cov", "html5lib", "cython", "typed-ast"] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "1.0.2" +description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "1.0.2" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.0.0" +description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest", "html5lib"] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +description = "A sphinx extension which renders display math in HTML via JavaScript" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +test = ["pytest", "flake8", "mypy"] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "1.0.3" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "1.1.5" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + [[package]] name = "toml" version = "0.10.2" @@ -687,9 +854,13 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes [metadata] lock-version = "1.1" python-versions = "^3.9" -content-hash = "f9e3c5502f1aa3c91b8c2a76f7f4c14d39cb84281143d987cf9e8ed043efa175" +content-hash = "83eb072728504c8b6d08f07db01396bd7bccd29fa73a938e36be0e0f12495bca" [metadata.files] +alabaster = [ + {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, + {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, +] astroid = [ {file = "astroid-2.8.0-py3-none-any.whl", hash = "sha256:dcc06f6165f415220013801642bd6c9808a02967070919c4b746c6864c205471"}, {file = "astroid-2.8.0.tar.gz", hash = "sha256:fe81f80c0b35264acb5653302ffbd935d394f1775c5e4487df745bf9c2442708"}, @@ -702,6 +873,10 @@ attrs = [ {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, ] +babel = [ + {file = "Babel-2.9.1-py2.py3-none-any.whl", hash = "sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9"}, + {file = "Babel-2.9.1.tar.gz", hash = "sha256:bc0c176f9f6a994582230df350aa6e05ba2ebe4b3ac317eab29d9be5d2768da0"}, +] bleach = [ {file = "bleach-4.1.0-py2.py3-none-any.whl", hash = "sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994"}, {file = "bleach-4.1.0.tar.gz", hash = "sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da"}, @@ -865,6 +1040,10 @@ idna = [ {file = "idna-3.2-py3-none-any.whl", hash = "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a"}, {file = "idna-3.2.tar.gz", hash = "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"}, ] +imagesize = [ + {file = "imagesize-1.2.0-py2.py3-none-any.whl", hash = "sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1"}, + {file = "imagesize-1.2.0.tar.gz", hash = "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1"}, +] importlib-metadata = [ {file = "importlib_metadata-4.8.1-py3-none-any.whl", hash = "sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15"}, {file = "importlib_metadata-4.8.1.tar.gz", hash = "sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1"}, @@ -886,6 +1065,10 @@ jeepney = [ {file = "jeepney-0.7.1-py3-none-any.whl", hash = "sha256:1b5a0ea5c0e7b166b2f5895b91a08c14de8915afda4407fb5022a195224958ac"}, {file = "jeepney-0.7.1.tar.gz", hash = "sha256:fa9e232dfa0c498bd0b8a3a73b8d8a31978304dcef0515adc859d4e096f96f4f"}, ] +jinja2 = [ + {file = "Jinja2-3.0.1-py3-none-any.whl", hash = "sha256:1f06f2da51e7b56b8f238affdd6b4e2c61e39598a378cc49345bc1bd42a978a4"}, + {file = "Jinja2-3.0.1.tar.gz", hash = "sha256:703f484b47a6af502e743c9122595cc812b0271f661722403114f71a79d0f5a4"}, +] keyring = [ {file = "keyring-23.2.1-py3-none-any.whl", hash = "sha256:bd2145a237ed70c8ce72978b497619ddfcae640b6dcf494402d5143e37755c6e"}, {file = "keyring-23.2.1.tar.gz", hash = "sha256:6334aee6073db2fb1f30892697b1730105b5e9a77ce7e61fca6b435225493efe"}, @@ -914,6 +1097,42 @@ lazy-object-proxy = [ {file = "lazy_object_proxy-1.6.0-cp39-cp39-win32.whl", hash = "sha256:1fee665d2638491f4d6e55bd483e15ef21f6c8c2095f235fef72601021e64f61"}, {file = "lazy_object_proxy-1.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:f5144c75445ae3ca2057faac03fda5a902eff196702b0a24daf1d6ce0650514b"}, ] +markupsafe = [ + {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, + {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, +] mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, @@ -974,6 +1193,10 @@ python-semantic-release = [ {file = "python-semantic-release-7.19.2.tar.gz", hash = "sha256:8ca0e5f72d31e7b0603b95caad6fb2d5315483ac1fadd86648771966d9ec6f2c"}, {file = "python_semantic_release-7.19.2-py3-none-any.whl", hash = "sha256:b2c8bb16a643fee0831be4d06138bc1440ebd4f252c3397d41abde179ea56852"}, ] +pytz = [ + {file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"}, + {file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"}, +] pywin32-ctypes = [ {file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"}, {file = "pywin32_ctypes-0.2.0-py2.py3-none-any.whl", hash = "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"}, @@ -1014,6 +1237,38 @@ smmap = [ {file = "smmap-4.0.0-py2.py3-none-any.whl", hash = "sha256:a9a7479e4c572e2e775c404dcd3080c8dc49f39918c2cf74913d30c4c478e3c2"}, {file = "smmap-4.0.0.tar.gz", hash = "sha256:7e65386bd122d45405ddf795637b7f7d2b532e7e401d46bbe3fb49b9986d5182"}, ] +snowballstemmer = [ + {file = "snowballstemmer-2.1.0-py2.py3-none-any.whl", hash = "sha256:b51b447bea85f9968c13b650126a888aabd4cb4463fca868ec596826325dedc2"}, + {file = "snowballstemmer-2.1.0.tar.gz", hash = "sha256:e997baa4f2e9139951b6f4c631bad912dfd3c792467e2f03d7239464af90e914"}, +] +sphinx = [ + {file = "Sphinx-4.2.0-py3-none-any.whl", hash = "sha256:98a535c62a4fcfcc362528592f69b26f7caec587d32cd55688db580be0287ae0"}, + {file = "Sphinx-4.2.0.tar.gz", hash = "sha256:94078db9184491e15bce0a56d9186e0aec95f16ac20b12d00e06d4e36f1058a6"}, +] +sphinxcontrib-applehelp = [ + {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, + {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, +] +sphinxcontrib-devhelp = [ + {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, + {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, +] +sphinxcontrib-htmlhelp = [ + {file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"}, + {file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"}, +] +sphinxcontrib-jsmath = [ + {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, + {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, +] +sphinxcontrib-qthelp = [ + {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, + {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, +] +sphinxcontrib-serializinghtml = [ + {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, + {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, +] toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, diff --git a/pyproject.toml b/pyproject.toml index db63213..25c412b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,6 +18,7 @@ coverage = "^5.5" pylint = "^2.11.1" pyflakes = "^2.3.1" pytest = "^6.2.5" +Sphinx = "^4.2.0" [build-system] requires = ["poetry-core>=1.0.0"] From 667e1c174e074085b2cc28b528b6a2158443d97c Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Mon, 4 Oct 2021 12:09:35 -0400 Subject: [PATCH 24/47] docs: add rough intro to test rtd integration --- checkcert/checkcert.py | 5 ++++- docs/source/index.rst | 2 ++ tests/test_checkcert.py | 14 +++++++++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 66d10e9..c66249a 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -141,7 +141,10 @@ def main(san, dump, color, filename, valid, san_only, sep, pre, hosts): output_string = "" if pre: output_string += f"{sep}".lstrip() - output_string += f"{sep}".join(get_alt_names(hostinfo.cert)) + alt_names = get_alt_names(hostinfo.cert) + if hostinfo.hostname not in alt_names: + alt_names.insert(0, hostinfo.hostname) + output_string += f"{sep}".join(alt_names) print(output_string) break output_string += ( diff --git a/docs/source/index.rst b/docs/source/index.rst index 35c999b..da81419 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -10,6 +10,8 @@ Welcome to checkcert's documentation! :maxdepth: 2 :caption: Contents: + introduction + Indices and tables diff --git a/tests/test_checkcert.py b/tests/test_checkcert.py index de51e41..347dfa3 100644 --- a/tests/test_checkcert.py +++ b/tests/test_checkcert.py @@ -50,7 +50,19 @@ def test_san(): def test_san_only(): """verify --san outputs correctly""" - response = runner.invoke(cert_main, ["www.franklin.edu", "--san-only"]) + check_domain = "franklin.edu" + response = runner.invoke(cert_main, ["--san-only", check_domain]) + assert response.exit_code == 0 + sep_string = "," + response = runner.invoke( + cert_main, ["--san-only", f"--sep={sep_string}", check_domain] + ) + assert response.exit_code == 0 + assert sep_string in response.output + sep_string = " -d " + response = runner.invoke( + cert_main, ["--san-only", f"--sep={sep_string}", check_domain] + ) assert response.exit_code == 0 From 7326894353e22c5fb64264fbe4b67dd0ad9e4de9 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Mon, 4 Oct 2021 12:18:43 -0400 Subject: [PATCH 25/47] docs: enable rtd theme --- docs/source/conf.py | 16 +++++++++------- docs/source/introduction.rst | 4 ++++ poetry.lock | 21 ++++++++++++++++++++- pyproject.toml | 1 + 4 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 docs/source/introduction.rst diff --git a/docs/source/conf.py b/docs/source/conf.py index 78b9057..be9b10c 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -16,13 +16,14 @@ # -- Project information ----------------------------------------------------- +import sphinx_rtd_theme -project = 'checkcert' -copyright = '2021, Alex Kelly' -author = 'Alex Kelly' +project = "checkcert" +copyright = "2021, Alex Kelly" +author = "Alex Kelly" # The full version, including alpha/beta/rc tags -release = '0.5.0' +release = "0.5.0" # -- General configuration --------------------------------------------------- @@ -31,10 +32,11 @@ release = '0.5.0' # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ + "sphinx_rtd_theme", ] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -47,9 +49,9 @@ exclude_patterns = [] # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'alabaster' +html_theme = "sphinx_rtd_theme" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] \ No newline at end of file +html_static_path = ["_static"] diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst new file mode 100644 index 0000000..baba2ed --- /dev/null +++ b/docs/source/introduction.rst @@ -0,0 +1,4 @@ +Introduction +============ + +checkcert is a CLI to check a remote site secured with a certificate. It will allow you to get basic information about the certificate, if it is currently valid, any subjectAlternateNames that are present, and output content for ingestion into other utilities diff --git a/poetry.lock b/poetry.lock index 97f9ace..d0e1d94 100644 --- a/poetry.lock +++ b/poetry.lock @@ -672,6 +672,21 @@ docs = ["sphinxcontrib-websupport"] lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.900)", "docutils-stubs", "types-typed-ast", "types-pkg-resources", "types-requests"] test = ["pytest", "pytest-cov", "html5lib", "cython", "typed-ast"] +[[package]] +name = "sphinx-rtd-theme" +version = "1.0.0" +description = "Read the Docs theme for Sphinx" +category = "dev" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" + +[package.dependencies] +docutils = "<0.18" +sphinx = ">=1.6" + +[package.extras] +dev = ["transifex-client", "sphinxcontrib-httpdomain", "bump2version"] + [[package]] name = "sphinxcontrib-applehelp" version = "1.0.2" @@ -854,7 +869,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes [metadata] lock-version = "1.1" python-versions = "^3.9" -content-hash = "83eb072728504c8b6d08f07db01396bd7bccd29fa73a938e36be0e0f12495bca" +content-hash = "01f9486cf3b3cb666f32f2bd4975cfdc04f41388ea389538fe428de252a0f782" [metadata.files] alabaster = [ @@ -1245,6 +1260,10 @@ sphinx = [ {file = "Sphinx-4.2.0-py3-none-any.whl", hash = "sha256:98a535c62a4fcfcc362528592f69b26f7caec587d32cd55688db580be0287ae0"}, {file = "Sphinx-4.2.0.tar.gz", hash = "sha256:94078db9184491e15bce0a56d9186e0aec95f16ac20b12d00e06d4e36f1058a6"}, ] +sphinx-rtd-theme = [ + {file = "sphinx_rtd_theme-1.0.0-py2.py3-none-any.whl", hash = "sha256:4d35a56f4508cfee4c4fb604373ede6feae2a306731d533f409ef5c3496fdbd8"}, + {file = "sphinx_rtd_theme-1.0.0.tar.gz", hash = "sha256:eec6d497e4c2195fa0e8b2016b337532b8a699a68bcb22a512870e16925c6a5c"}, +] sphinxcontrib-applehelp = [ {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, diff --git a/pyproject.toml b/pyproject.toml index 25c412b..2f4cff8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,7 @@ pylint = "^2.11.1" pyflakes = "^2.3.1" pytest = "^6.2.5" Sphinx = "^4.2.0" +sphinx-rtd-theme = "^1.0.0" [build-system] requires = ["poetry-core>=1.0.0"] From 185915df34140037ba0997c1d3b123f17ae532d8 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Mon, 4 Oct 2021 12:29:40 -0400 Subject: [PATCH 26/47] docs: add installation section --- docs/source/index.rst | 1 + docs/source/install.rst | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 docs/source/install.rst diff --git a/docs/source/index.rst b/docs/source/index.rst index da81419..f97319f 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -11,6 +11,7 @@ Welcome to checkcert's documentation! :caption: Contents: introduction + install diff --git a/docs/source/install.rst b/docs/source/install.rst new file mode 100644 index 0000000..31fe33b --- /dev/null +++ b/docs/source/install.rst @@ -0,0 +1,26 @@ +Installation +============ + +From Pypi +--------- + +The easiest way is to install via pypi via: + +``pip install checkcert`` + +If you already have checkcert installed and wish to update it, run: + +``pip install -U checkcert`` + +This will upgrade the currently-installed version to the latest. + +From Git +-------- + +There are many methods for running within a virtual environment isolated for a particular package. Certcheck has been built with poetry, so this document details that method, but there are certainly other ways to accomplish the same thing + +1. clone the repo ``git clone https://github.com/kellya/checkcert.git`` +2. cd to the directory you just cloned ``cd checkcert`` +3. install the required packages ``poetry install`` +4. activate the poetry-built venv ``poetry shell`` +5. run with ``python certcheck/certcheck.py`` From 978b42ae572a24b9f118dff914fcd3051fd31db7 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Mon, 4 Oct 2021 12:37:58 -0400 Subject: [PATCH 27/47] build: add docs to make --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1762948..8ac305e 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,9 @@ clean: rm -rf $(BUILDDIR) find . -name __pycache__|xargs rm -rf +docs: + cd docs && make html + poetry-release: build poetry publish @@ -49,4 +52,4 @@ tea-release: build release: poetry-release -.PHONY: dir clean release gh-release poetry-release coverage tea-release +.PHONY: dir clean release gh-release poetry-release coverage tea-release docs From d3ce964ded901778af2cb146655dbcc1fbef1044 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Mon, 4 Oct 2021 13:59:55 -0400 Subject: [PATCH 28/47] fix: default valid output text to "false", override with "--valid" --- checkcert/checkcert.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 859c584..bf50bd3 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -107,7 +107,7 @@ def get_host_list_tuple(hosts: list) -> List[Tuple[str, int]]: help="Read a list of hosts to check from a file", ) @click.option( - "--valid/--no-valid", default=True, help="Show True/False for cert validity" + "--valid/--no-valid", default=False, help="Show True/False for cert validity" ) @click.option( "--san-only", From ddf0614712463075caa3b93774e05b98db7099e7 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Mon, 4 Oct 2021 14:00:55 -0400 Subject: [PATCH 29/47] docs: update docs to reflect all current options --- Makefile | 1 + docs/source/images/basic.png | Bin 0 -> 28046 bytes docs/source/images/multi.png | Bin 0 -> 76134 bytes docs/source/images/san.png | Bin 0 -> 79107 bytes docs/source/images/valid.png | Bin 0 -> 40838 bytes docs/source/index.rst | 10 +- docs/source/running.rst | 214 +++++++++++++++++++++++++++++++++++ 7 files changed, 216 insertions(+), 9 deletions(-) create mode 100644 docs/source/images/basic.png create mode 100644 docs/source/images/multi.png create mode 100644 docs/source/images/san.png create mode 100644 docs/source/images/valid.png create mode 100644 docs/source/running.rst diff --git a/Makefile b/Makefile index 8ac305e..d4f1871 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,7 @@ dir: clean: rm -rf $(BUILDDIR) find . -name __pycache__|xargs rm -rf + rm -rf docs/build docs: cd docs && make html diff --git a/docs/source/images/basic.png b/docs/source/images/basic.png new file mode 100644 index 0000000000000000000000000000000000000000..36344d86dc174b82f7634810f3c28a1cb43783b4 GIT binary patch literal 28046 zcmYhiWm_Ct)MZP8dvKTF!QCYg9D;jcg}b{ZxVshZ4u!izaCZs|5Zql0`Z;gk?%RK1 zul-@ovBr#4QIbJNAx43LfkBs(l~jX)`P2gg17nJW00RT_PtUv>1_lPsRYFb!2?+_w z56LV728I$wPEuUMEBh?RyUR|>{j#^p1JhE}6CpR_?|1G`y#& z3~@xHhV0H!C>Y2}`5aL}CfF*wSJ{PDxah`yCb$~7;WTWF1Q&h>7hBC+6je5uA~_eX zGu`^E&^_0-%}!hGno5ICt(t;mY%Eo2!ksT+Nc>nZ8a$olm1aiKp_<3M6|@`FpRL;D z24yhG@$f$qUwQ)`V1@gS7wnc8&=2M;a(#Bl0hn@u%#k zH3OU_cJt@dzLX30BXg_6*upMd1<60;+C1#8-De{4Um03^NzFQF&qh)MPYyw6S6>j*2N2rF{No zcoN%^TN9^X2T!t`{-LL)sZZcD?2=t@WRtxt?4~9nKkfajd}mneIOPgIY4wjJY_)EoDdICaNl@(t(HrNuZ67^p$XPll^>v#)R6 zU$AIoB~obu12xXs?&%U)*vhy8Zj&h7}^kp3kd~ z6^9qw#pK1gU6WVbr&P@TYO7C5Qgjc|i?xJdo{=dNp6bdLSuLOD7|-6jq}>f?L%evT zcVgtEN(s3`1klBIZ%`_TlbxvOq*~l5nGRF6POM8r*;S@^GniQN+0F!&SFg>)(~SpD1y7wD6W(=v z=3_D>_ez0}t|4TWs5O@g+H?@i^SzBW!__DJKT~ej4U3P>rU^bTvA0i-Ovm=s^0)K! zz};gk*qycq9|+`DyvbRq!SgHrV`Y6f)2Blar1 zs`>nR?j2cY)=bYji)UGfcB zxjsE=fkR}6%&hScNyW32E z!PqA#&2#R4cY5`FUihQk&;HrC0knhdK?a*`?`|<1GG2cf_Hc*RI=$1f!uj=y>`OC6q z-63sI?Z55AEk?W7m~KFTQNX5E*fqT;*z!yxncP#9s~WEF?KP~-ve}u{Z1mlHKT-KaKzd!|=?^#R%Z{j&e^XmhLX=ul(+9dHd;EW{;i z?8Co!pdD;&Eok}0lzE+`QLw8xMR@Kk%N`k>Mrf$*6H|U>lae7HTH;qEYxUjr71+AN zEf|VQYRu5ArGZF=A5hzWi&BAO$VXXZ6jigU$`)rla5} zb8D&$4RpeRgbx~R`+z9|6@7ef5OIHl7;*CU6)#GVS*@J`}-@EIi{xqR*u%=f#{}P89q}B*40PU8>aMX%T)%Z!^Ii(?=K2@}`MA;~ox%6H{%Qc{ve&}2Kk!5br$gv|k<^xZn zhgS+*jLJpX6Zk)+ewdR)P|*btFpl(X{8>$NCfwBco_PFQ&I1BtKwg{s0{*6uHxAnJ z$zSJ}8S0raqVhM`wJ@xn?9l^xsXcBZR#?uqXcZBCCr~^g2~_;>!N8A#qVJxyRT{2kQxZmfDR@Mf=#z{A z?o>3uy=)&xMQ|};lqn5}u{FmDxyjN#%%uibj|IJDypM2+&_th4K86h%D6yaWAkdyS z|MFEMV6I2|!WO6M-hV7ZYXA4JaU~|wc6@V=%c*ZwIuWk=Ov5H*ymw8uCBSZeY1I^! zu^cbvlL(-K0&}ky-PMsn>?D=M_;Moj;AiQFQ4d0<*e^(As00Q+D;}{?bI!rQ{=m39 zZ{=88*XsNTa0m9Ur*3yNMd|8vYhb^&5#S%5h-Yt7cQ< zJpf2Q^ZO2C^_BQ56!}S{&Iz8`Fo$bv%r!MsAvBfb`yueSXkeTmw8Ap&RrG`0%1<*P zQ|@#9WonK0_GBGtYk+)b6nCMIqg4RkN3QNOuGTx7Vs?$})UfxiC-AM_t^BwcLB{Wo zosI*}na}U<5Lbrfm^+NsM?K(e$@p;VHXw)x6W^{+Hngd?9ynH;ojfx#H`@77k4gSV_KQ zNbZM_gkDzokz~>RXp)Ih&n|7hgtx9tJ~K1&DCpKrCP!|-eL4s*Ez3E^Y#Q?0K7_)> zVy*iBo^LK-Xn`Y`Y1ofFZPQbf(1*tid5#0iZ8=@JNw?2-W z_^u**p_&2rTVRMR2DiGhQX+{z$rN}Zd^)pid&c&_q;$8TB&A(}l7ACjn#)?Hi;BU# zry@X1yv;BRw!vPmw`T;=S@GwopZT&KEIWpuv_OU_nE+k|4+adQgm%!7hG*EQ^-^a4 zFzljFrUXp)Llg|YAM#dP3^eP;XSh;y=boTnYpALIj$h{U zYK=OZ_l$Ru*&ow(*2>qdDo;~wLxpk~&iG}@MOJww1`D_OG1nhMnRenvP-DUAU`(|c zc6)R#zIg-Eq^+Fu6D9U$!<2tFo`zhhg&|V3xws5ShE00IFww-Ir3Bw_Vn|aa8RL8m z=)PQtv(Us~?Y<7B+=G!Z>SW<>W71}Z!r;DvM72@Vt)AKV7Qt&mbPBDM#0!p->ED($ zlXfQ%yK9eHd+XX!6HsyD=W1M|3)-Xs&E$KtT02V=tNnjY?a9>dZe(#-6*CI#FSKpR*&Z$FL^ zwmf5ZyZGi%+i@;Uu}WG+hUrQ`pdpBplZBkahulII%&&3xW8ZN0%_Gsv%1^3XWW&m! z4F$iJQEVHO{;h-Hfb}>#y=qRqoxskoiZd{>?k08T7=EErgQEJXUgFig1A_88w_ux1 z)cCwqbs2y;*=u^$^H?jB5jbLFK5kzl?TYyGan?O`afO7oLf%!bjsZTEHt*g2-%F~J z+v@qlf-JdAm(`1HnPnY*aWK%r{jsuaw)EQ)GiPi>f=y>slggL#joY#h^k$sTMYppr z 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

T?&d6(ejc7i^ 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 literal 0 HcmV?d00001 diff --git a/docs/source/images/multi.png b/docs/source/images/multi.png new file mode 100644 index 0000000000000000000000000000000000000000..e1f7d3b00ddda99a5b9c27763a6b6f832a1bd73d GIT binary patch literal 76134 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�e*q|bp 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 literal 0 HcmV?d00001 diff --git a/docs/source/images/san.png b/docs/source/images/san.png new file mode 100644 index 0000000000000000000000000000000000000000..657e3f91413398f05b0227228509c1816e1f7257 GIT binary patch literal 79107 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

& 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%0Ds-O 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%0A#eyGwvvTw^ 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 option, so for comma separated, run ``checkcert --san-only --sep , www.example.com`` which will yield:: + + www.example.org,example.com,example.edu,example.net,example.org,www.example.com,www.example.edu,www.example.net + +If it is desired to output that list to another command as commandline options (for example when migrating from a managed PKI front-end to using ACME/certbot). Certbot wants the domains specified as -d. checkcert may run as: ``checkcert --san-only --sep " -d "- www.example.com`` which will return:: + + www.example.org -d example.com -d example.edu -d example.net -d example.org -d www.example.com -d www.example.edu -d www.example.net + +.. note:: the documentation for certbot specifies multiple domains should be specified each with their own '-d' option. certbot in particular seems to work with a comma-separated list too, even though the docs don't specify that it works that way. + +Notice that the " -d " is used as a **separator** and therefore the first entry does not have a -d before it. To make -d show up before every entry (as would be required in this case) you must also add --pre to "prefix" the entry with the separator; thus, running ``checkcert --san-only --sep " -d " --pre www.example.com`` will yield:: + + -d www.example.org -d example.com -d example.edu -d example.net -d example.org -d www.example.com -d www.example.edu -d www.example.net + +.. note:: Since this is utilizing separator in a slightly different way, the space before the option must be specified, otherwise everything would run together. checkcert is aware of this and will strip off the space at the beginning if ``--pre`` is used. + +This output could be directly included into certbot as ``certbot $(checkcert --san-only --sep " -d " --pre www.example.com")`` + + +.. note:: Certbot was the specific reason this was added. As such, it will prepend the name queried to the list. The domain itself is not always included in the SAN list, checkcert will verify if the domain is in the list and will always prefix it if not. If example.com was not in the list of SANS, but ``checkcert --san --pre --sep " -d " example.com`` was used, '-d example.com' will be the first entry even if it was not part of the SANs. + +Dumping the text version of a cert +---------------------------------- + +``--dump`` will give you the textual version of the certificate presented. Running ``checkcert --dump www.example.com`` will return:: + + Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 0f:be:08:b0:85:4d:05:73:8a:b0:cc:e1:c9:af:ee:c9 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=DigiCert Inc, CN=DigiCert TLS RSA SHA256 2020 CA1 + Validity + Not Before: Nov 24 00:00:00 2020 GMT + Not After : Dec 25 23:59:59 2021 GMT + Subject: C=US, ST=California, L=Los Angeles, O=Internet Corporation for Assigned Names and Numbers, CN=www.example.org + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:ba:fc:ee:cc:ca:0a:08:ff:0e:93:1d:b3:be:0b: + 9c:03:96:22:9e:b1:4f:10:ae:51:40:fd:53:5f:b3: + c4:61:40:28:04:ee:a2:e6:12:00:b0:82:85:98:5c: + 6d:5b:6b:20:84:44:62:95:4e:6b:76:7c:50:70:5d: + df:13:1d:ec:63:83:ad:63:a5:52:04:f2:cf:84:ba: + db:2a:8c:c7:2e:b4:3c:64:df:eb:61:36:fe:86:03: + 54:79:3e:cd:03:59:8f:ef:c2:04:93:10:23:e2:a1: + b9:b6:58:b8:26:ae:35:68:26:d4:94:2b:7b:7a:ab: + 86:5e:89:08:9a:10:be:51:8e:48:a5:01:19:4b:4b: + 4a:0f:8b:ee:da:4b:19:d3:84:1e:b6:9d:24:f2:35: + 9d:02:f3:00:db:b5:b7:13:08:07:1c:d7:95:19:66: + c9:3c:2d:03:9f:b4:6a:3f:0d:77:af:b8:45:c9:2e: + 53:a6:57:b2:c2:37:58:d6:70:7b:69:de:a4:71:95: + d9:6c:47:1a:15:9e:d9:b9:ea:c0:e9:19:0f:18:4f: + 8f:b2:76:51:6f:5a:05:26:46:28:5e:29:ac:ba:f9: + 15:16:15:9e:1d:05:c2:18:2d:5c:b8:35:92:ac:cd: + dc:a5:0b:ce:cc:a1:f6:bd:2e:dd:d7:9f:b3:1a:5b: + 38:23 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Authority Key Identifier: + keyid:B7:6B:A2:EA:A8:AA:84:8C:79:EA:B4:DA:0F:98:B2:C5:95:76:B9:F4 + + X509v3 Subject Key Identifier: + 26:1A:F8:E4:B1:B0:72:84:CE:DA:81:06:D2:27:98:FB:ED:3A:3D:17 + X509v3 Subject Alternative Name: + DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net + X509v3 Key Usage: critical + Digital Signature, Key Encipherment + X509v3 Extended Key Usage: + TLS Web Server Authentication, TLS Web Client Authentication + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl3.digicert.com/DigiCertTLSRSASHA2562020CA1.crl + + Full Name: + URI:http://crl4.digicert.com/DigiCertTLSRSASHA2562020CA1.crl + + X509v3 Certificate Policies: + Policy: 2.16.840.1.114412.1.1 + CPS: https://www.digicert.com/CPS + Policy: 2.23.140.1.2.2 + + Authority Information Access: + OCSP - URI:http://ocsp.digicert.com + CA Issuers - URI:http://cacerts.digicert.com/DigiCertTLSRSASHA2562020CA1.crt + + X509v3 Basic Constraints: critical + CA:FALSE + CT Precertificate SCTs: + Signed Certificate Timestamp: + Version : v1 (0x0) + Log ID : F6:5C:94:2F:D1:77:30:22:14:54:18:08:30:94:56:8E: + E3:4D:13:19:33:BF:DF:0C:2F:20:0B:CC:4E:F1:64:E3 + Timestamp : Nov 24 19:32:04.334 2020 GMT + Extensions: none + Signature : ecdsa-with-SHA256 + 30:46:02:21:00:A4:6B:A8:D0:43:A4:F1:07:32:2D:ED: + 9C:39:7D:77:E8:73:C1:9F:ED:22:4A:00:C5:BE:9A:C9: + B5:B6:12:DC:B1:02:21:00:8D:E8:5F:8A:C7:52:CD:0D: + A1:23:D5:B5:BB:DB:DB:62:13:88:22:D6:70:EC:83:5E: + 3F:C9:AC:94:4C:8C:58:3A + Signed Certificate Timestamp: + Version : v1 (0x0) + Log ID : 5C:DC:43:92:FE:E6:AB:45:44:B1:5E:9A:D4:56:E6:10: + 37:FB:D5:FA:47:DC:A1:73:94:B2:5E:E6:F6:C7:0E:CA + Timestamp : Nov 24 19:32:04.429 2020 GMT + Extensions: none + Signature : ecdsa-with-SHA256 + 30:45:02:20:6A:AC:11:FA:05:09:12:FF:9B:8E:89:30: + DF:0E:05:6E:CA:8E:59:CC:ED:B5:C2:0A:3C:33:34:A8: + B0:33:DA:AC:02:21:00:DA:D8:5C:51:6D:64:0A:A6:AA: + 3D:8B:35:20:13:3A:6A:97:4F:76:B9:67:CB:BE:FC:CC: + A4:57:67:B4:3F:1B:BD + Signature Algorithm: sha256WithRSAEncryption + a7:2a:10:30:5c:b8:6b:7a:1b:f8:66:38:f6:e9:a0:0a:d5:13: + 82:82:f8:65:89:57:a5:b8:eb:13:29:1d:84:6c:ec:fb:e3:05: + 11:d7:1e:31:5e:0e:e2:c0:00:e5:6d:06:48:be:3d:55:6f:ba: + b7:11:35:b6:ea:c4:cf:84:f1:30:4c:bb:33:9e:11:17:2b:c9: + d2:19:4b:2c:d0:ad:5f:17:23:84:e1:df:17:a2:3b:a8:7f:69: + 29:7c:48:a6:61:5f:26:3f:75:e2:3b:5b:a3:36:b3:1c:cd:e3: + 04:57:30:1f:fc:c9:fa:4b:8e:48:80:58:27:9c:a2:c7:c3:26: + dc:17:02:fa:e6:6c:ea:81:01:5c:92:8f:d3:18:08:17:70:7a: + c2:a3:4b:6c:3a:fa:e3:cf:f6:fe:7e:c9:56:e5:a5:4e:1b:14: + 4f:a9:98:9d:79:b1:1e:c3:ab:b1:0d:15:85:a9:46:b6:e5:c2: + 58:e8:5a:fe:c8:14:28:68:90:c6:b8:c8:94:7f:e1:0f:89:fa: + a7:d6:09:37:a1:62:b7:00:27:b5:be:f1:b1:5e:45:28:06:b3: + 54:15:e6:c3:c8:ac:82:01:ce:86:e2:2b:e1:7a:e4:bd:4c:cb: + 9c:5e:d0:62:c2:61:bd:8b:5a:62:b6:76:30:bc:46:0f:e3:45: + 23:c0:64:5f From 5455503445cb874da25b119986ad33f17475047a Mon Sep 17 00:00:00 2001 From: semantic-release Date: Mon, 4 Oct 2021 14:01:49 -0400 Subject: [PATCH 30/47] 0.6.0 Automatically generated by python-semantic-release --- checkcert/checkcert.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index bf50bd3..7c744bc 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -11,7 +11,7 @@ from cryptography.x509.oid import NameOID import idna -__version__ = "0.5.0" +__version__ = "0.6.0" HostInfo = namedtuple("HostInfo", ["cert", "hostname", "peername", "is_valid"]) diff --git a/pyproject.toml b/pyproject.toml index e4eb12c..043ecd9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "checkcert" -version = "0.5.0" +version = "0.6.0" description = "CLI to check tls cert information and determine validity" authors = ["Alex Kelly "] readme = "README.md" From 609223759465de542f310d080b81f6df9143e445 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Mon, 4 Oct 2021 14:02:45 -0400 Subject: [PATCH 31/47] docs: update changelog for 0.6.0 --- CHANGELOG.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f28c70..754b8c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,39 @@ # Changelog +## v0.6.0 (2021-10-04) + +#### New Features + +* add separator for --san-only +#### Fixes + +* default valid output text to "false", override with "--valid" +#### Docs + +* update docs to reflect all current options +* add installation section +* enable rtd theme +* add rough intro to test rtd integration +* add docs dir for handling sphinx-based documentation +#### Others + +* add docs to make + +Full set of changes: [`v0.5.0...v0.6.0`](https://git.admin.franklin.edu/tins/checkcert/compare/v0.5.0...v0.6.0) + +## v0.5.0 (2021-10-04) + +#### New Features + +* add ability to output just the sans in a space separated list +#### Refactorings + +* use Any as a workaround for specific types that haven't been imported yet +* add type hints to all functions +* cleanup main logic to reduce branches + +Full set of changes: [`v0.4.0...v0.5.0`](https://git.admin.franklin.edu/tins/checkcert/compare/v0.4.0...v0.5.0) + ## v0.4.0 (2021-10-01) #### New Features From 0ab0fb8000dd66fc849c39af5bd45b6c71866290 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Mon, 4 Oct 2021 14:08:12 -0400 Subject: [PATCH 32/47] docs: add full documentation site --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 043ecd9..f11106c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,6 +5,7 @@ description = "CLI to check tls cert information and determine validity" authors = ["Alex Kelly "] readme = "README.md" homepage = "https://github.com/kellya/checkcert" +documentation = "https://checkcert.readthedocs.io" license = "MIT" [tool.poetry.dependencies] From 18a59afeade6c2ce474671675b329f270cf2cc9a Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Mon, 4 Oct 2021 14:17:40 -0400 Subject: [PATCH 33/47] docs: remove personal "you/I/me" --- docs/source/running.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/source/running.rst b/docs/source/running.rst index c4f7abd..3c32b27 100644 --- a/docs/source/running.rst +++ b/docs/source/running.rst @@ -6,7 +6,7 @@ This section assumes that checkcert is installed via pypi, and the ``certcheck`` Basic query ----------- -To do a simple validation, run something like ``checkcert www.example.com``. You should get output like: +To do a simple validation, run something like ``checkcert www.example.com``. This should yield output like: .. figure:: images/basic.png :alt: basic output example @@ -90,7 +90,7 @@ If it is desired to output that list to another command as commandline options ( .. note:: the documentation for certbot specifies multiple domains should be specified each with their own '-d' option. certbot in particular seems to work with a comma-separated list too, even though the docs don't specify that it works that way. -Notice that the " -d " is used as a **separator** and therefore the first entry does not have a -d before it. To make -d show up before every entry (as would be required in this case) you must also add --pre to "prefix" the entry with the separator; thus, running ``checkcert --san-only --sep " -d " --pre www.example.com`` will yield:: +Notice that the " -d " is used as a **separator** and therefore the first entry does not have a -d before it. To make -d show up before every entry (as would be required in this case) The ``--pre`` option must be added to "prefix" the entry with the separator; thus, running ``checkcert --san-only --sep " -d " --pre www.example.com`` will yield:: -d www.example.org -d example.com -d example.edu -d example.net -d example.org -d www.example.com -d www.example.edu -d www.example.net @@ -104,7 +104,7 @@ This output could be directly included into certbot as ``certbot $(checkcert --s Dumping the text version of a cert ---------------------------------- -``--dump`` will give you the textual version of the certificate presented. Running ``checkcert --dump www.example.com`` will return:: +``--dump`` will output the textual version of the certificate presented. Running ``checkcert --dump www.example.com`` will return:: Certificate: Data: From c6d657952da79863c3f3b0823347bc02f0f49386 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Mon, 4 Oct 2021 14:47:45 -0400 Subject: [PATCH 34/47] test: fix separator testing issues test: add coverage for cert-not-in-san case --- tests/test_checkcert.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/test_checkcert.py b/tests/test_checkcert.py index 347dfa3..1a957fb 100644 --- a/tests/test_checkcert.py +++ b/tests/test_checkcert.py @@ -22,6 +22,8 @@ def test_main(): assert response.exit_code == 0 response = runner.invoke(cert_main, ["www.franklin.edu", "library.franklin.edu"]) assert response.exit_code == 0 + response = runner.invoke(cert_main, ["www.franklin.edu", "--valid"]) + assert response.exit_code == 0 response = runner.invoke( cert_main, ["www.franklin.edu:443", "library.franklin.edu"] ) @@ -50,20 +52,25 @@ def test_san(): def test_san_only(): """verify --san outputs correctly""" - check_domain = "franklin.edu" + check_domain = "example.com" response = runner.invoke(cert_main, ["--san-only", check_domain]) assert response.exit_code == 0 sep_string = "," response = runner.invoke( - cert_main, ["--san-only", f"--sep={sep_string}", check_domain] + cert_main, ["--san-only", "--sep", sep_string, check_domain] ) assert response.exit_code == 0 assert sep_string in response.output - sep_string = " -d " response = runner.invoke( - cert_main, ["--san-only", f"--sep={sep_string}", check_domain] + cert_main, ["--san-only", "--sep", sep_string, "--pre", check_domain] ) assert response.exit_code == 0 + assert response.output.startswith(sep_string) + response = runner.invoke( + cert_main, ["--san-only", "--sep", sep_string, "--pre", "cs.franklin.edu"] + ) + assert response.exit_code == 0 + assert response.output.startswith(sep_string) def test_bad_cert(): From c22f282a61a7a61c1bfa3579ff2801419fddfb88 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Mon, 4 Oct 2021 14:51:53 -0400 Subject: [PATCH 35/47] docs: update full doc url in readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 4f921cb..d77fdcf 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,9 @@ gist](https://gist.github.com/gdamjan/55a8b9eec6cf7b771f92021d93b87b2c). checkcert has the logic of that gist wrapped in a click-based CLI and added command-line options (checkcert --help to see them) +Full documentation is available at +[https://checkcert.readthedocs.io](https://checkcert.readthedocs.io) + # Installation ## from PyPi From 457b36e1da871b845f4d7f2bc581dad13405035b Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Mon, 4 Oct 2021 16:48:25 -0400 Subject: [PATCH 36/47] feat(completion): add completion scripts --- completions/checkcert-complete.sh | 29 +++++++++++++++++++++++++ completions/checkcert-complete.zsh | 35 ++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 completions/checkcert-complete.sh create mode 100644 completions/checkcert-complete.zsh diff --git a/completions/checkcert-complete.sh b/completions/checkcert-complete.sh new file mode 100644 index 0000000..362a38b --- /dev/null +++ b/completions/checkcert-complete.sh @@ -0,0 +1,29 @@ +_checkcert_completion() { + local IFS=$'\n' + local response + + response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD _CHECKCERT_COMPLETE=bash_complete $1) + + for completion in $response; do + IFS=',' read type value <<< "$completion" + + if [[ $type == 'dir' ]]; then + COMREPLY=() + compopt -o dirnames + elif [[ $type == 'file' ]]; then + COMREPLY=() + compopt -o default + elif [[ $type == 'plain' ]]; then + COMPREPLY+=($value) + fi + done + + return 0 +} + +_checkcert_completion_setup() { + complete -o nosort -F _checkcert_completion checkcert +} + +_checkcert_completion_setup; + diff --git a/completions/checkcert-complete.zsh b/completions/checkcert-complete.zsh new file mode 100644 index 0000000..b0611e5 --- /dev/null +++ b/completions/checkcert-complete.zsh @@ -0,0 +1,35 @@ +#compdef checkcert + +_checkcert_completion() { + local -a completions + local -a completions_with_descriptions + local -a response + (( ! $+commands[checkcert] )) && return 1 + + response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) _CHECKCERT_COMPLETE=zsh_complete checkcert)}") + + for type key descr in ${response}; do + if [[ "$type" == "plain" ]]; then + if [[ "$descr" == "_" ]]; then + completions+=("$key") + else + completions_with_descriptions+=("$key":"$descr") + fi + elif [[ "$type" == "dir" ]]; then + _path_files -/ + elif [[ "$type" == "file" ]]; then + _path_files -f + fi + done + + if [ -n "$completions_with_descriptions" ]; then + _describe -V unsorted completions_with_descriptions -U + fi + + if [ -n "$completions" ]; then + compadd -U -V unsorted -a completions + fi +} + +compdef _checkcert_completion checkcert; + From cc23ddc7c792f6c40bddd2b29a4cf44d3844a6ef Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Mon, 4 Oct 2021 16:53:36 -0400 Subject: [PATCH 37/47] docs: add shell completion information --- docs/source/index.rst | 1 + docs/source/shell_completion.rst | 60 ++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 docs/source/shell_completion.rst diff --git a/docs/source/index.rst b/docs/source/index.rst index fd83a61..3dff34a 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -13,3 +13,4 @@ Welcome to checkcert's documentation! introduction install running + shell_completion diff --git a/docs/source/shell_completion.rst b/docs/source/shell_completion.rst new file mode 100644 index 0000000..5af4182 --- /dev/null +++ b/docs/source/shell_completion.rst @@ -0,0 +1,60 @@ +Shell Completion +================ + +In order to use shell completion, checkcert must first be installed via ``pip install checkcert``. That generates the `checkcert` entry point that ultimately is used for the command completion. These instructions will not work if using a git cloned version. + +Completion scripts are provided in the source's "completion" directory. You may copy those to source in your shell's rc files. + +These steps are basically copied from Click's Documentation, since that is what is generating the completions. Check `Click's completion documentation `_ for more details. + +Obtaining from github +--------------------- + +Download the needed completion script from github. Using curl, you could download the zsh completion with + +``curl -LO https://raw.githubusercontent.com/kellya/checkcert/main/completions/checkcert-complete.zsh`` + +Then just append ``source /path/to/checkcert-complete.zsh`` to your .zshrc. + +Bash will be pretty much the same, just use: + +``curl -LO https://raw.githubusercontent.com/kellya/checkcert/main/completions/checkcert-complete.sh`` instead + + +Generating Completion script +---------------------------- + +If you do not have access to the files from github, but have checkcert installed, you may generate the completion scripts for inclusion in your shell rc file. + +zsh +^^^ + +``_CHECKCERT_COMPLETE=zsh_source checkcert > ~/.checkcert-complete.zsh`` + +Then in .zshrc, add a ``source ~/.checkcert-complete.zsh`` + +.. note:: There are various plugin directories that could be used to automatically install a completion. There are many options, so this doc just highlights a way that will work. + +bash +^^^^ + +The bash method is pretty much the same as zsh. + +``_CHECKCERT_COMPLETE=bash_source checkcert > ~/.checkcert-complete.bash`` + +Generating Completion via eval +------------------------------ + +Instead of generating a script to execute, you may use eval to generate the completions. This is a little quicker to implement; however there is a speed trade-off as the shell has to run this each time. + +zsh +^^^ + +Execute the following: ``eval "$(_CHECKCERT_COMPLETE=zsh_source checkcert)"``. You may put this in your ~/.zshrc to persist the setting. + +bash +^^^^ + +Execute the following: ``eval "$(_CHECKCERT_COMPLETE=bash_source checkcert)"`` + + From 5f35baebb9a94aa3a44f7ef2c23e1de78e3343f6 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Thu, 7 Oct 2021 09:48:19 -0400 Subject: [PATCH 38/47] docs: add intro readme for docs building --- docs/README.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..2b4b8a5 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,4 @@ +# build pdf docs +If you want to build the pdf documentation via ``make latexpdf`` be warned that it requires a lot of packages. For fedora, the following should get all the dependencies to make it work: + +``dnf -y install texlive-gsftop texlive-makeindexk texlive-parskip texlive-tabulary texlive-needspace texlive-upquote texlive-fancyvrb texlive-framed texlive-capt-of texlive-wrapfig texlive-float texlive-fncychap texlive-tex-gyre texlive-babel texlive-amsfonts texlive-amsmath texlive-ec texlive-cmap latexmk`` From 252f74b59e7a80be0382091eecd142ecd623ef10 Mon Sep 17 00:00:00 2001 From: semantic-release Date: Thu, 7 Oct 2021 09:49:08 -0400 Subject: [PATCH 39/47] 0.7.0 Automatically generated by python-semantic-release --- checkcert/checkcert.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 7c744bc..e1123e8 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -11,7 +11,7 @@ from cryptography.x509.oid import NameOID import idna -__version__ = "0.6.0" +__version__ = "0.7.0" HostInfo = namedtuple("HostInfo", ["cert", "hostname", "peername", "is_valid"]) diff --git a/pyproject.toml b/pyproject.toml index f11106c..44c80cc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "checkcert" -version = "0.6.0" +version = "0.7.0" description = "CLI to check tls cert information and determine validity" authors = ["Alex Kelly "] readme = "README.md" From 593b22113747674881f9c797f27ab961095bd94c Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Thu, 7 Oct 2021 09:49:55 -0400 Subject: [PATCH 40/47] 0.7.0 --- CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 754b8c1..7bbebc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## v0.7.0 (2021-10-07) + +#### New Features + +* (completion): add completion scripts +#### Docs + +* add intro readme for docs building +* add shell completion information +* update full doc url in readme +* remove personal "you/I/me" +* add full documentation site +* update changelog for 0.6.0 +#### Others + +* fix separator testing issues + +Full set of changes: [`v0.6.0...v0.7.0`](https://git.admin.franklin.edu/tins/checkcert/compare/v0.6.0...v0.7.0) + ## v0.6.0 (2021-10-04) #### New Features From 1a2fab6135517fcc8474ec9effced3940dc6c27e Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Thu, 7 Oct 2021 15:18:42 -0400 Subject: [PATCH 41/47] refactor: move output to a print function rather than directly in main logic --- checkcert/checkcert.py | 71 +++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 7c744bc..ae3da06 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -89,6 +89,38 @@ def get_host_list_tuple(hosts: list) -> List[Tuple[str, int]]: return all_hosts +def print_output(hostinfo, settings: dict) -> None: + """print the output of hostinfo conditionally based on items in settings""" + output_string = "" + if settings["san_only"]: + if settings["pre"]: + output_string += f"{settings['sep']}".lstrip() + alt_names = get_alt_names(hostinfo.cert) + if hostinfo.hostname not in alt_names: + alt_names.insert(0, hostinfo.hostname) + output_string += f"{settings['sep']}".join(alt_names) + print(output_string) + return None + output_string += ( + f"\n{hostinfo.hostname} " f"({hostinfo.peername[0]}:{hostinfo.peername[1]})\n" + ) + output_string += f" commonName: {get_common_name(hostinfo.cert)}\n" + output_string += f" issuer: {get_issuer(hostinfo.cert)}\n" + output_string += f" notBefore: {hostinfo.cert.not_valid_before}\n" + output_string += f" notAfter: {hostinfo.cert.not_valid_after}\n" + if settings["valid"]: + output_string += f" Valid: {hostinfo.is_valid}\n" + if settings["san"]: + output_string += f" SAN: {get_alt_names(hostinfo.cert)}\n" + if hostinfo.is_valid and settings["color"]: + click.echo(click.style(output_string, fg="green")) + elif not hostinfo.is_valid and settings["color"]: + click.echo(click.style(output_string, fg="red")) + else: + click.echo(click.style(output_string)) + return None + + @click.command() @click.version_option(__version__, prog_name="checkcert") @click.option("--san", is_flag=True, help="Output Subject Alternate Names") @@ -133,38 +165,19 @@ def main(san, dump, color, filename, valid, san_only, sep, pre, hosts): all_hosts = get_host_list_tuple(hosts) with concurrent.futures.ThreadPoolExecutor(max_workers=4) as epool: for hostinfo in epool.map(lambda x: get_certificate(x[0], x[1]), all_hosts): - output_string = "\n" if dump: print(get_x509_text(hostinfo.cert).decode()) else: - if san_only: - output_string = "" - if pre: - output_string += f"{sep}".lstrip() - alt_names = get_alt_names(hostinfo.cert) - if hostinfo.hostname not in alt_names: - alt_names.insert(0, hostinfo.hostname) - output_string += f"{sep}".join(alt_names) - print(output_string) - break - output_string += ( - f"{hostinfo.hostname} " - f"({hostinfo.peername[0]}:{hostinfo.peername[1]})\n" - ) - output_string += f" commonName: {get_common_name(hostinfo.cert)}\n" - output_string += f" issuer: {get_issuer(hostinfo.cert)}\n" - output_string += f" notBefore: {hostinfo.cert.not_valid_before}\n" - output_string += f" notAfter: {hostinfo.cert.not_valid_after}\n" - if valid: - output_string += f" Valid: {hostinfo.is_valid}\n" - if san: - output_string += f" SAN: {get_alt_names(hostinfo.cert)}\n" - if hostinfo.is_valid and color: - click.echo(click.style(output_string, fg="green")) - elif not hostinfo.is_valid and color: - click.echo(click.style(output_string, fg="red")) - else: - click.echo(click.style(output_string)) + settings_dict = { + "san": san, + "sep": sep, + "dump": dump, + "color": color, + "valid": valid, + "san_only": san_only, + "pre": pre, + } + print_output(hostinfo, settings_dict) if __name__ == "__main__": From 21076b20c7fc4ff5fd82788d7a8095f6d9da27ec Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Thu, 7 Oct 2021 15:26:46 -0400 Subject: [PATCH 42/47] refactor: add hostinfo type for type validation --- checkcert/checkcert.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index ae3da06..717d81a 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -89,7 +89,7 @@ def get_host_list_tuple(hosts: list) -> List[Tuple[str, int]]: return all_hosts -def print_output(hostinfo, settings: dict) -> None: +def print_output(hostinfo: HostInfo, settings: dict) -> None: """print the output of hostinfo conditionally based on items in settings""" output_string = "" if settings["san_only"]: @@ -100,6 +100,8 @@ def print_output(hostinfo, settings: dict) -> None: alt_names.insert(0, hostinfo.hostname) output_string += f"{settings['sep']}".join(alt_names) print(output_string) + # in the san-only branch, once we get to this point the output is + # already complete, so just return to end the function processing return None output_string += ( f"\n{hostinfo.hostname} " f"({hostinfo.peername[0]}:{hostinfo.peername[1]})\n" From 036692ba3571ec27d9234e7a444bf87927b98d7e Mon Sep 17 00:00:00 2001 From: semantic-release Date: Thu, 7 Oct 2021 15:27:11 -0400 Subject: [PATCH 43/47] 0.7.1 Automatically generated by python-semantic-release --- checkcert/checkcert.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index d9e97c1..9ae211d 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -11,7 +11,7 @@ from cryptography.x509.oid import NameOID import idna -__version__ = "0.7.0" +__version__ = "0.7.1" HostInfo = namedtuple("HostInfo", ["cert", "hostname", "peername", "is_valid"]) diff --git a/pyproject.toml b/pyproject.toml index 44c80cc..8601238 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "checkcert" -version = "0.7.0" +version = "0.7.1" description = "CLI to check tls cert information and determine validity" authors = ["Alex Kelly "] readme = "README.md" From 15c165074b8b567af6593df28ec87191132abef3 Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Fri, 8 Oct 2021 09:59:57 -0400 Subject: [PATCH 44/47] refactor: correct type hinting for certs --- checkcert/checkcert.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 717d81a..4664cb7 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -7,6 +7,7 @@ import click from OpenSSL import SSL from OpenSSL import crypto from cryptography import x509 +from OpenSSL.crypto import X509 from cryptography.x509.oid import NameOID import idna @@ -41,7 +42,7 @@ def get_certificate(hostname: str, port: int) -> HostInfo: ) -def get_alt_names(cert: Any) -> Any: +def get_alt_names(cert: x509.Certificate) -> Any: """retrieve the SAN values for given cert""" try: ext = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName) @@ -50,12 +51,12 @@ def get_alt_names(cert: Any) -> Any: return None -def get_x509_text(cert: Any) -> Any: +def get_x509_text(cert: X509) -> bytes: """return the human-readable text version of the certificate""" return crypto.dump_certificate(crypto.FILETYPE_TEXT, cert) -def get_common_name(cert: Any) -> Any: +def get_common_name(cert: x509.Certificate) -> Any: """Return the common name from the certificate""" try: names = cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME) @@ -64,7 +65,7 @@ def get_common_name(cert: Any) -> Any: return None -def get_issuer(cert: Any) -> Any: +def get_issuer(cert: x509.Certificate) -> Any: """Return the name of the CA/Issuer of the certificate""" try: names = cert.issuer.get_attributes_for_oid(NameOID.COMMON_NAME) From bbfe16ed28967192f971dc02189f368b012b1b7f Mon Sep 17 00:00:00 2001 From: Alex Kelly Date: Fri, 22 Oct 2021 10:57:18 -0400 Subject: [PATCH 45/47] fix: add exception for socket connection refused --- checkcert/checkcert.py | 11 +++- poetry.lock | 132 +++++++++++++++++++++++++++++------------ pyproject.toml | 1 + 3 files changed, 103 insertions(+), 41 deletions(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 4664cb7..419f02d 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -1,4 +1,5 @@ """ CLI to get basic information about certificates and determine validity""" +import sys from collections import namedtuple import concurrent.futures from socket import socket @@ -6,8 +7,8 @@ from typing import List, Tuple, Any import click from OpenSSL import SSL from OpenSSL import crypto -from cryptography import x509 from OpenSSL.crypto import X509 +from cryptography import x509 from cryptography.x509.oid import NameOID import idna @@ -22,7 +23,11 @@ def get_certificate(hostname: str, port: int) -> HostInfo: hostname_idna = idna.encode(hostname) sock = socket() - sock.connect((hostname, port)) + try: + sock.connect((hostname, port)) + except ConnectionRefusedError: + print("Error: Connection Refused") + sys.exit(3) peername = sock.getpeername() ctx = SSL.Context(SSL.SSLv23_METHOD) # most compatible sock_ssl = SSL.Connection(ctx, sock) @@ -92,7 +97,7 @@ def get_host_list_tuple(hosts: list) -> List[Tuple[str, int]]: def print_output(hostinfo: HostInfo, settings: dict) -> None: """print the output of hostinfo conditionally based on items in settings""" - output_string = "" + output_string: str = "" if settings["san_only"]: if settings["pre"]: output_string += f"{settings['sep']}".lstrip() diff --git a/poetry.lock b/poetry.lock index d0e1d94..ac653a4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -8,7 +8,7 @@ python-versions = "*" [[package]] name = "astroid" -version = "2.8.0" +version = "2.8.2" description = "An abstract syntax tree for Python with inference support." category = "dev" optional = false @@ -138,7 +138,7 @@ toml = ["toml"] [[package]] name = "cryptography" -version = "3.4.8" +version = "35.0.0" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" optional = false @@ -151,9 +151,9 @@ cffi = ">=1.12" docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"] docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] -sdist = ["setuptools-rust (>=0.11.4)"] +sdist = ["setuptools_rust (>=0.11.4)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["pytest (>=6.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] +test = ["pytest (>=6.2.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] [[package]] name = "docutils" @@ -273,7 +273,7 @@ trio = ["trio", "async-generator"] [[package]] name = "jinja2" -version = "3.0.1" +version = "3.0.2" description = "A very fast and expressive template engine." category = "dev" optional = false @@ -327,6 +327,31 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "mypy" +version = "0.910" +description = "Optional static typing for Python" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +mypy-extensions = ">=0.4.3,<0.5.0" +toml = "*" +typing-extensions = ">=3.7.4" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +python2 = ["typed-ast (>=1.4.0,<1.5.0)"] + +[[package]] +name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "packaging" version = "21.0" @@ -391,7 +416,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pyflakes" -version = "2.3.1" +version = "2.4.0" description = "passive checker of Python programs" category = "dev" optional = false @@ -527,7 +552,7 @@ python-versions = "*" [[package]] name = "readme-renderer" -version = "29.0" +version = "30.0" description = "readme_renderer is a library for rendering \"readme\" descriptions for Warehouse" category = "dev" optional = false @@ -537,10 +562,9 @@ python-versions = "*" bleach = ">=2.1.0" docutils = ">=0.13.1" Pygments = ">=2.5.1" -six = "*" [package.extras] -md = ["cmarkgfm (>=0.5.0,<0.6.0)"] +md = ["cmarkgfm (>=0.5.0,<0.7.0)"] [[package]] name = "requests" @@ -856,7 +880,7 @@ python-versions = "*" [[package]] name = "zipp" -version = "3.5.1" +version = "3.6.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "dev" optional = false @@ -869,7 +893,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes [metadata] lock-version = "1.1" python-versions = "^3.9" -content-hash = "01f9486cf3b3cb666f32f2bd4975cfdc04f41388ea389538fe428de252a0f782" +content-hash = "e6d761e045c3a735d1e875f5384d01840d28850284d11b5252823516c6d9c55f" [metadata.files] alabaster = [ @@ -877,8 +901,8 @@ alabaster = [ {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, ] astroid = [ - {file = "astroid-2.8.0-py3-none-any.whl", hash = "sha256:dcc06f6165f415220013801642bd6c9808a02967070919c4b746c6864c205471"}, - {file = "astroid-2.8.0.tar.gz", hash = "sha256:fe81f80c0b35264acb5653302ffbd935d394f1775c5e4487df745bf9c2442708"}, + {file = "astroid-2.8.2-py3-none-any.whl", hash = "sha256:9eaeaf92b3e21b70bec1a262e7eb118d2e96294892a5de595c92a12adc80dfc2"}, + {file = "astroid-2.8.2.tar.gz", hash = "sha256:304e99c129794f2cfda584a12b71fde85205da950e2f330f4be09150525ae949"}, ] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, @@ -1018,23 +1042,26 @@ coverage = [ {file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"}, ] cryptography = [ - {file = "cryptography-3.4.8-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:a00cf305f07b26c351d8d4e1af84ad7501eca8a342dedf24a7acb0e7b7406e14"}, - {file = "cryptography-3.4.8-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:f44d141b8c4ea5eb4dbc9b3ad992d45580c1d22bf5e24363f2fbf50c2d7ae8a7"}, - {file = "cryptography-3.4.8-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0a7dcbcd3f1913f664aca35d47c1331fce738d44ec34b7be8b9d332151b0b01e"}, - {file = "cryptography-3.4.8-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34dae04a0dce5730d8eb7894eab617d8a70d0c97da76b905de9efb7128ad7085"}, - {file = "cryptography-3.4.8-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1eb7bb0df6f6f583dd8e054689def236255161ebbcf62b226454ab9ec663746b"}, - {file = "cryptography-3.4.8-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:9965c46c674ba8cc572bc09a03f4c649292ee73e1b683adb1ce81e82e9a6a0fb"}, - {file = "cryptography-3.4.8-cp36-abi3-win32.whl", hash = "sha256:21ca464b3a4b8d8e86ba0ee5045e103a1fcfac3b39319727bc0fc58c09c6aff7"}, - {file = "cryptography-3.4.8-cp36-abi3-win_amd64.whl", hash = "sha256:3520667fda779eb788ea00080124875be18f2d8f0848ec00733c0ec3bb8219fc"}, - {file = "cryptography-3.4.8-pp36-pypy36_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d2a6e5ef66503da51d2110edf6c403dc6b494cc0082f85db12f54e9c5d4c3ec5"}, - {file = "cryptography-3.4.8-pp36-pypy36_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a305600e7a6b7b855cd798e00278161b681ad6e9b7eca94c721d5f588ab212af"}, - {file = "cryptography-3.4.8-pp36-pypy36_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:3fa3a7ccf96e826affdf1a0a9432be74dc73423125c8f96a909e3835a5ef194a"}, - {file = "cryptography-3.4.8-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:d9ec0e67a14f9d1d48dd87a2531009a9b251c02ea42851c060b25c782516ff06"}, - {file = "cryptography-3.4.8-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5b0fbfae7ff7febdb74b574055c7466da334a5371f253732d7e2e7525d570498"}, - {file = "cryptography-3.4.8-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94fff993ee9bc1b2440d3b7243d488c6a3d9724cc2b09cdb297f6a886d040ef7"}, - {file = "cryptography-3.4.8-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:8695456444f277af73a4877db9fc979849cd3ee74c198d04fc0776ebc3db52b9"}, - {file = "cryptography-3.4.8-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:cd65b60cfe004790c795cc35f272e41a3df4631e2fb6b35aa7ac6ef2859d554e"}, - {file = "cryptography-3.4.8.tar.gz", hash = "sha256:94cc5ed4ceaefcbe5bf38c8fba6a21fc1d365bb8fb826ea1688e3370b2e24a1c"}, + {file = "cryptography-35.0.0-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:d57e0cdc1b44b6cdf8af1d01807db06886f10177469312fbde8f44ccbb284bc9"}, + {file = "cryptography-35.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:ced40344e811d6abba00295ced98c01aecf0c2de39481792d87af4fa58b7b4d6"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:54b2605e5475944e2213258e0ab8696f4f357a31371e538ef21e8d61c843c28d"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:7b7ceeff114c31f285528ba8b390d3e9cfa2da17b56f11d366769a807f17cbaa"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d69645f535f4b2c722cfb07a8eab916265545b3475fdb34e0be2f4ee8b0b15e"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2d0e0acc20ede0f06ef7aa58546eee96d2592c00f450c9acb89c5879b61992"}, + {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:07bb7fbfb5de0980590ddfc7f13081520def06dc9ed214000ad4372fb4e3c7f6"}, + {file = "cryptography-35.0.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:7eba2cebca600a7806b893cb1d541a6e910afa87e97acf2021a22b32da1df52d"}, + {file = "cryptography-35.0.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:18d90f4711bf63e2fb21e8c8e51ed8189438e6b35a6d996201ebd98a26abbbe6"}, + {file = "cryptography-35.0.0-cp36-abi3-win32.whl", hash = "sha256:c10c797ac89c746e488d2ee92bd4abd593615694ee17b2500578b63cad6b93a8"}, + {file = "cryptography-35.0.0-cp36-abi3-win_amd64.whl", hash = "sha256:7075b304cd567694dc692ffc9747f3e9cb393cc4aa4fb7b9f3abd6f5c4e43588"}, + {file = "cryptography-35.0.0-pp36-pypy36_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a688ebcd08250eab5bb5bca318cc05a8c66de5e4171a65ca51db6bd753ff8953"}, + {file = "cryptography-35.0.0-pp36-pypy36_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d99915d6ab265c22873f1b4d6ea5ef462ef797b4140be4c9d8b179915e0985c6"}, + {file = "cryptography-35.0.0-pp36-pypy36_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:928185a6d1ccdb816e883f56ebe92e975a262d31cc536429041921f8cb5a62fd"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:ebeddd119f526bcf323a89f853afb12e225902a24d29b55fe18dd6fcb2838a76"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:22a38e96118a4ce3b97509443feace1d1011d0571fae81fc3ad35f25ba3ea999"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb80e8a1f91e4b7ef8b33041591e6d89b2b8e122d787e87eeb2b08da71bb16ad"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:abb5a361d2585bb95012a19ed9b2c8f412c5d723a9836418fab7aaa0243e67d2"}, + {file = "cryptography-35.0.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:1ed82abf16df40a60942a8c211251ae72858b25b7421ce2497c2eb7a1cee817c"}, + {file = "cryptography-35.0.0.tar.gz", hash = "sha256:9933f28f70d0517686bd7de36166dda42094eac49415459d9bdf5e7df3e0086d"}, ] docutils = [ {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, @@ -1081,8 +1108,8 @@ jeepney = [ {file = "jeepney-0.7.1.tar.gz", hash = "sha256:fa9e232dfa0c498bd0b8a3a73b8d8a31978304dcef0515adc859d4e096f96f4f"}, ] jinja2 = [ - {file = "Jinja2-3.0.1-py3-none-any.whl", hash = "sha256:1f06f2da51e7b56b8f238affdd6b4e2c61e39598a378cc49345bc1bd42a978a4"}, - {file = "Jinja2-3.0.1.tar.gz", hash = "sha256:703f484b47a6af502e743c9122595cc812b0271f661722403114f71a79d0f5a4"}, + {file = "Jinja2-3.0.2-py3-none-any.whl", hash = "sha256:8569982d3f0889eed11dd620c706d39b60c36d6d25843961f33f77fb6bc6b20c"}, + {file = "Jinja2-3.0.2.tar.gz", hash = "sha256:827a0e32839ab1600d4eb1c4c33ec5a8edfbc5cb42dafa13b81f182f97784b45"}, ] keyring = [ {file = "keyring-23.2.1-py3-none-any.whl", hash = "sha256:bd2145a237ed70c8ce72978b497619ddfcae640b6dcf494402d5143e37755c6e"}, @@ -1152,6 +1179,35 @@ mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, ] +mypy = [ + {file = "mypy-0.910-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:a155d80ea6cee511a3694b108c4494a39f42de11ee4e61e72bc424c490e46457"}, + {file = "mypy-0.910-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b94e4b785e304a04ea0828759172a15add27088520dc7e49ceade7834275bedb"}, + {file = "mypy-0.910-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:088cd9c7904b4ad80bec811053272986611b84221835e079be5bcad029e79dd9"}, + {file = "mypy-0.910-cp35-cp35m-win_amd64.whl", hash = "sha256:adaeee09bfde366d2c13fe6093a7df5df83c9a2ba98638c7d76b010694db760e"}, + {file = "mypy-0.910-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ecd2c3fe726758037234c93df7e98deb257fd15c24c9180dacf1ef829da5f921"}, + {file = "mypy-0.910-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d9dd839eb0dc1bbe866a288ba3c1afc33a202015d2ad83b31e875b5905a079b6"}, + {file = "mypy-0.910-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:3e382b29f8e0ccf19a2df2b29a167591245df90c0b5a2542249873b5c1d78212"}, + {file = "mypy-0.910-cp36-cp36m-win_amd64.whl", hash = "sha256:53fd2eb27a8ee2892614370896956af2ff61254c275aaee4c230ae771cadd885"}, + {file = "mypy-0.910-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b6fb13123aeef4a3abbcfd7e71773ff3ff1526a7d3dc538f3929a49b42be03f0"}, + {file = "mypy-0.910-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e4dab234478e3bd3ce83bac4193b2ecd9cf94e720ddd95ce69840273bf44f6de"}, + {file = "mypy-0.910-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:7df1ead20c81371ccd6091fa3e2878559b5c4d4caadaf1a484cf88d93ca06703"}, + {file = "mypy-0.910-cp37-cp37m-win_amd64.whl", hash = "sha256:0aadfb2d3935988ec3815952e44058a3100499f5be5b28c34ac9d79f002a4a9a"}, + {file = "mypy-0.910-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ec4e0cd079db280b6bdabdc807047ff3e199f334050db5cbb91ba3e959a67504"}, + {file = "mypy-0.910-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:119bed3832d961f3a880787bf621634ba042cb8dc850a7429f643508eeac97b9"}, + {file = "mypy-0.910-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:866c41f28cee548475f146aa4d39a51cf3b6a84246969f3759cb3e9c742fc072"}, + {file = "mypy-0.910-cp38-cp38-win_amd64.whl", hash = "sha256:ceb6e0a6e27fb364fb3853389607cf7eb3a126ad335790fa1e14ed02fba50811"}, + {file = "mypy-0.910-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a85e280d4d217150ce8cb1a6dddffd14e753a4e0c3cf90baabb32cefa41b59e"}, + {file = "mypy-0.910-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:42c266ced41b65ed40a282c575705325fa7991af370036d3f134518336636f5b"}, + {file = "mypy-0.910-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:3c4b8ca36877fc75339253721f69603a9c7fdb5d4d5a95a1a1b899d8b86a4de2"}, + {file = "mypy-0.910-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:c0df2d30ed496a08de5daed2a9ea807d07c21ae0ab23acf541ab88c24b26ab97"}, + {file = "mypy-0.910-cp39-cp39-win_amd64.whl", hash = "sha256:c6c2602dffb74867498f86e6129fd52a2770c48b7cd3ece77ada4fa38f94eba8"}, + {file = "mypy-0.910-py3-none-any.whl", hash = "sha256:ef565033fa5a958e62796867b1df10c40263ea9ded87164d67572834e57a174d"}, + {file = "mypy-0.910.tar.gz", hash = "sha256:704098302473cb31a218f1775a873b376b30b4c18229421e9e9dc8916fd16150"}, +] +mypy-extensions = [ + {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, + {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, +] packaging = [ {file = "packaging-21.0-py3-none-any.whl", hash = "sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14"}, {file = "packaging-21.0.tar.gz", hash = "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7"}, @@ -1177,8 +1233,8 @@ pycparser = [ {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"}, ] pyflakes = [ - {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, - {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, + {file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"}, + {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"}, ] pygments = [ {file = "Pygments-2.10.0-py3-none-any.whl", hash = "sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380"}, @@ -1217,8 +1273,8 @@ pywin32-ctypes = [ {file = "pywin32_ctypes-0.2.0-py2.py3-none-any.whl", hash = "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"}, ] readme-renderer = [ - {file = "readme_renderer-29.0-py2.py3-none-any.whl", hash = "sha256:63b4075c6698fcfa78e584930f07f39e05d46f3ec97f65006e430b595ca6348c"}, - {file = "readme_renderer-29.0.tar.gz", hash = "sha256:92fd5ac2bf8677f310f3303aa4bce5b9d5f9f2094ab98c29f13791d7b805a3db"}, + {file = "readme_renderer-30.0-py2.py3-none-any.whl", hash = "sha256:3286806450d9961d6e3b5f8a59f77e61503799aca5155c8d8d40359b4e1e1adc"}, + {file = "readme_renderer-30.0.tar.gz", hash = "sha256:8299700d7a910c304072a7601eafada6712a5b011a20139417e1b1e9f04645d8"}, ] requests = [ {file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"}, @@ -1325,6 +1381,6 @@ wrapt = [ {file = "wrapt-1.12.1.tar.gz", hash = "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"}, ] zipp = [ - {file = "zipp-3.5.1-py3-none-any.whl", hash = "sha256:8dc6c4d5a809d659067cc713f76bcf42fae8ae641db12fddfa93694a15abc96b"}, - {file = "zipp-3.5.1.tar.gz", hash = "sha256:1fc9641b26f3bd81069b7738b039f2819cab6e3fc3399a953e19d92cc81eff4d"}, + {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"}, + {file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"}, ] diff --git a/pyproject.toml b/pyproject.toml index f11106c..d1ed4c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ pyflakes = "^2.3.1" pytest = "^6.2.5" Sphinx = "^4.2.0" sphinx-rtd-theme = "^1.0.0" +mypy = "^0.910" [build-system] requires = ["poetry-core>=1.0.0"] From 9183302a1f77bdea52336f3da9afdd8d40df3f7f Mon Sep 17 00:00:00 2001 From: semantic-release Date: Fri, 22 Oct 2021 10:57:29 -0400 Subject: [PATCH 46/47] 0.7.0 Automatically generated by python-semantic-release --- checkcert/checkcert.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 419f02d..2146f20 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -13,7 +13,7 @@ from cryptography.x509.oid import NameOID import idna -__version__ = "0.6.0" +__version__ = "0.7.0" HostInfo = namedtuple("HostInfo", ["cert", "hostname", "peername", "is_valid"]) diff --git a/pyproject.toml b/pyproject.toml index d1ed4c9..bd39a89 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "checkcert" -version = "0.6.0" +version = "0.7.0" description = "CLI to check tls cert information and determine validity" authors = ["Alex Kelly "] readme = "README.md" From 884641494032a8baa6d24416940c01329115cb9e Mon Sep 17 00:00:00 2001 From: semantic-release Date: Fri, 22 Oct 2021 10:59:19 -0400 Subject: [PATCH 47/47] 0.7.2 Automatically generated by python-semantic-release --- checkcert/checkcert.py | 2 +- pyproject.toml | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/checkcert/checkcert.py b/checkcert/checkcert.py index 8c67450..687fbc3 100644 --- a/checkcert/checkcert.py +++ b/checkcert/checkcert.py @@ -13,7 +13,7 @@ from cryptography.x509.oid import NameOID import idna -__version__ = "0.7.1" +__version__ = "0.7.2" HostInfo = namedtuple("HostInfo", ["cert", "hostname", "peername", "is_valid"]) diff --git a/pyproject.toml b/pyproject.toml index 3b1f1ec..7ba3dcd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,6 @@ [tool.poetry] name = "checkcert" -<<<<<<< HEAD -version = "0.7.0" -======= -version = "0.7.1" ->>>>>>> main +version = "0.7.2" description = "CLI to check tls cert information and determine validity" authors = ["Alex Kelly "] readme = "README.md"