This commit is contained in:
fenris 2026-04-03 01:05:31 +02:00
commit 6b38521bea
5 changed files with 191 additions and 0 deletions

8
readme.md Normal file
View file

@ -0,0 +1,8 @@
# tls-utils
## Running
### Requirements
- Python3

View file

@ -0,0 +1,78 @@
import subprocess as _subprocess
def get_certificate_info_raw(source):
p1 = _subprocess.Popen(
["openssl", "x509", "-outform", "pem"],
stdin = _subprocess.PIPE,
stdout = _subprocess.PIPE
)
(p1_stdout, p1_stderr, ) = p1.communicate(input = bytes(source, "utf-8"))
p2 = _subprocess.Popen(
["openssl", "x509", "-noout", "-text"],
stdin = _subprocess.PIPE,
stdout = _subprocess.PIPE
)
(p2_stdout, p2_stderr, ) = p2.communicate(input = p1_stdout)
return p2_stdout.decode("utf-8")
def get_certificate_info_from_file(path):
return get_certificate_info_raw(
_subprocess.check_output(
["cat", path],
text = True
)
)
def get_certificate_info_from_internet(domain):
return get_certificate_info_raw(
_subprocess.check_output(
["openssl", "s_client", "-connect", ("%s:443" % domain), "-showcerts"],
stdin = _subprocess.DEVNULL,
stderr = _subprocess.DEVNULL,
text = True
)
)
def extract_fingerprint(certificate_info):
state = {
"situation": 0,
"result": "",
}
for line in certificate_info.split("\n"):
if (state["situation"] == 0):
if (line.strip() == "Subject Public Key Info:"):
state = {
"situation": 1,
"result": state["result"],
}
else:
pass
elif (state["situation"] == 1):
if (line.strip() == "pub:"):
state = {
"situation": 2,
"result": state["result"],
}
else:
pass
elif (state["situation"] == 2):
if (line.startswith(" ")):
state = {
"situation": 2,
"result": (state["result"] + line.strip().replace(":", "")),
}
else:
state = {
"situation": 3,
"result": state["result"]
}
break
else:
pass
return state["result"]

7
source/helpers/string.py Normal file
View file

@ -0,0 +1,7 @@
def coin(template, arguments):
result = template
for (key, value, ) in arguments.items():
result = result.replace("{{%s}}" % key, value)
return result

62
source/verify.py Normal file
View file

@ -0,0 +1,62 @@
import sys as _sys
import argparse as _argparse
import helpers.string as _string
import helpers.certinfo as _certinfo
def main():
## args
argument_parser = _argparse.ArgumentParser(
prog = "tls-verify",
description = "compares the fingerprints of a TLS certificate on the machine with the one delivered through the internet for a given domain",
)
argument_parser.add_argument(
"domain",
type = str,
metavar = "<domain>",
)
argument_parser.add_argument(
"-d",
"--cert-directory",
type = str,
default = "/etc/ssl/fullchains",
metavar = "<cert-directory>",
)
argument_parser.add_argument(
"-e",
"--file-extension",
type = str,
default = "pem",
metavar = "<file-extension>",
)
args = argument_parser.parse_args()
## exec
fingerprint_shall = _certinfo.extract_fingerprint(
_certinfo.get_certificate_info_from_file(
_string.coin(
"{{directory}}/{{domain}}.{{extension}}",
{
"directory": args.cert_directory,
"domain": args.domain,
"extension": args.file_extension
}
)
)
)
fingerprint_is = _certinfo.extract_fingerprint(
_certinfo.get_certificate_info_from_internet(
args.domain
)
)
if (fingerprint_shall == fingerprint_is):
_sys.stdout.write("ok\n")
_sys.exit(0)
else:
_sys.stderr.write("!MISMATCH!\n")
_sys.stderr.write("[shall] %s\n" % fingerprint_shall)
_sys.stderr.write("[is ] %s\n" % fingerprint_is)
_sys.exit(1)

36
tools/build Executable file
View file

@ -0,0 +1,36 @@
#!/usr/bin/env sh
## consts
dir_source="source"
dir_temp="/tmp/tls-utils-temp"
dir_build="/tmp/tls-utils"
## vars
path_verify=${dir_build}/tls-verify
## exec
### exec:verify
rm ${dir_temp} --force --recursive
mkdir ${dir_temp} --parents
cp ${dir_source}/. ${dir_temp}/ --recursive --update --verbose
for dir in $(find ${dir_temp} -mindepth 1 -type d) ; do touch ${dir}/__init__.py ; done
echo '' > ${dir_temp}/__main__.py
echo 'from verify import *' >> ${dir_temp}/__main__.py
echo 'if __name__ == "__main__": main()' >> ${dir_temp}/__main__.py
mkdir ${dir_build} --parents
# rm ${path_verify}.zip --force
cd ${dir_temp}
python3 -m zipfile -c ${path_verify}.zip .
cd -
echo '#!/usr/bin/env python3' > ${path_verify}
cat ${path_verify}.zip >> ${path_verify}
rm ${path_verify}.zip
chmod +x ${path_verify}