#!/bin/bash # # RFC3161 and RFC5816 Timestamping for git repositories. # # Copyright (c) 2021 Mabulous GmbH # Authors: Matthias Bühlmann # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # # The interactive user interfaces in modified source and object code versions # of this program must display Appropriate Legal Notices, as required under # Section 5 of the GNU Affero General Public License version 3. In accordance # with Section 7(b) of the GNU Affero General Public License, you must retain # the Info line in every timestamp that is created or manipulated using a # covered work. # # You can be released from the requirements of the license by purchasing # a commercial license. Buying such a license is mandatory as soon as you # develop commercial activities involving this software without # disclosing the source code of your own applications. # These activities include: offering paid services to customers as an ASP, # providing data storage and archival services, shipping this software with a # closed source product. # # For more information, please contact Mabulous GmbH at this # address: info@mabulous.com # TSA0_URL=$(git config timestamping.tsa0.url) if [ -z "$TSA0_URL" ]; then # Do nothing if TSA0 has not been configured. exit 0 fi DIR="${BASH_SOURCE%/*}" if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi . "$DIR/timestamping" extended_exit_trap() { local EXIT_CODE="$?" if [ "$EXIT_CODE" -gt 0 ]; then echo_error "Aborting commit." git reset --soft HEAD^ fi rm -rf -- "$TMP_DIR" exit "$EXIT_CODE" } trap "extended_exit_trap" EXIT COMMIT_MSG=$(git show --pretty=format:"%B" --no-patch HEAD) #avoid recursion and validate timestamp if [[ "$COMMIT_MSG" == "$SUBJECT_LINE"* ]]; then log "exiting recursion" exit 0 fi echo_info "Adding Timestamp commit" #prepare commit message COMMIT_MSG_FILE="$TMP_DIR"/commit_msg.txt echo "$SUBJECT_LINE" > "$COMMIT_MSG_FILE" #get hash of unstamped commit DIGEST=$(git rev-parse --verify HEAD) #request a timestamp token for each TSA defined TSA_IDX=-1 while : ; do ((TSA_IDX++)) TSA_URL=$(git config timestamping.tsa"$TSA_IDX".url) if [ -z "$TSA_URL" ]; then break fi echo_info "for TSA $TSA_URL" TOKEN_OPTIONAL=$(git config --type=bool timestamping.tsa"$TSA_IDX".optional) #retrieve token TOKEN_FILE="$TMP_DIR"/token.tst if ! request_token "$TSA_URL" "$DIGEST" false "$TOKEN_FILE"; then if [ ! "$TOKEN_OPTIONAL" ]; then echo_error "Error: Retrieving timestamp token for critical TSA$TSA_IDX failed." exit 1 else echo_warning "Warning: Retrieving timestamp token for optional TSA$TSA_IDX failed. Token won't be added." continue fi fi #validate token and download LTV data if ! verify_token_and_add_ltv_data "$TOKEN_FILE" "$DIGEST" "$TSA_URL"; then if [ ! "$TOKEN_OPTIONAL" ]; then echo_error "Error: Validating timestamp token for critical TSA$TSA_IDX failed." exit 1 else echo_warning "Warning: Validating timestamp token for optional TSA$TSA_IDX failed. Token won't be added." continue fi fi #add token to commit message openssl ts -reply -token_in -in "$TOKEN_FILE" -token_out -text -out "$TMP_DIR"/token.txt &> "$OUT_STREAM" #do not remove or change Info line (see license) INFO="Info: Timestamp generated with GitTrustedTimestamps by Mabulous GmbH" TOKENBASE64=$(openssl base64 -in "$TOKEN_FILE") TOKENTEXT=$(cat "$TMP_DIR"/token.txt) TRAILER_VALUE="$TSA_URL"$'\n'"$INFO"$'\n\n'"$TOKENTEXT"$'\n\n'"$TOKEN_HEADER"$'\n'"$TOKENBASE64"$'\n'"$TOKEN_FOOTER" #fold TRAILER_VALUE=$(echo -n "$TRAILER_VALUE" | sed -e 's/^/ /') git interpret-trailers --where end --if-exists addIfDifferent --no-divider --trailer "$TRAILER_TOKEN$TRAILER_VALUE" --in-place "$COMMIT_MSG_FILE" done #add all ltv files if [ ! -d "$LTV_DIR"/certs ]; then mkdir -p "$LTV_DIR"/certs fi if [ ! -d "$LTV_DIR"/crls ]; then mkdir -p "$LTV_DIR"/crls fi ls "$TMP_LTV_DIR"/*/* | while read SOURCE_FILE; do TARGET_FILE="$LTV_DIR"${SOURCE_FILE#"$TMP_LTV_DIR"} mv -f "$SOURCE_FILE" "$TARGET_FILE" git add "$TARGET_FILE" done git commit --allow-empty --quiet -F "$COMMIT_MSG_FILE" echo_info "Timestamping complete" exit 0