2 Commits

Author SHA1 Message Date
Artur Neumann
4f911c69d4 -----TIMESTAMP COMMIT-----
Version: 1

Algorithm: sha1

Preimage: version:1,parent:9006f166f79aff8463e0b94a40816b5809d26f59,tree:5132ba0a84fb9f255de095c750a3ee66b99743bc

Digest: 41c32d5c57c86c73e17431d985431dcfa11b0794

Timestamp: https://freetsa.org/tsr
 Info: Timestamp generated with GitTrustedTimestamps by Mabulous GmbH

 Version: 1
 Policy OID: tsa_policy1
 Hash Algorithm: sha1
 Message data:
     0000 - 41 c3 2d 5c 57 c8 6c 73-e1 74 31 d9 85 43 1d cf   A.-\W.ls.t1..C..
     0010 - a1 1b 07 94                                       ....
 Serial number: 0x051E7BA6
 Time stamp: Jan 22 08:32:24 2025 GMT
 Accuracy: unspecified
 Ordering: yes
 Nonce: 0x7C7126C79B4BBE42
 TSA: DirName:/O=Free TSA/OU=TSA/description=This certificate digitally signs documents and time stamp requests made using the freetsa.org online services/CN=www.freetsa.org/emailAddress=busilezas@gmail.com/L=Wuerzburg/C=DE/ST=Bayern
 Extensions:

 -----BEGIN RFC3161 TOKEN-----
 MIIFNwYJKoZIhvcNAQcCoIIFKDCCBSQCAQMxDzANBglghkgBZQMEAgMFADCCAX4G
 CyqGSIb3DQEJEAEEoIIBbQSCAWkwggFlAgEBBgQqAwQBMCEwCQYFKw4DAhoFAAQU
 QcMtXFfIbHPhdDHZhUMdz6EbB5QCBAUee6YYDzIwMjUwMTIyMDgzMjI0WgEB/wII
 fHEmx5tLvkKgggERpIIBDTCCAQkxETAPBgNVBAoTCEZyZWUgVFNBMQwwCgYDVQQL
 EwNUU0ExdjB0BgNVBA0TbVRoaXMgY2VydGlmaWNhdGUgZGlnaXRhbGx5IHNpZ25z
 IGRvY3VtZW50cyBhbmQgdGltZSBzdGFtcCByZXF1ZXN0cyBtYWRlIHVzaW5nIHRo
 ZSBmcmVldHNhLm9yZyBvbmxpbmUgc2VydmljZXMxGDAWBgNVBAMTD3d3dy5mcmVl
 dHNhLm9yZzEiMCAGCSqGSIb3DQEJARYTYnVzaWxlemFzQGdtYWlsLmNvbTESMBAG
 A1UEBxMJV3VlcnpidXJnMQswCQYDVQQGEwJERTEPMA0GA1UECBMGQmF5ZXJuMYID
 ijCCA4YCAQEwgaMwgZUxETAPBgNVBAoTCEZyZWUgVFNBMRAwDgYDVQQLEwdSb290
 IENBMRgwFgYDVQQDEw93d3cuZnJlZXRzYS5vcmcxIjAgBgkqhkiG9w0BCQEWE2J1
 c2lsZXphc0BnbWFpbC5jb20xEjAQBgNVBAcTCVd1ZXJ6YnVyZzEPMA0GA1UECBMG
 QmF5ZXJuMQswCQYDVQQGEwJERQIJAMHphhYNqOmCMA0GCWCGSAFlAwQCAwUAoIG4
 MBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0BCQUxDxcNMjUw
 MTIyMDgzMjI0WjArBgsqhkiG9w0BCRACDDEcMBowGDAWBBSRbaPYYOzKguNLxZ0X
 k+fpaIdfFDBPBgkqhkiG9w0BCQQxQgRAg6ToWoufJdhvp/UBOzM/qmSW83npLW3A
 WJkk3KU9uKvj1jCy9NUAL4dctJtRhWi1ObKqfg6tVkJUjUWfDg6OADANBgkqhkiG
 9w0BAQEFAASCAgCWzbvex3bQtr9zF0ZaICp1l3x15RzKOTLm3HXzLCeY+9ICwwZI
 3bWE4WAXlkebzQ99EmYYDFFBPKLYFDXl7pQMLcTNpng+fCx/xfiKh1baS4Zzlt51
 Tg0GZN4Vr3Zubp5qaRgDRe+761R6nfbsf1SECHI5N1kn0eURHl4J+9tF2hVhMQ33
 NMkFSrBlLJSd5b/rZHI5Qpq70NnUdLhJwNLRGs6i2EBFlm2T393VdjkOlaIVM/id
 5WrtnTAzScRuOayTE25IBxsDSX18tE9bD1ijlQbQSdspFkk1V3tpAHCUFAzvrgfO
 Ehm4eGKVDIkedPsUkJAL73QKDINLd5ycvb+bjIVLbt8VxSz8c7pso0BX+xgXRuQ3
 HvRIPi+bfpV4hXVw12VOAnHUu68f/po9G4aQM+XPzSy9L1kjbak1G1+zPW/3ohzt
 o4rNmpm4I915U1pl17xoLm48YCYoJWry/bf8VvBmHaXe8TDvaKr2rvJv9ZrTbwoB
 vBGLnh7XtRB4Wip3CAz+aifCs9cBdeM1IirQamBo9fP9qhhVDSxQqqeb+xN11xs4
 9spjC22ocoKe5PnhA34EAAuhyBqx1KBiuUCwUz25mqntEI91B+T+bj1TQ/EJ5fZs
 V726SJTW740a2z+pVTwtUPfyNl6/SllmQvjIMrLl2+kYiUOBonrchy0r3Q==
 -----END RFC3161 TOKEN-----

Timestamp: https://tsa.cesnet.cz:3162/tsa
 Info: Timestamp generated with GitTrustedTimestamps by Mabulous GmbH

 Version: 1
 Policy OID: 1.3.6.1.4.1.22408.1.2.3.45
 Hash Algorithm: sha1
 Message data:
     0000 - 41 c3 2d 5c 57 c8 6c 73-e1 74 31 d9 85 43 1d cf   A.-\W.ls.t1..C..
     0010 - a1 1b 07 94                                       ....
 Serial number: 0x29DD5895563F759F
 Time stamp: Jan 22 08:32:25 2025 GMT
 Accuracy: unspecified
 Ordering: no
 Nonce: 0x8A22D2B54B5700A0
 TSA: DirName:/DC=cz/DC=cesnet-ca/O=CESNET/CN=tsa.cesnet.cz
 Extensions:

 -----BEGIN RFC3161 TOKEN-----
 MIID1QYJKoZIhvcNAQcCoIIDxjCCA8ICAQMxDzANBglghkgBZQMEAgEFADCBzgYL
 KoZIhvcNAQkQAQSggb4EgbswgbgCAQEGDCsGAQQBga8IAQIDLTAhMAkGBSsOAwIa
 BQAEFEHDLVxXyGxz4XQx2YVDHc+hGweUAggp3ViVVj91nxgPMjAyNTAxMjIwODMy
 MjVaAgkAiiLStUtXAKCgXKRaMFgxEjAQBgoJkiaJk/IsZAEZFgJjejEZMBcGCgmS
 JomT8ixkARkWCWNlc25ldC1jYTEPMA0GA1UECgwGQ0VTTkVUMRYwFAYDVQQDDA10
 c2EuY2VzbmV0LmN6MYIC2TCCAtUCAQEwbDBgMRIwEAYKCZImiZPyLGQBGRYCY3ox
 GTAXBgoJkiaJk/IsZAEZFgljZXNuZXQtY2ExEjAQBgNVBAoMCUNFU05FVCBDQTEb
 MBkGA1UEAwwSUGVyc29uYWwgU2lnbmluZyAyAghq94ZoOsDXcDANBglghkgBZQME
 AgEFAKCCAT4wGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJ
 BTEPFw0yNTAxMjIwODMyMjVaMC0GCSqGSIb3DQEJNDEgMB4wDQYJYIZIAWUDBAIB
 BQChDQYJKoZIhvcNAQELBQAwLwYJKoZIhvcNAQkEMSIEIOWdZojHJbm/TmIOeWoB
 kvA3fXcB43GN+ZV8RMo+bDvnMIGhBgsqhkiG9w0BCRACDDGBkTCBjjCBizCBiAQU
 UCTsC5lLIjDwCg+Qpg0dKB0bP74wcDBkpGIwYDESMBAGCgmSJomT8ixkARkWAmN6
 MRkwFwYKCZImiZPyLGQBGRYJY2VzbmV0LWNhMRIwEAYDVQQKDAlDRVNORVQgQ0Ex
 GzAZBgNVBAMMElBlcnNvbmFsIFNpZ25pbmcgMgIIaveGaDrA13AwDQYJKoZIhvcN
 AQELBQAEggEAFSYXAxsh2Mxm268N3ESz/VYSJxMo8hcH5hGSicGJv1YIWI8QhV0t
 Wp6wOtk1sUcnAe5QZlQ6IzBc1PT+NIqNEEUydM9riyOmNIMZXnBiyI/DuRxo9mJd
 BBcmYthx4borfmBmClj7hIMjLtBB+hlChwryH45TBXDCJxMnKR0i8sd4Cc0kdyGr
 oey9DkIWRo5aH7otfZrRF9iUIMptnMS2eO3+6RsdqZgvNcVJq8HXvldmmQ7RZ3V5
 DrpPTxEaWgPdMh8Bo3z26c3U9vpnsKuAtViaAhoyvBVX7HnUXn+v1cPgqdRNMOQU
 e0rA1gZ+mA2aT0A52fmOBhiqL4ecT4FO0Q==
 -----END RFC3161 TOKEN-----
2025-01-22 14:17:26 +05:45
Artur Neumann
9006f166f7 script to validate whether the hash of the trustanchors folder changed
this is useful to make sure the same set of TSA are used on different
machines and that they haven't been changed.
E.g. I want to make sure I use the same TSA on my local machine as in CI
and I want to make sure the imported certificates in CI are the same as
in my local machine, so that I can trust them.
2025-01-22 14:17:10 +05:45
7 changed files with 2256 additions and 2279 deletions

View File

@@ -1,32 +0,0 @@
name: Validate Trusted Timestamps Actions Demo
run-name: ${{ gitea.actor }} is validating the trusted timestamps of all commits 🚀
on: [push]
variables:
EXPECTED_TRUSTANCHORS_HASH: "70a1c7e2fc62a0b62e44063f0e730b20b0f209d15c84b310ad06ce616c352829"
jobs:
Validate:
runs-on: ubuntu-latest
timeout-minutes: 2
steps:
- name: Install extra software
run: |
apt-get update
apt-get install -y xxd
- name: Check out repository code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup timestamping authorities
run: |
git config --local timestamping.tsa0.url https://freetsa.org/tsr
bash -c 'yes | ./hooks/trust.sh https://freetsa.org/tsr'
git config --local timestamping.tsa1.url https://tsa.cesnet.cz:3162/tsa
bash -c 'yes | ./hooks/trust.sh https://tsa.cesnet.cz:3162/tsa'
- name: Check hashes of all trustanchors
run: |
./hooks/validate_trustanchors_hash.sh .git/hoqoks/trustanchors ${{ EXPECTED_TRUSTANCHORS_HASH }}
- name: Validate timestamps of all commits
run: |
./hooks/validate.sh --minversion 0

File diff suppressed because it is too large Load Diff

View File

@@ -2,17 +2,17 @@
MIIC5jCCAc4CAQEwDQYJKoZIhvcNAQELBQAwcjELMAkGA1UEBhMCVVMxFTATBgNV
BAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8G
A1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBDQRcN
MjUwMjEyMDUyMjQ1WhcNMjUwMjE5MDUyMjQ1WjCB9TAhAhAL2v0LKRQzmpYSZqw1
MjUwMTIyMDUxMzE2WhcNMjUwMTI5MDUxMzE2WjCB9TAhAhAL2v0LKRQzmpYSZqw1
OkdEFw0xNjEwMjQxNzQyNDlaMCECEAH40oMtKRkZcbNQw9u8pQAXDTE2MTExMTE1
MjEzNFowIQIQClKwbEb16yWgi9U/3Ht4hhcNMTgwOTAzMTIxMTQyWjAhAhAFlx7K
SlmJinvPTLfjd5doFw0xOTA5MzAwODE2MjRaMCECEAxFkEkmQLBOlEh/jEwCeJAX
DTIxMDIwOTIyMzk0MlowIQIQBMvnUVSd49EL7YN0yV7iRBcNMjEwMjA5MjMyMzM3
WjAhAhALmUrhw5aLANVesgZ0jpseFw0yMTAyMDkyMzI0MjNaoDAwLjAfBgNVHSME
GDAWgBT0tuEgHf4prtLkYaWyoiWyyBc1bjALBgNVHRQEBAICDO8wDQYJKoZIhvcN
AQELBQADggEBALr4VopJYkMfQ97HiyqytcWRY/vgyU/LxOwlH0/1DBSeeObQB0Nj
uF7vcF2bhbpnxba7gvzOPryudwtbqquf2cl3CJG6MC2D8Nk1XzntDnpxCjVSfsAr
158zAWPevyiuj3yzFz04mYALt/ZmOJMTF0vyKN8cg5bwfLu3itV6b6vhpuloIhRc
Hmsbgr3BtCVHkf4vJWq/qKDEMcOhSrJ6wxGCzVyphenewSIbVcogj19cRZDFPWOC
3sAy/GY3Rz0qK30tDvNbE1uum8gy5ijXFmepJ/lEetRCvrIsxTsXJOj0tqVZfIIQ
E1YWUZ57TiBBrdS+dTgmRxkN/zaAfYVAIck=
GDAWgBT0tuEgHf4prtLkYaWyoiWyyBc1bjALBgNVHRQEBAICDNowDQYJKoZIhvcN
AQELBQADggEBAFxgvuHLyxJ88doIv2nQk02kaURi2IaTraKX+pknGhW6f2v9foSX
Ywhx/fyfqpA0eChER6jAReMQil1t+5RLmVU8QGG77wz83TBclMpcNxQNINV7JKVh
rqyCemrNrTW+RKgVO/EL02fqRTf9f3mSbSLEo07dI88BYTY1YXtnkrbcwxq1ARPp
kCAAoGRHWqxQ9hIKrOhWWnGzG43Vghmo0E8l2xJut+3zyLv16/WBFBgxtTWSK3xI
SNSsTcZaQY286Akco+sNnss6JuzG7Lm0/0Hv6zjVJys6qYDZsPP+G6hc1RTAI6w2
MEzWgX64tLBdo3L33ZJbVoBhg6mX/euck04=
-----END X509 CRL-----

0
hooks/post-commit Executable file → Normal file
View File

2
hooks/timestamping Executable file → Normal file
View File

@@ -553,7 +553,7 @@ download_crls_for_chain() {
local URL=$(openssl x509 -inform PEM -in $EXTRACTED_CERT -text -noout \
| awk '/CRL Distribution Points:/{f=1} f && /URI:/ {print; exit}' \
| sed 's/^.*URI://1')
if curl -L "$URL" --output "$CRL_TMP" &> "$OUT_STREAM"; then
if curl "$URL" --output "$CRL_TMP" &> "$OUT_STREAM"; then
if openssl crl -in "$CRL_TMP" -inform DER -noout &> "$OUT_STREAM"; then
openssl crl -in "$CRL_TMP" -inform DER >> "$OUTPUT_FILE"
elif openssl crl -in "$CRL_TMP" -inform PEM -noout &> "$OUT_STREAM"; then

0
hooks/trust.sh Executable file → Normal file
View File

121
hooks/validate.sh Executable file → Normal file
View File

@@ -42,12 +42,8 @@ if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
. "$DIR/timestamping"
declare -i MINVERSION=$TIMESTAMPING_VERSION
declare -i MAX_COMMITS_TO_CHECK=0
declare -A PROCESSED_COMMIT
declare -A COMMITS
declare -A COMMIT_TIMES
while [[ $# -gt 0 ]]; do
while [[ $# -gt 1 ]]; do
KEY="$1"
case $KEY in
@@ -65,27 +61,17 @@ while [[ $# -gt 0 ]]; do
shift # past argument
shift # past value
;;
-max|--maxcommits)
INTEGER_REGEX='^[0-9]+$'
if ! [[ "$2" =~ $INTEGER_REGEX ]]; then
echo_error "$KEY: expected positive integer"
exit 1
fi
MAX_COMMITS_TO_CHECK="$2"
shift # past argument
shift # past value
;;
-v|--verbose)
OUT_STREAM=/dev/stdout
shift # past argument
;;
*) # unknown option
OBJECT=$KEY
shift # past argument
echo_error "Unknown argument: $KEY"
exit 1
;;
esac
done
OBJECT="$1"
if [ -z "$OBJECT" ]; then
OBJECT="HEAD"
fi
@@ -103,10 +89,6 @@ fi
# tokens, the function will return 0 but echo a warning about the invalid token.
validate_commit() {
local COMMIT_HASH="$1"
if [[ ${PROCESSED_COMMIT[$COMMIT_HASH]} ]]; then
log "validate_commit for $COMMIT_HASH has already been validated"
return 0
fi
log "validate_commit for $COMMIT_HASH"
local TIMESTAMP_COMMIT_VERSION
@@ -293,11 +275,9 @@ validate_commit() {
#assert that all extracted timestamps have been processed
assert "[ $NUM_PROCESSED -eq $NUM_EXTRACTED ]" "All extracted token must be processed."
PROCESSED_COMMIT[$COMMIT_HASH]=1
if [ $NUM_VALID -gt 0 ]; then
if [ $NUM_INVALID -gt 0 ]; then
echo_warning "Warning: While commit $COMMIT_HASH contains $NUM_VALID valid timestamp tokens and thus is considered properly timestamped, it also contains $NUM_INVALID invalid timestamp tokens."
echo_warning "Warning: While commit $COMMIT_HASH contains $NUM_VALID valid timestamp tokens and thus is considered proppely timestamped, it also contains $NUM_INVALID invalid timestamp tokens."
fi
DATE_STRING=$(date -d @"$EARLIEST_VALID_UNIX_TIME")
echo_info "Commit $COMMIT_HASH, which timestamps commit $PARENT_HASH at $DATE_STRING, contains $NUM_VALID valid timestamp tokens."
@@ -313,13 +293,6 @@ validate_commit() {
# param1: commit hash
# returns: 0 if the validation of the commit and all its ancestors succeeded
validate_commit_and_parents() {
# If MAX_COMMITS_TO_CHECK is zero (or a negative number) then that is understood as "infinity".
# So finish if we have reached the limit, and if the limit is not "infinity".
NUM_COMMITS_CHECKED=${#PROCESSED_COMMIT[@]}
if [[ ${NUM_COMMITS_CHECKED} -ge ${MAX_COMMITS_TO_CHECK} ]] && [[ ${MAX_COMMITS_TO_CHECK} -ge 1 ]]; then
# enough commits have already been checked, so return early
return 0;
fi
local COMMIT_HASH="$1"
log "validate_commit_and_parents for $COMMIT_HASH"
@@ -327,7 +300,6 @@ validate_commit_and_parents() {
if ! validate_commit "$COMMIT_HASH"; then
ALL_PASSED=false
fi
NUM_COMMITS_CHECKED=${#PROCESSED_COMMIT[@]}
local PARENTS=$(git cat-file -p "$COMMIT_HASH" | awk '/^$/{exit} /parent/ {print}' | sed 's/parent //')
#iterate over all parents of commit
if [ ! -z "$PARENTS" ]; then
@@ -337,65 +309,7 @@ validate_commit_and_parents() {
fi
done <<< $(printf "%s" "$PARENTS")
fi
if [ "$ALL_PASSED" = true ]; then
return 0
fi
return 1
}
# Recursive function to find all ancestors of commit
# param1: commit hash
# creates an array COMMITS, key is the commit hash, value is the commit time (Unix epoch seconds)
# the array contains all commits found in all paths from the passed-in commit hash back to the root commit of the repo
# the array is global so it can be accessed after the function returns
find_all_commits() {
local COMMIT_HASH="$1"
log "find_all_commits for $COMMIT_HASH"
# git show "ct" format returns the commit time as Unix epoch seconds
COMMIT_TIME=$(git show --no-patch --format=%ct "$COMMIT_HASH")
COMMITS[$COMMIT_HASH]="${COMMIT_TIME}"
local PARENTS=$(git cat-file -p "$COMMIT_HASH" | awk '/^$/{exit} /parent/ {print}' | sed 's/parent //')
# iterate over all parents of commit
if [ ! -z "$PARENTS" ]; then
while read PARENT_HASH; do
if [[ ${COMMITS[$PARENT_HASH]} ]]; then
log "commit $PARENT_HASH has already been processed"
else
find_all_commits "$PARENT_HASH"
fi
done <<< $(printf "%s" "$PARENTS")
fi
}
# Validate the commits in the COMMITS array, up to MAX_COMMITS_TO_CHECK
# returns: 0 if the validation of the commits succeeded
validate_commits() {
ALL_PASSED=true
# create an associative array with keys using the Unix epoch commit time and value the commit hash
# this array can be easily used to sort in (forward or reverse) order of time
for HASH in "${!COMMITS[@]}"; do
UNIX_EPOCH_TIME="${COMMITS[$HASH]}"
# two commits could have the exact same Unix epoch in seconds
# so make that unique by appending an "x" and the hash
UNIQUE_KEY="${UNIX_EPOCH_TIME}x${HASH}"
COMMIT_TIMES[$UNIQUE_KEY]="${HASH}"
done
# sort into reverse order
SORTED_KEYS=($(printf "%s\n" "${!COMMIT_TIMES[@]}" | sort -r))
# process the commits from latest time to oldest time
ALL_PASSED=true
for ENTRY in "${SORTED_KEYS[@]}"; do
COMMIT_HASH=${COMMIT_TIMES[${ENTRY}]}
log "${ENTRY} has value ${COMMIT_HASH}"
NUM_COMMITS_CHECKED=${#PROCESSED_COMMIT[@]}
if [[ ${NUM_COMMITS_CHECKED} -lt ${MAX_COMMITS_TO_CHECK} ]]; then
if ! validate_commit "$COMMIT_HASH"; then
ALL_PASSED=false
fi
fi
done
if [ "$ALL_PASSED" = true ]; then
if [ "$ALL_PASSED"=true ]; then
return 0
fi
return 1
@@ -412,21 +326,10 @@ echo ""
echo_info "Validating timestamps. This may take a while..."
echo ""
if [[ ${MAX_COMMITS_TO_CHECK} -ge 1 ]]; then
find_all_commits "$COMMIT_HASH"
if validate_commits; then
echo_success "Validation OK: ${NUM_COMMITS_CHECKED} 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."
exit 1
fi
if validate_commit_and_parents "$COMMIT_HASH"; then
echo_success "Validation OK: All timestamped commits in the commit history of $COMMIT_HASH contain at least one valid timestamp."
exit 0
else
if validate_commit_and_parents "$COMMIT_HASH"; then
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."
exit 1
fi
fi
echo_error "Validation Failed: There are timestamped commits in the commit history of $COMMIT_HASH which do not contain any valid timestamps."
exit 1
fi