diff --git a/README.md b/README.md index 1cd233c..6669125 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ Additionally to retrieving TSA tokens and timestamping the commits with them, th If a token does not pass these tests, it is not added and the commit is either aborted (if the TSA is not set to optional) or a warning is output (if the TSA is set to optional). This repository uses the post-commit hook itself, so if you check the commit history of this repository, you will see that each commit is followed by a -----TIMESTAMP COMMIT----- that contains one or more timestamp tokens. -For example, [this](https://github.com/MrMabulous/GitTrustedTimestamps/commit/67a93e8b5dc58f828e9f364ace03ac48a007c778) *timestamp commit* timestamps [this](https://github.com/MrMabulous/GitTrustedTimestamps/commit/6e9841d157c222e9bd79d6580dd029adccf55cde) regular commit, which is its direct parent. You can see that the "Digest" that is timestamped by the token is `bf8d5c510b87e22c06f3300e5dbe69f5c6a3f1e1=sha1(parent:6e9841d157c222e9bd79d6580dd029adccf55cde,tree:75be5fcd56edaff4da1fc31d3632da14618f7fc0)`, whereas the tree hash and parent hash in the preimage correspond to the parent and tree of this *timestamp commit*. +For example, [this](https://github.com/MrMabulous/GitTrustedTimestamps/commit/58ba3dbd480e3c07dbd14beca02092982f8e9492) *timestamp commit* timestamps [this](https://github.com/MrMabulous/GitTrustedTimestamps/commit/80034aeb7857a910f06429c3580635b4afa40cc0) regular commit, which is its direct parent. You can see that the "Digest" that is timestamped by the token is `bf8d5c510b87e22c06f3300e5dbe69f5c6a3f1e1=sha1(parent:6e9841d157c222e9bd79d6580dd029adccf55cde,tree:75be5fcd56edaff4da1fc31d3632da14618f7fc0)`, whereas the tree hash and parent hash in the preimage correspond to the parent and tree of this *timestamp commit*. Since github did not support sha256 hashes yet at the time this repository was created, the hashing algorithm used is sha1 (for a repository initialized with `git init --object-format=sha256` the hashing algorithm will be sha256 or other, once git adds support for further algorithms) # For how long are timestamps valid? diff --git a/hooks/timestamping b/hooks/timestamping index 2740979..d29c96f 100644 --- a/hooks/timestamping +++ b/hooks/timestamping @@ -75,6 +75,13 @@ echo_info() { echo -e "${LIGHT_BLUE}$1${NO_COLOR}" } +#echo light green text +echo_success() { + local LIGHT_GREEN='\033[1;32m' + local NO_COLOR='\033[0m' + echo -e "${LIGHT_GREEN}$1${NO_COLOR}" +} + #echo dark gray text to OUT_STREAM log() { local DARK_GRAY='\033[1;30m' diff --git a/hooks/validate.sh b/hooks/validate.sh index 52b16a3..1c52822 100644 --- a/hooks/validate.sh +++ b/hooks/validate.sh @@ -41,6 +41,46 @@ DIR="${BASH_SOURCE%/*}" if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi . "$DIR/timestamping" +declare -i MINVERSION=$TIMESTAMPING_VERSION + +while [[ $# -gt 1 ]]; do + KEY="$1" + + case $KEY in + -min|--minversion) + INTEGER_REGEX='^[0-9]+$' + if ! [[ "$2" =~ $INTEGER_REGEX ]]; then + echo_error "$KEY: expected positive integer" + exit 1 + fi + MINVERSION="$2" + if [ $MINVERSION -gt $TIMESTAMPING_VERSION ]; then + echo_error "$KEY: this script only supports validating up to version $TIMESTAMPING_VERSION, but got $MINVERSION" + exit 1 + fi + shift # past argument + shift # past value + ;; + -v|--verbose) + OUT_STREAM=/dev/stdout + shift # past argument + ;; + *) # unknown option + echo_error "Unknown argument: $KEY" + exit 1 + ;; + esac +done +OBJECT="$1" +if [ -z "$OBJECT" ]; then + OBJECT="HEAD" +fi +COMMIT_HASH=$(git rev-parse "$OBJECT") +if [ -z "$COMMIT_HASH" ]; then + echo_error "Invalid rev $OBJECT" + return 1 +fi + # If commit contains timestamp tokens, validates them. # param1: commit hash # returns: 0 if the commit contains no timestamp tokens or contains at least one @@ -55,6 +95,8 @@ validate_commit() { local URL_ARRAY local TOKEN_ARRAY if ! extract_token_from_commit "$COMMIT_HASH" "$TMP_DIR" TIMESTAMP_COMMIT_VERSION URL_ARRAY TOKEN_ARRAY; then + echo_error "Extracting token from commit $COMMIT_HASH failed." + echo "" return 1 fi local NUM_EXTRACTED="${#TOKEN_ARRAY[@]}" @@ -64,6 +106,26 @@ validate_commit() { return 0 fi + assert "[ $TIMESTAMP_COMMIT_VERSION -gt -1 ]" "version must not be -1 if commit contains timestamps." + + #By default, validate.sh only trusts timestamps with the current timestamp-commit-version. If older versions + #should be trusted, for example because the timestamping logic has been updated to include a new version during + #the lifetime of the repository, then it must be explicitly specified using the --minversion argument + if [ $TIMESTAMP_COMMIT_VERSION -lt $MINVERSION ]; then + local VERSION_TRUST_STRING="version $MINVERSION - $TIMESTAMPING_VERSION" + if [ $MINVERSION -eq $TIMESTAMPING_VERSION ]; then + VERSION_TRUST_STRING="version $MINVERSION" + fi + echo_error "Timestamping version of commit $COMMIT_HASH is $TIMESTAMP_COMMIT_VERSION, but script is set to only trust $VERSION_TRUST_STRING. Use --minversion argument to trust older versions. " + echo "" + return 1 + fi + if [ $TIMESTAMP_COMMIT_VERSION -gt $TIMESTAMPING_VERSION ]; then + echo_error "Timestamping version of commit $COMMIT_HASH is $TIMESTAMP_COMMIT_VERSION, but this script only supports validation of timestamps up to version $TIMESTAMP_COMMIT_VERSION." + echo "" + return 1 + fi + local PARENT_HASH=$(git cat-file -p "$COMMIT_HASH" | awk '/^$/{exit} /parent/ {print}' | sed 's/parent //') local TREE_HASH=$(git cat-file -p "$COMMIT_HASH" | awk '/^$/{exit} /tree/ {print}' | sed 's/tree //') local EXPECTED_DIGEST @@ -223,6 +285,7 @@ validate_commit() { return 0 fi echo_error "All $NUM_EXTRACTED timestamp tokens in commit $COMMIT_HASH are invalid." + echo "" return 1 } @@ -252,16 +315,6 @@ validate_commit_and_parents() { return 1 } -OBJECT="$1" -if [ -z "$OBJECT" ]; then - OBJECT="HEAD" -fi -COMMIT_HASH=$(git rev-parse "$OBJECT") -if [ -z "$COMMIT_HASH" ]; then - echo_error "Invalid rev $OBJECT" - return 1 -fi - echo_info "Checking repository integrity..." #check git repository integrity if ! git fsck --full --strict --no-progress --no-dangling "$COMMIT_HASH"; then @@ -274,7 +327,7 @@ echo "" echo_info "Validating timestamps. This may take a while..." echo "" if validate_commit_and_parents "$COMMIT_HASH"; then - echo_info "Validation OK: All timestamped commits in the commit history of $COMMIT_HASH contain at least one valid timestamp." + echo_success "Validation OK: All timestamped commits in the commit history of $COMMIT_HASH contain at least one valid timestamp." exit 0 else echo_error "Validation Failed: There are timestamped commits in the commit history of $COMMIT_HASH which do not contain any valid timestamps."