Compare commits

...

5 Commits

Author SHA1 Message Date
e6c331575a Make target file relative to script file
Since we expect them to be in the same directory
2025-11-24 12:07:34 -08:00
0e6f27a4f2 Add explanation to script template 2025-11-24 12:07:16 -08:00
6eb284659b Simplify readme 2025-11-23 21:11:34 -08:00
22aff9c6b2 Add error handling for missing files 2025-11-23 20:58:43 -08:00
a8ac4c2d06 Fix some issues found by shellcheck 2025-11-23 20:02:06 -08:00
4 changed files with 82 additions and 61 deletions

View File

@@ -1,18 +1,23 @@
#!/bin/bash
#!/bin/env sh
TEMPLATE_FILE="$(dirname $0)/verify-script.template"
TEMPLATE_FILE="$(dirname "$0")/verify-script.template"
if [ ! -f "$TEMPLATE_FILE" ]; then
echo "'$TEMPLATE_FILE' not found. The template file should have come with this script." 1>&2
exit 1
fi
FILE_PATH="$1"
if [ ! -f "$FILE_PATH" ]; then
echo "'$FILE_PATH' not found" 1>&2
exit 1
fi
FILE_NAME="$(basename "$FILE_PATH")"
FILE_HASH="$(sha256sum "$FILE_PATH" | awk '{print $1}')"
# TODO: argument for the message in case you want to apply it to many files.
read -p "Enter message to sign for the file: " MESSAGE
read -r -p "Enter message to sign for the file: " MESSAGE
MESSAGE="$MESSAGE\n"
#echo "message: $MESSAGE"
FILE_NAME="$(basename $1)"
#echo "file name: $FILE_NAME"
FILE_HASH="$(sha256sum $FILE_NAME | awk '{print $1}')"
#echo "file hash: $FILE_HASH"
SUBSTITUTED_TEMPLATE=$(sed -e "s!{message}!$MESSAGE!g" -e "s!{filename}!$FILE_NAME!g" -e "s!{filehash}!$FILE_HASH!g" "$TEMPLATE_FILE")
SUBSTITUTED_TEMPLATE=$(sed -e "s!{message}!$MESSAGE!g" -e "s!{filename}!$FILE_NAME!g" -e "s!{filehash}!$FILE_HASH!g" $TEMPLATE_FILE)
#echo "substituted: $SUBSTITUTED_TEMPLATE"
printf "$SUBSTITUTED_TEMPLATE" > "$1.sh"
printf '%s' "$SUBSTITUTED_TEMPLATE" > "$1.sh"

47
readme.md Normal file
View File

@@ -0,0 +1,47 @@
This is a simple utility to create a signed message associated with a target file. Recipients who can check the validity of the message signature will also know that it applies to the specific target file they have a copy of. It is meant as an alternative to signing files directly. See the motivation section below.
# Usage
To create the message:
1. Run this utility on a target file, then input your message when prompted.
* A shell script associated with the file (named {target-file}.sh) will be created
2. Sign the shell script.
3. Distribute the target file, shell script, and signature together.
To verify the message, recipients will:
1. Verify your signature of the script file
2. Run the script file, and if the target file matches the one you specified (check by comparing hashes) your message will be output.
* If the recipient does not want to run the script, they can simply inspect it to find the message and the file's hash which they can verify matches by themselves.
# Example script
This is the kind of script that is created:
```sh
#!/bin/env sh
MESSAGE="test
"
FILE="npr2.htm"
EXPECTED_HASH="3e1af128cb192b6d8ded7f2d66afc1ebe8bd9619f252573888b4bf385448db89"
if [ "$(sha256sum "$FILE" | awk '{print $1}')" = "$EXPECTED_HASH" ]; then
printf "File %s validated with message:\\n%s" "$FILE" "$MESSAGE"
exit 0
else
echo "File $FILE is not valid"
exit 1
fi
```
# Motivation
Signing a file typically means "I authored this", but sometimes you want to communicate something else, for example to indicate that you retrieved something on a given date.
However, just signing the file can't really convey that meaning. There are probably plenty of potential formats that could deal with this, but one very simple method is to create a bash file associated with the file you want to attest and have a message + file hash embedded in the script. Then you can sign the script which ties the message to the specific version of the file. Whoever recieves the trio of files would verify the script with the signature, then run the script which would output the message if the target file matches the embedded hash.
TODO: example of making it a function in your profile
TODO: guix package

View File

@@ -1,47 +0,0 @@
This simple script takes a file as an argument and prompts the user for a message. Then a new script is created alongside the target file as {filename}.sh which has the message and file hash embedded. You would then sign the script file and distribute all three.
To verify that your message applies to the file they recieved, your recipient(s) would verify your signature of the script, and then run it (or merely inspect it if they don't trust you too much) which will confirm their file matches the one you wrote the message about.
Example:
I have a file foo.txt, so I run ():
`create-file-message.sh webpage.htm`
When prompted, enter the message to associate with the file.
Then sign the resulting webpage.htm.sh file
`gpg --sign webpage.htm.sh`
You will then have the following files which should be distributed together:
* webpage.htm
* webpage.htm.sh
* webpage.htm.sh.sig
Whoever wants to validate the file and the message will first import your public key, then they validate webpage.htm`
When prompted, enter the message to associate with the file.
Then sign the resulting webpage.htm.sh file
`gpg --sign webpage.htm.sh`
You will then have the following files which should be distributed together:
* webpage.htm
* webpage.htm.sh
* webpage.htm.sh.sig
Whoever wants to validate the file and the message will first import your public key, then they verify the script file with `gpg --verify webpage.htm.sh`, finally they run `./webpage.htm.sh` which will check whether the target file matches the stored hash and if so will display the message.
TODO: example of making it a function in your profile
TODO: guix package
Motivation:
Signing a file typically means "I authored this", but sometimes you want to sign something else, for example to indicate that you retrieved something on a given date.
However, just signing the file can't really convey that meaning. There are probably plenty of potential formats that could deal with this, but one very simple method is to create a bash file associated with the file you want to attest and have a message + file hash embedded in the script. Then you can sign the script which ties the message to the specific version of the file. Whoever recieves the trio of files would verify the script with the signature, then run the script which would output the message if the target file matches the embedded hash.

View File

@@ -1,11 +1,27 @@
#!/bin/env sh
# This script should have come along with two files:
# * The target file '{filename}'
# * The signature file '{filename}.sh.sig'
# (or this file should have been signed in some other way)
#
# First, you should verify that this file came from the person you expect by
# verifying the signature.
#
# Next, you should run this script which will check that the target file
# matches the hash that was calculated when the message below was written.
# This will confirm that the file you have matches the file the message was
# written about.
#
# Alternatively, if you don't want to run this script, you can verify the
# hash manually.
MESSAGE="{message}"
FILE="{filename}"
FILE_PATH="$(dirname "$0")/$FILE"
EXPECTED_HASH="{filehash}"
if [ "$(sha256sum "$FILE" | awk '{print $1}')" = "$EXPECTED_HASH" ]; then
printf "File %%s validated with message:\\n%%s" "$FILE" "$MESSAGE"
if [ "$(sha256sum "$FILE_PATH" | awk '{print $1}')" = "$EXPECTED_HASH" ]; then
printf "File %s validated with message:\\n%s" "$FILE" "$MESSAGE"
exit 0
else
echo "File $FILE is not valid"