<-- Home

Timestamp script

This script computes the hash of every file in a directory, boils that down into one master hash value, and then submits this to two different free cryptographic timestamp services. The timestamp certificates as well as the hash values are then stored in a git repository. This is meant to be called daily as a cron job. That way, you will always be able to prove (cryptographically) that you had a certain version of a particular file on a particular day. This may be useful for example in proving priority on an idea or invention. I have no idea what the legal standing of cryptographic timestamps is, but of course it could only help your case.

To use this script, customize the definitions listed in the first three lines. SRCDIR points to the directory you want to timestamp. DSTDIR should be an empty git repository which will be used to store the certificates. When you want to prove a timestamp, just pull the checksums and certificate out of the history of the DSTDIR git repo. You will also have to have a copy of the actual file that you are authenticating (which you should have if you use a version control system for your projects).

There will be three files in DSTDIR, representing a sort of hash pyramid. To verify a timestamp for a file, you will first need to check out the version of this git repository corresponding to the particular day you are interested in. The sha512 sum of your file to be authenticated will be contained in timestamps.list. The sha512 sum of that file will be the contents of timestamps.sha512 (this value is what is signed by the stamper.itconsult.co.uk service, which sends you a certificate via email). The sha512 sum of timestamps.sha512 should in turn be contained in the certificate from the timemarker.org service, whose certificate is stored in timestamps.cert.

#!/bin/bash

# Generate cryptographic timestamps for all files in projects directory.  The
# SHA-512 hash is computed for each file and stored in a list.  This list is in
# turn hashed with SHA-512 and the resulting value is submitted to two
# cryptographic timestamp services and is also posted to twitter.
#
# The list of per-file SHA-512 values, as well as the timemarker.org
# certificate, are stored in a git repository.  In order to verify a timestamp,
# simply check out the appropriate commit from the git repo and check that the
# SHA-512 values match.
#
# The stamper.itconsult.co.uk stamps will be delivered to you via email.

# The directory to make a timestamp of.
SRCDIR=/home/jdoe/projects
# A git repo that will keep a record of timestamps.
DSTDIR=/home/jdoe/timestamps

############################################

# Trap errors and print a message.
# From http://stackoverflow.com/a/185900
function error() {
  local PARENT_LINENO="$1"
  local MESSAGE="$2"
  local CODE="${3:-1}"
  if [[ -n "$MESSAGE" ]] ; then
    echo "Error on or near line ${PARENT_LINENO}: ${MESSAGE}; exiting with status ${CODE}"
  else
    echo "Error on or near line ${PARENT_LINENO}; exiting with status ${CODE}"
  fi
  exit "${CODE}"
}
trap 'error ${LINENO}' ERR
# Call error function when any command gives error exit status.
set -e

DATE=$(date +'%F %T')
# This file will hold a list of hash values of each file in SRCDIR.
FN_LISTFILE=$DSTDIR/timestamps.list
# This will hold the hash of the above file.  This is what gets timestamped.
FN_REDUCED=$DSTDIR/timestamps.sha512
# This will hold the certificate received from timemarker.org.
FN_CERT=$DSTDIR/timestamps.cert

# Put date as first line in hash list.  This guarantees that the hash changes
# from day to day, and avoids for example the error that twitter throws when a
# status message is duplicated.  It is also just nice bookkeeping.
echo "# $DATE" > $FN_LISTFILE
# Compute hash of all files in SRCDIR.
find $SRCDIR -type f -exec sha512sum '{}' ';' >> $FN_LISTFILE

# Boil this file down into a single hash.
BIGSUM=$(sha512sum $FN_LISTFILE |cut -d' ' -f1)
echo -n $BIGSUM > $FN_REDUCED

# Submit BIGSUM to timestamp service timemarker.org.
python <<END
import base64
import urllib
url = 'http://srv.timemarker.org/Service.svc/getStamp/file/?data=' + \
	urllib.quote(base64.b64encode('$BIGSUM'))
urllib.urlretrieve(url, '$FN_CERT')
END

# Make sure that the checksum in the certificate can be made from the input file.
# This also serves to document *how* the cert sum can be made from the input,
# for later verification.
grep -q $(sha512sum $FN_REDUCED |cut -d' ' -f 1) $FN_CERT

# Another timestamp service.  This one delivers the certificates to you via email.
echo -e "Subject: Stamp for $DATE\n\n$BIGSUM" | ssmtp text@stamper.itconsult.co.uk

# Post to Twitter.  It is possible that the date mark of Twitter posts could
# have some credibility.  The 'twitter' command is supplied by the Python
# module of the same name.
twitter set "stamp:$BIGSUM"

# Put the certificate into the git repository.
cd $DSTDIR
git add $FN_LISTFILE $FN_REDUCED
git add $FN_CERT
git commit -q -a -m "$DATE"

<-- Home