Debian Verifier
1. Introdução
Sempre que se recomenda que a assinatura digital e os hashes de um arquivo sejam verificados, o usuário comum esbarra em algumas dificuldades para compreender o processo e executar os comandos necessários. Algumas vezes por falta de conhecimento técnico, outras porque o processo pode variar de acordo com a forma como a assinatura foi gerada ou com a criptografia usada.
O script Debian Verifier faz apenas isso: baixa a imagem, a assinatura digital e os hashes do Debian Linux e verifica se a assinatura é válida e se os hashes são os mesmos. É um script (bash ou python) que não precisa de privilégios de root e roda no macOS e no Linux (a versão python deve rodar também no Windows). Assim como no casos dos pacotes do Decred verificados pelo Decred Verifier, foi gerado um hash SHA-256 de cada arquivo, esses hashes foram inseridos em um arquivo de texto chamado SHA256SUMS
, e esse arquivo foi digitalmente assinado.
Para baixar a chave pública que verifica a autenticidade do Debian Linux será iniciada uma conexão TCP 11371 (hkp) para falar com o servidor de chaves do Debian e para baixar a imagem do Debian Linux será necessário falar TCP 443 (https) com o site oficial.
Saiba mais sobre a verificação de assinaturas digitais ou sobre os procedimentos para verificação da assinatura digital do Debian Linux.
2. Bash Script
Para executar o script, copie o código de ~200 linhas para um arquivo local e adicione o atributo de execução como mostrado a seguir:
$ chmod +x debian_verifier.sh
Debian Verifier:
#! /bin/bash -
# Debian Verifier v0.2.1
# This script downloads and verifies the digital signature of Debian Linux (stables releases only).
# Reference: https://www.debian.org/CD/verify
# Author: Marcelo Martins (stakey.club)
# Syntax: debian_verifier.sh -v [version number | "current"] -a $ARCH -m ["cd" | "dvd"]
# -v: Debian version: defaults to 'current' if left blank. Ex: 9.8.0
# -a: Architecture: amd64, arm64, armel, armhf, i386, mips, mips64el, mipsel, ppc64el, s390x, source or multi-arch
# $ARCH defaults to 'multi-arch' if left blank
# -m: Media type: 'cd' or 'dvd', defaults to 'cd' if left blank
# Examples: ./debian_verifier.sh
# ./debian_verifier.sh -v 9.8.0 -a i386 -m dvd
# ./debian_verifier.sh -v 9.8.0 -a amd64 -m cd
usage() {
echo "Usage: $0 [-v <string>] [-a <\$ARCH>] [-m <cd|dvd>]" 1>&2
echo "-v: Debian version: defaults to 'current' if left blank. Ex: 9.8.0"
echo "-a: \$ARCH may be one of these: amd64, arm64, armel, armhf, i386, mips, mips64el, mipsel, ppc64el, s390x, multi-arch"
echo " \$ARCH defaults to 'multi-arch' if left blank"
echo "-m: Media type: 'cd' or 'dvd', defaults to 'cd' if left blank"
exit 1
}
while getopts ":a:v:m:" o; do
case "${o}" in
a)
a=${OPTARG}
;;
v)
v=${OPTARG}
;;
m)
m=${OPTARG}
;;
*)
usage
;;
esac
done
shift $((OPTIND-1))
if [[ -z ${v} ]]; then
VERSION="current"
elif [[ ${v} =~ ^[0-9]\.[0-9]{1,2}\.?[0-9]{0,2} ]]; then
VERSION=${v}
else
echo -e "ERROR: Package version seems to be in the wrong format.\n"
usage
fi
if [[ -z ${a} || ${a} == "multi-arch" ]]; then
ARCH_DIR="multi-arch"
ARCH_FILE="amd64-i386"
elif [[ ${a} =~ [amd64|arm64|armel|armhf|i386|mips|mips64el|mipsel|ppc64el|s390x] ]]; then
ARCH_DIR=${a}
ARCH_FILE=${a}
else
echo -e "ERROR: Architecture is invalid.\n"
usage
fi
if [[ -z ${m} || ${m} == "cd" ]]; then
MEDIA_DIR="iso-cd"
MEDIA_FILE="netinst"
MEDIA="CD"
elif [[ ${m} == "dvd" ]]; then
MEDIA_DIR="iso-dvd"
MEDIA_FILE="DVD-1"
MEDIA="DVD"
else
echo -e "ERROR: Media is invalid.\n"
usage
fi
ARCHIVE_DOWNLOAD="https://cdimage.debian.org/cdimage/archive/$VERSION/$ARCH_DIR/$MEDIA_DIR"
RELEASE_DOWNLOAD="https://cdimage.debian.org/debian-cd/$VERSION/$ARCH_DIR/$MEDIA_DIR"
DEBIAN_DOWNLOAD=""
DEBIAN_MANIFEST="SHA256SUMS"
DEBIAN_MANIFEST_SIGN="SHA256SUMS.sign"
DEBIAN_KEYHOST="keyring.debian.org"
# The keys will be kept hardcoded.
DEBIAN_KEY_FP=(64E6EA7D 6294BE9B 09EA8AC3)
DEBIAN_KEY_ID=()
for k in ${!DEBIAN_KEY_FP[*]}; do
DEBIAN_KEY_ID=${DEBIAN_KEY_ID[*]}" 0x"${DEBIAN_KEY_FP[k]}
done
[[ ! -x `which gpg` ]] && echo "ERROR: Could not locate gpg." && exit 5
if [[ `uname -a | grep -c "Darwin"` -gt 0 ]]; then
FLAVOR="Mac"
[[ ! -x `which curl` ]] && echo "ERROR: Could not locate curl." && exit 6
LATEST_VERSION=`curl -Ssf -L https://cdimage.debian.org/debian-cd/ | grep '[0-9]\{1,2\}\.[0-9]\{1,2\}.*/' | grep "folder" | grep -v "live" | cut -d'>' -f 3 | cut -d'"' -f 2 | cut -d'/' -f 1`
if [[ $VERSION == "current" || $VERSION == $LATEST_VERSION ]]; then
VERSION_NUMBER=`curl -s -L $RELEASE_DOWNLOAD | grep -m 1 "debian-[0-9]" | cut -d'>' -f 3 | cut -d'-' -f 2`
DEBIAN_DOWNLOAD=$RELEASE_DOWNLOAD
else
VERSION_NUMBER=$VERSION
DEBIAN_DOWNLOAD=$ARCHIVE_DOWNLOAD
fi
if [[ `curl -Is $DEBIAN_DOWNLOAD/ | head -n 1 | grep -c "404"` -gt 0 ]]; then
echo "ERROR: could not find folder $DEBIAN_DOWNLOAD/."
if [[ $DEBIAN_DOWNLOAD == $ARCHIVE_DOWNLOAD ]]; then
echo "The latest version of Debian Linux is $LATEST_VERSION."
echo "You asked for version $VERSION, for platform $ARCH_DIR in $MEDIA_DIR media."
echo "There is a chance this media does not exist in the archives anymore."
fi
exit 8
fi
else
FLAVOR="Linux"
[[ ! -x `which wget` ]] && echo "ERROR: Could not locate wget." && exit 7
LATEST_VERSION=`wget -q -O - https://cdimage.debian.org/debian-cd/ | grep '[0-9]\{1,2\}\.[0-9]\{1,2\}.*/' | grep "folder" | grep -v "live" | cut -d'>' -f 3 | cut -d'"' -f 2 | cut -d'/' -f 1`
if [[ $VERSION == "current" || $VERSION == $LATEST_VERSION ]]; then
VERSION_NUMBER=`wget -q -O - $RELEASE_DOWNLOAD | grep -m 1 "debian-[0-9]" | cut -d'>' -f 3 | cut -d'-' -f 2`
DEBIAN_DOWNLOAD=$RELEASE_DOWNLOAD
else
VERSION_NUMBER=$VERSION
DEBIAN_DOWNLOAD=$ARCHIVE_DOWNLOAD
fi
if [[ `wget -S -nv -q -O - $DEBIAN_DOWNLOAD/ | head -n 1 | grep -c "404"` -gt 0 ]]; then
echo "ERROR: could not find folder $DEBIAN_DOWNLOAD/."
if [[ $DEBIAN_DOWNLOAD == $ARCHIVE_DOWNLOAD ]]; then
echo "The latest version of Debian Linux is $LATEST_VERSION."
echo "You asked for version $VERSION, for platform $ARCH_DIR in $MEDIA_DIR media."
echo "There is a chance this media does not exist in the archives anymore."
fi
exit 8
fi
fi
DEBIAN_IMAGE="debian-$VERSION_NUMBER-$ARCH_FILE-$MEDIA_FILE.iso"
GREP_STRING="'"
for k in ${!DEBIAN_KEY_FP[*]}; do
GREP_STRING="$GREP_STRING\|${DEBIAN_KEY_FP[k]}"
done
GREP_STRING="$GREP_STRING\|'"
if [[ `gpg --with-colons -k "Debian" | grep 'fpr' | grep -c "$GREP_STRING"` -eq 3 ]]; then
echo "Debian signing public keys { ${DEBIAN_KEY_ID[*]} } have already been imported."
else
# Uses keyring.debian.org to import the key (uses HKP, depends on TCP 11371).
for i in ${!DEBIAN_KEY_ID[*]}; do
if [[ `gpg --with-colons -k "Debian" | grep 'fpr' | grep -c ${DEBIAN_KEY_FP[i]}` -eq 0 ]]; then
echo "Importing Debian signing public key ${DEBIAN_KEY_ID[i]} from $DEBIAN_KEYHOST"
GPG_OUT=$(gpg --with-colons --status-fd 1 --keyserver $DEBIAN_KEYHOST --recv-keys ${DEBIAN_KEY_ID[i]} 2> /dev/null)
if [[ `echo $GPG_OUT | grep -c "FAILURE"` -eq 1 ]]; then
echo "[ FAIL ] GPG failed to import key ${DEBIAN_KEY_ID[i]} from $DEBIAN_KEYHOST. It may have timed out."
echo "Make sure you can send traffic using port TCP 11371."
exit 2
fi
fi
done
fi
DOWNLOAD_DIR=${DEBIAN_IMAGE%.*} # Manifest and signature files have the same name for all versions.
[[ ! -d $DOWNLOAD_DIR ]] && mkdir $DOWNLOAD_DIR
if [[ ! -f $DOWNLOAD_DIR/$DEBIAN_IMAGE || ! -f $DOWNLOAD_DIR/$DEBIAN_MANIFEST || ! -f $DOWNLOAD_DIR/$DEBIAN_MANIFEST_SIGN ]]; then
echo "Downloading files from Debian website to local directory '$DOWNLOAD_DIR'..."
if [[ $FLAVOR == "Mac" ]]; then
[[ ! -f $DOWNLOAD_DIR/$DEBIAN_IMAGE ]] && echo "- $DEBIAN_IMAGE" && curl -C - -L -# $DEBIAN_DOWNLOAD/$DEBIAN_IMAGE -o $DOWNLOAD_DIR/$DEBIAN_IMAGE
[[ ! -f $DOWNLOAD_DIR/$DEBIAN_MANIFEST ]] && echo "- $DEBIAN_MANIFEST" && curl -L -# $DEBIAN_DOWNLOAD/$DEBIAN_MANIFEST -o $DOWNLOAD_DIR/$DEBIAN_MANIFEST
[[ ! -f $DOWNLOAD_DIR/$DEBIAN_MANIFEST_SIGN ]] && echo "- $DEBIAN_MANIFEST_SIGN" && curl -L -# $DEBIAN_DOWNLOAD/$DEBIAN_MANIFEST_SIGN -o $DOWNLOAD_DIR/$DEBIAN_MANIFEST_SIGN
else
[[ ! -f $DOWNLOAD_DIR/$DEBIAN_IMAGE ]] && wget -c -nv -q --show-progress $DEBIAN_DOWNLOAD/$DEBIAN_IMAGE -O $DOWNLOAD_DIR/$DEBIAN_IMAGE
[[ ! -f $DOWNLOAD_DIR/$DEBIAN_MANIFEST ]] && wget -nv -q --show-progress $DEBIAN_DOWNLOAD/$DEBIAN_MANIFEST -O $DOWNLOAD_DIR/$DEBIAN_MANIFEST
[[ ! -f $DOWNLOAD_DIR/$DEBIAN_MANIFEST_SIGN ]] && wget -nv -q --show-progress $DEBIAN_DOWNLOAD/$DEBIAN_MANIFEST_SIGN -O $DOWNLOAD_DIR/$DEBIAN_MANIFEST_SIGN
fi
else
echo "All files have already been copied to local directory '$DOWNLOAD_DIR'."
echo "- $DEBIAN_IMAGE"
echo "- $DEBIAN_MANIFEST"
echo "- $DEBIAN_MANIFEST_SIGN"
fi
echo -e "\nVerifying digital signature and hashes...\n"
GPG_OUT2=$(gpg --with-colons --status-fd 1 --verify $DOWNLOAD_DIR/$DEBIAN_MANIFEST_SIGN 2> /dev/null)
if [[ `echo $GPG_OUT2 | grep -c "GOOD"` -eq 1 ]]; then
if [[ $FLAVOR == "Mac" ]]; then
[[ ! -x `which shasum` ]] && echo "ERROR: Could not locate shasum." && exit 9
SHASUM=`shasum -a 256 $DOWNLOAD_DIR/$DEBIAN_IMAGE | cut -d' ' -f1`
else # Linux or ARM
[[ ! -x `which sha256sum` ]] && echo "ERROR: Could not locate sha256sum." && exit 9
SHASUM=`sha256sum $DOWNLOAD_DIR/$DEBIAN_IMAGE | cut -d' ' -f1`
fi
if [[ `grep -c $SHASUM $DOWNLOAD_DIR/$DEBIAN_MANIFEST` -eq 1 ]]; then
echo -e "[ SUCCESS ] GPG signature for $DEBIAN_MANIFEST successfully verified."
echo -e "[ SUCCESS ] SHA-256 hash of $DEBIAN_IMAGE successfully verified.\n"
# The script won't delete files.
echo -e "It's now safe to delete files $DEBIAN_MANIFEST and $DEBIAN_MANIFEST_SIGN\n"
echo "RESULT: SUCCESS. It means that $DEBIAN_IMAGE wasn't modified after its creation"
echo "and that the file $DEBIAN_MANIFEST that contains the proof was signed by Debian signing private key."
echo -e "Learn more at https://stakey.club/en/verifying-digital-signatures/\n"
# The script won't do anything to the downloaded image.
echo "To use the image:"
echo "1. burn $DEBIAN_IMAGE to a $MEDIA; or"
echo "2. use it to boot a virtual machine"
else
echo -e "[ SUCCESS ] GPG signature for $DEBIAN_IMAGE successfully verified."
echo -e "[ FAIL ] SHA-256 hash of $DEBIAN_IMAGE verification FAILED!\n"
echo "RESULT: FAIL. It means that the manifest wasn't modified after its creation"
echo "but $DEBIAN_IMAGE is incomplete or was probably modified after its creation."
exit 3
fi
else
echo -e "[ FAIL ] GPG did not find a \"good signature\" for $DEBIAN_IMAGE. Verification FAILED!"
exit 4
fi
3. Python Script
Para executar o script no Python será necessário instalar também os pacotes abaixo. No Windows, será necessário instalar o Python e o gpg4win:
$ sudo pip install python-gnupg
$ sudo pip install certifi
$ python debian_verifier.sh
Debian Verifier:
#!/usr/bin/env python3
import argparse
from pathlib import Path
import re
import urllib.request
import ssl
import hashlib
import gnupg
import shutil
import certifi
# Debian Verifier v0.2
# This script downloads and verifies the digital signature of Debian Linux (stables releases only).
# Reference: https://www.debian.org/CD/verify
# Author: Marcelo Martins (stakey.club)
# Syntax: debian_verifier.py -v [version number | "current"] -a $ARCH -m ["cd" | "dvd"]
# -v: Debian version: defaults to 'current' if left blank. Ex: 9.8.0
# -a: Architecture: amd64, arm64, armel, armhf, i386, mips, mips64el, mipsel, ppc64el, s390x, source or multi-arch
# $ARCH defaults to 'multi-arch' if left blank
# -m: Media type: 'cd' or 'dvd', defaults to 'cd' if left blank
# Examples: $ python debian_verifier.py
# $ python debian_verifier.py -v 9.8.0 -a i386 -m dvd
# $ python debian_verifier.py -v 9.8.0 -a amd64 -m cd
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--version", help="Version to download", dest='version')
parser.add_argument("-a", "--arch", help="Architecture", dest='arch')
parser.add_argument("-m", "--media", help="Media", dest='media')
args = parser.parse_args()
__version__ = '0.2'
def usage():
print("Usage: $0 [-v <string>] [-a <$ARCH>] [-m <cd|dvd>]")
print("-v: Debian version: defaults to 'current' if left blank. Ex: 9.8.0")
print("-a: $ARCH may be one of these: amd64, arm64, armel, armhf, i386, mips, mips64el, "
"mipsel, ppc64el, s390x, multi-arch")
print(" $ARCH defaults to 'multi-arch' if left blank")
print("-m: Media type: 'cd' or 'dvd', defaults to 'cd' if left blank")
exit(1)
if not args.version:
VERSION = "current"
elif re.search('^[0-9]{1,2}.[0-9]{1,2}.?[0-9]{0,2}', args.version):
VERSION = args.version
else:
VERSION = ""
print("ERROR: Package version seems to be in the wrong format.\n")
usage()
if not args.arch:
ARCH_DIR = "multi-arch"
ARCH_FILE = "amd64-i386"
elif re.search('amd64|arm64|armel|armhf|i386|mips|mips64el|mipsel|ppc64el|s390x', args.arch):
ARCH_DIR = args.arch
ARCH_FILE = args.arch
else:
ARCH_DIR, ARCH_FILE = "", ""
print("ERROR: Architecture is invalid.\n")
usage()
if not args.media or args.media == "cd":
MEDIA_DIR = "iso-cd"
MEDIA_FILE = "netinst"
MEDIA = "CD"
elif args.media == "dvd":
MEDIA_DIR = "iso-dvd"
MEDIA_FILE = "DVD-1"
MEDIA = "DVD"
else:
MEDIA_DIR, MEDIA_FILE, MEDIA = "", "", ""
print("ERROR: Media is invalid.\n")
usage()
HASH_BLOCKSIZE = 65536
ARCHIVE_DOWNLOAD = "https://cdimage.debian.org/cdimage/archive/" + VERSION + "/" + ARCH_DIR + "/" + MEDIA_DIR
RELEASE_DOWNLOAD = "https://cdimage.debian.org/debian-cd/" + VERSION + "/" + ARCH_DIR + "/" + MEDIA_DIR
DEBIAN_DOWNLOAD = ""
DEBIAN_MANIFEST = "SHA256SUMS"
DEBIAN_MANIFEST_SIGN = "SHA256SUMS.sign"
DEBIAN_KEYHOST = "keyring.debian.org"
# The keys will be kept hardcoded.
DEBIAN_KEY_FP = ["64E6EA7D", "6294BE9B", "09EA8AC3"]
DEBIAN_KEY_ID = []
for k in DEBIAN_KEY_FP:
DEBIAN_KEY_ID.append("0x" + k)
client_context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT)
client_context.options |= ssl.OP_NO_TLSv1
client_context.options |= ssl.OP_NO_TLSv1_1
client_context.load_default_certs(purpose=ssl.Purpose.SERVER_AUTH)
client_context.load_verify_locations(capath=certifi.where())
LATEST_VERSION = re.search('([0-9]{1,2}.[0-9]{1,2}.?[0-9]{0,2}?)/',
str(urllib.request.urlopen("https://cdimage.debian.org/debian-cd/",
context=client_context).read(3000))).group(1)
if VERSION == "current" or VERSION == LATEST_VERSION:
VERSION_NUMBER = re.search('debian-([0-9]{1,2}.[0-9]{1,2}.?[0-9]{0,2})',
str(urllib.request.urlopen(RELEASE_DOWNLOAD,
context=client_context).read(9000))).group(1)
DEBIAN_DOWNLOAD = RELEASE_DOWNLOAD
else:
VERSION_NUMBER = VERSION
DEBIAN_DOWNLOAD = ARCHIVE_DOWNLOAD
response = urllib.request.urlopen(DEBIAN_DOWNLOAD, context=client_context)
if response.code == 404:
print("ERROR: could not find folder", DEBIAN_DOWNLOAD + "/.")
if DEBIAN_DOWNLOAD == ARCHIVE_DOWNLOAD:
print("The latest version of Debian Linux is", LATEST_VERSION + ".")
print("You asked for version", VERSION + ", for platform", ARCH_DIR, "in", MEDIA_DIR, "media.")
print("There is a chance this media does not exist in the archives anymore.")
exit(8)
DEBIAN_IMAGE = "debian-" + VERSION_NUMBER + "-" + ARCH_FILE + "-" + MEDIA_FILE + ".iso"
gpg = gnupg.GPG()
if len(list(set(re.findall("|".join(DEBIAN_KEY_FP), str(gpg.list_keys(keys=DEBIAN_KEY_ID)))))) == 3:
print("Debian signing public keys", DEBIAN_KEY_ID, "have already been imported.")
else:
# Uses keyring.debian.org to import the key (uses HKP, depends on TCP 11371).
for idx, k in enumerate(DEBIAN_KEY_FP):
if len(list(set(re.findall(str(k), str(gpg.list_keys(keys=DEBIAN_KEY_ID)))))) == 0:
print("Importing Debian signing public key", DEBIAN_KEY_ID[idx], "from", DEBIAN_KEYHOST)
gpg_out = gpg.recv_keys(DEBIAN_KEYHOST, DEBIAN_KEY_ID)
if not gpg_out.results[0]['ok']:
print("[ FAIL ] GPG failed to import key ${DEBIAN_KEY_ID[i]} from", DEBIAN_KEYHOST,
". It may have timed out.")
print("Make sure you can send traffic using port TCP 11371.")
exit(2)
DOWNLOAD_DIR = "debian-" + VERSION_NUMBER + "-" + ARCH_FILE + "-" + MEDIA_FILE
not Path(DOWNLOAD_DIR).is_dir() and Path(DOWNLOAD_DIR).mkdir()
if not Path(DOWNLOAD_DIR + "/" + DEBIAN_IMAGE).is_file() and \
not Path(DOWNLOAD_DIR + "/" + DEBIAN_MANIFEST).is_file() and \
not Path(DOWNLOAD_DIR + "/" + DEBIAN_MANIFEST_SIGN).is_file():
print("Downloading files from Debian website to local directory '" + DOWNLOAD_DIR + "'...")
if not Path(DOWNLOAD_DIR + "/" + DEBIAN_MANIFEST_SIGN).is_file():
print("-", DEBIAN_MANIFEST_SIGN)
with urllib.request.urlopen(DEBIAN_DOWNLOAD + "/" + DEBIAN_MANIFEST_SIGN, context=client_context) as response, \
open(DOWNLOAD_DIR + "/" + DEBIAN_MANIFEST_SIGN, 'wb') as out_file:
shutil.copyfileobj(response, out_file)
if not Path(DOWNLOAD_DIR + "/" + DEBIAN_MANIFEST).is_file():
print("-", DEBIAN_MANIFEST)
with urllib.request.urlopen(DEBIAN_DOWNLOAD + "/" + DEBIAN_MANIFEST, context=client_context) as response, \
open(DOWNLOAD_DIR + "/" + DEBIAN_MANIFEST, 'wb') as out_file:
shutil.copyfileobj(response, out_file)
if not Path(DOWNLOAD_DIR + "/" + DEBIAN_IMAGE).is_file():
print("-", DEBIAN_IMAGE)
with urllib.request.urlopen(DEBIAN_DOWNLOAD + "/" + DEBIAN_IMAGE, context=client_context) as response, \
open(DOWNLOAD_DIR + "/" + DEBIAN_IMAGE, 'wb') as out_file:
shutil.copyfileobj(response, out_file)
else:
print("All files have already been copied to local directory '" + DOWNLOAD_DIR + "'.")
print("-", DEBIAN_IMAGE)
print("-", DEBIAN_MANIFEST)
print("-", DEBIAN_MANIFEST_SIGN)
print("\nVerifying digital signature and hashes...\n")
v = open(DOWNLOAD_DIR + "/" + DEBIAN_MANIFEST_SIGN, "rb")
verify_result = gpg.verify_file(v, DOWNLOAD_DIR + "/" + DEBIAN_MANIFEST)
v.close()
if verify_result.status == "signature valid":
hasher = hashlib.sha256()
with open(DOWNLOAD_DIR + "/" + DEBIAN_IMAGE, 'rb') as hf:
buf = hf.read(HASH_BLOCKSIZE)
while len(buf) > 0:
hasher.update(buf)
buf = hf.read(HASH_BLOCKSIZE)
DIGEST = hasher.hexdigest()
hash_found = False
file = open(DOWNLOAD_DIR + "/" + DEBIAN_MANIFEST, "r")
for line in file:
if re.search(DIGEST, line):
hash_found = True
file.close()
if hash_found:
print("[ SUCCESS ] GPG signature for", DEBIAN_MANIFEST, "successfully verified.")
print("[ SUCCESS ] SHA-256 hash of", DEBIAN_IMAGE, "successfully verified.\n")
# The script won't delete files.
print("It's now safe to delete files", DEBIAN_MANIFEST, "and", DEBIAN_MANIFEST_SIGN, "\n")
print("RESULT: SUCCESS. It means that", DEBIAN_IMAGE, "wasn't modified after its creation")
print("and that the file", DEBIAN_MANIFEST, "that contains the proof was signed by Debian signing private key.")
print("Learn more at https://stakey.club/en/verifying-digital-signatures/\n")
# The script won't do anything to the downloaded image.
print("To use the image:")
print("1. burn", DEBIAN_IMAGE, "to a", MEDIA + "; or")
print("2. use it to boot a virtual machine")
else:
print("[ SUCCESS ] GPG signature for", DEBIAN_IMAGE, "successfully verified.")
print("[ FAIL ] SHA-256 hash of", DEBIAN_IMAGE, "verification FAILED!\n")
print("RESULT: FAIL. It means that the manifest wasn't modified after its creation")
print("but", DEBIAN_IMAGE, "is incomplete or was probably modified after its creation.")
exit(3)
else:
print("[ FAIL ] GPG did not find a \"good signature\" for", DEBIAN_IMAGE + ". Verification FAILED!")
exit(4)