2 Commits

Author SHA1 Message Date
Artur Neumann
8b507a7dbd -----TIMESTAMP COMMIT-----
Version: 1

Algorithm: sha1

Preimage: version:1,parent:cb082d29fb182cf908fdc7f89b3336204444c65c,tree:42bfceabd878ae1144c9d7a461e5b91c5bac7d7d

Digest: 1d5032b3c53be0a86fc193a02211fac12febc24f

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 - 1d 50 32 b3 c5 3b e0 a8-6f c1 93 a0 22 11 fa c1   .P2..;..o..."...
     0010 - 2f eb c2 4f                                       /..O
 Serial number: 0x0527B39A
 Time stamp: Jan 24 10:23:07 2025 GMT
 Accuracy: unspecified
 Ordering: yes
 Nonce: 0xF5E891CBF8D33F94
 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-----
 MIIFOAYJKoZIhvcNAQcCoIIFKTCCBSUCAQMxDzANBglghkgBZQMEAgMFADCCAX8G
 CyqGSIb3DQEJEAEEoIIBbgSCAWowggFmAgEBBgQqAwQBMCEwCQYFKw4DAhoFAAQU
 HVAys8U74KhvwZOgIhH6wS/rwk8CBAUns5oYDzIwMjUwMTI0MTAyMzA3WgEB/wIJ
 APXokcv40z+UoIIBEaSCAQ0wggEJMREwDwYDVQQKEwhGcmVlIFRTQTEMMAoGA1UE
 CxMDVFNBMXYwdAYDVQQNE21UaGlzIGNlcnRpZmljYXRlIGRpZ2l0YWxseSBzaWdu
 cyBkb2N1bWVudHMgYW5kIHRpbWUgc3RhbXAgcmVxdWVzdHMgbWFkZSB1c2luZyB0
 aGUgZnJlZXRzYS5vcmcgb25saW5lIHNlcnZpY2VzMRgwFgYDVQQDEw93d3cuZnJl
 ZXRzYS5vcmcxIjAgBgkqhkiG9w0BCQEWE2J1c2lsZXphc0BnbWFpbC5jb20xEjAQ
 BgNVBAcTCVd1ZXJ6YnVyZzELMAkGA1UEBhMCREUxDzANBgNVBAgTBkJheWVybjGC
 A4owggOGAgEBMIGjMIGVMREwDwYDVQQKEwhGcmVlIFRTQTEQMA4GA1UECxMHUm9v
 dCBDQTEYMBYGA1UEAxMPd3d3LmZyZWV0c2Eub3JnMSIwIAYJKoZIhvcNAQkBFhNi
 dXNpbGV6YXNAZ21haWwuY29tMRIwEAYDVQQHEwlXdWVyemJ1cmcxDzANBgNVBAgT
 BkJheWVybjELMAkGA1UEBhMCREUCCQDB6YYWDajpgjANBglghkgBZQMEAgMFAKCB
 uDAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTI1
 MDEyNDEwMjMwN1owKwYLKoZIhvcNAQkQAgwxHDAaMBgwFgQUkW2j2GDsyoLjS8Wd
 F5Pn6WiHXxQwTwYJKoZIhvcNAQkEMUIEQN7EaC85Vyk+0l3HqRxUgpijlmVkgazq
 Dxy0KLnjoATJvB+q/cqWelCj4mqWq8J8getOgSm4RvTwveCtInV5fvowDQYJKoZI
 hvcNAQEBBQAEggIAcx+r+yFu6vR/Wb+tLmx6R/kNSYHQEJN7e9chp8BQieFBrP2w
 Vc+TSWgkWfZEshOWwMitexUVJGNcbsfbpe3xyUQQ9UEpu4R2w8DFkUkR+0GCoFXJ
 2dOWSkN1o7AjziV4BWJp2n7qV5f2llG4aHylLSHGtFc5UtmfmzlfCX13nSyjqBxW
 YzOl8m0o51PrIqnz7pWvUtwlqmvIg1Cr4aVr7APLXF7sDvB4ZspYKmXlyBdAgHU0
 tqJUqj3oBeLUaUQw2z6ThwsTVu0v3BViTz5q5FpoUYQT5lO+of2bK+UgQIpNuRtv
 XoqVnP7YR0CXUl/AW12Tjfb6Ifp9MZu+Pzhh9BJq1Wur/fXrL/CnJC/jhowVa24Z
 e6oq203R61ZUCsBOYzGaDGFwqF+D86+caZePcQfQFIB9voJbhSkoqKQgvWoFIZBD
 ukH16CoMewT2VkmorF7IUhBTkglNJKKKoLgdV3jv+Zyu8nknJcJTcaPfGWB47h3p
 gNc2GceOVBmSh22+GcWEjDitQ5sNnI7lJoyIV/H0yADaWVEYCDIKcmQo/KRvsTq2
 Y1dYkKUtHkVfxOC5BD7rKjcOCm18uTpRdhkZvBteAa4XBGbkiAYWPgqkZtMAlj5J
 2xVX2+Iki4X/B794vpR+5bdXNEbnPrhCuUnvLK1kuiUSYzCO9L5jn2tMhIM=
 -----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 - 1d 50 32 b3 c5 3b e0 a8-6f c1 93 a0 22 11 fa c1   .P2..;..o..."...
     0010 - 2f eb c2 4f                                       /..O
 Serial number: 0x58137BC933BED608
 Time stamp: Jan 24 10:23:08 2025 GMT
 Accuracy: unspecified
 Ordering: no
 Nonce: 0x3892A48C5B5008BF
 TSA: DirName:/DC=cz/DC=cesnet-ca/O=CESNET/CN=tsa.cesnet.cz
 Extensions:

 -----BEGIN RFC3161 TOKEN-----
 MIID1AYJKoZIhvcNAQcCoIIDxTCCA8ECAQMxDzANBglghkgBZQMEAgEFADCBzQYL
 KoZIhvcNAQkQAQSggb0EgbowgbcCAQEGDCsGAQQBga8IAQIDLTAhMAkGBSsOAwIa
 BQAEFB1QMrPFO+Cob8GToCIR+sEv68JPAghYE3vJM77WCBgPMjAyNTAxMjQxMDIz
 MDhaAgg4kqSMW1AIv6BcpFowWDESMBAGCgmSJomT8ixkARkWAmN6MRkwFwYKCZIm
 iZPyLGQBGRYJY2VzbmV0LWNhMQ8wDQYDVQQKDAZDRVNORVQxFjAUBgNVBAMMDXRz
 YS5jZXNuZXQuY3oxggLZMIIC1QIBATBsMGAxEjAQBgoJkiaJk/IsZAEZFgJjejEZ
 MBcGCgmSJomT8ixkARkWCWNlc25ldC1jYTESMBAGA1UECgwJQ0VTTkVUIENBMRsw
 GQYDVQQDDBJQZXJzb25hbCBTaWduaW5nIDICCGr3hmg6wNdwMA0GCWCGSAFlAwQC
 AQUAoIIBPjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkF
 MQ8XDTI1MDEyNDEwMjMwOFowLQYJKoZIhvcNAQk0MSAwHjANBglghkgBZQMEAgEF
 AKENBgkqhkiG9w0BAQsFADAvBgkqhkiG9w0BCQQxIgQggJxlA/YfI/tcWVRjKA1t
 sIMo0ZiOxUfdYFmPMluSu88wgaEGCyqGSIb3DQEJEAIMMYGRMIGOMIGLMIGIBBRQ
 JOwLmUsiMPAKD5CmDR0oHRs/vjBwMGSkYjBgMRIwEAYKCZImiZPyLGQBGRYCY3ox
 GTAXBgoJkiaJk/IsZAEZFgljZXNuZXQtY2ExEjAQBgNVBAoMCUNFU05FVCBDQTEb
 MBkGA1UEAwwSUGVyc29uYWwgU2lnbmluZyAyAghq94ZoOsDXcDANBgkqhkiG9w0B
 AQsFAASCAQBmZoUcuxNtRLYwz9qsrGzlCHFPA8fRzz19pYqs8SisOG7F8l+dcIaq
 hPZI7voGQjyIiDF8BEVF57oUEqDRVXBBtWgxYevhSldTaEX20cLTLsUnOGDTfy5S
 xtmAKjcMa6NzcvtwHAH8r6t7ivATG+Adhpa6ZLRQXRzRN77RHVNjdUwlz9Wzg9fg
 zVNGJSuOnkHzFja31KzGdWX6KduNPkTyWqNHA28hvOi3K1Eq4PfPqXVnGiftpJkK
 dBFluJSefb4X9JHEtFmOAERvYumO1/foxxPUq1+DPu3oSfBRNEwerUqO440e8dIg
 kE3BrZ4NZZ8/pDdGfpuPWLjxAftzKZ/9
 -----END RFC3161 TOKEN-----
2025-01-24 16:08:08 +05:45
Artur Neumann
cb082d29fb automatically validate all timestamps
any time a change is proposed or incrporated int the archive (main
branch) this check runs and
1. checks if all certificates of the Time-stamping authorities are as
   expected
2. all new and historic time-stamps are valid
2025-01-24 16:07:57 +05:45
5 changed files with 2278 additions and 2255 deletions

View File

@@ -1,3 +1,14 @@
location / {
proxy_pass http://localhost:5232/;
proxy_set_header X-Script-Name /radicale;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_pass_header Authorization;
}
name: Validate Trusted Timestamps Actions Demo
run-name: ${{ gitea.actor }} is validating the trusted timestamps of all commits 🚀
on: [push]

File diff suppressed because it is too large Load Diff

View File

@@ -2,17 +2,17 @@
MIIC5jCCAc4CAQEwDQYJKoZIhvcNAQELBQAwcjELMAkGA1UEBhMCVVMxFTATBgNV
BAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8G
A1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBDQRcN
MjUwMjEyMDUyMjQ1WhcNMjUwMjE5MDUyMjQ1WjCB9TAhAhAL2v0LKRQzmpYSZqw1
MjUwMTI0MDUxNDI4WhcNMjUwMTMxMDUxNDI4WjCB9TAhAhAL2v0LKRQzmpYSZqw1
OkdEFw0xNjEwMjQxNzQyNDlaMCECEAH40oMtKRkZcbNQw9u8pQAXDTE2MTExMTE1
MjEzNFowIQIQClKwbEb16yWgi9U/3Ht4hhcNMTgwOTAzMTIxMTQyWjAhAhAFlx7K
SlmJinvPTLfjd5doFw0xOTA5MzAwODE2MjRaMCECEAxFkEkmQLBOlEh/jEwCeJAX
DTIxMDIwOTIyMzk0MlowIQIQBMvnUVSd49EL7YN0yV7iRBcNMjEwMjA5MjMyMzM3
WjAhAhALmUrhw5aLANVesgZ0jpseFw0yMTAyMDkyMzI0MjNaoDAwLjAfBgNVHSME
GDAWgBT0tuEgHf4prtLkYaWyoiWyyBc1bjALBgNVHRQEBAICDO8wDQYJKoZIhvcN
AQELBQADggEBALr4VopJYkMfQ97HiyqytcWRY/vgyU/LxOwlH0/1DBSeeObQB0Nj
uF7vcF2bhbpnxba7gvzOPryudwtbqquf2cl3CJG6MC2D8Nk1XzntDnpxCjVSfsAr
158zAWPevyiuj3yzFz04mYALt/ZmOJMTF0vyKN8cg5bwfLu3itV6b6vhpuloIhRc
Hmsbgr3BtCVHkf4vJWq/qKDEMcOhSrJ6wxGCzVyphenewSIbVcogj19cRZDFPWOC
3sAy/GY3Rz0qK30tDvNbE1uum8gy5ijXFmepJ/lEetRCvrIsxTsXJOj0tqVZfIIQ
E1YWUZ57TiBBrdS+dTgmRxkN/zaAfYVAIck=
GDAWgBT0tuEgHf4prtLkYaWyoiWyyBc1bjALBgNVHRQEBAICDNwwDQYJKoZIhvcN
AQELBQADggEBAGuGW4lrI1pz4IwilL1u3rFRWD43/2Cu0+Pc1+tRx+QqB42aB0Jl
esdIRc7t7bZ+5wmJyl5DTToQ3Vm7v34dXlblmmlJ2IM+1BKNEO4jMg82i4CFHtaE
1e2lTfCOKR7YiTmUv/E44jAeQNJbt3k/6gnpDTGafJTIybYNh3uVDtC8Iiun4DKH
x1qe0qzuixF2TDdTRgPP293nShxNJP5G9G5JaOGSreVOItwEhI+GP6rrPffcanfJ
v7ghEutuJCE2BGZkqL5iEGgAbMYhFitCu58rfwCHF78uz8T/kxbe5Ax2Zu1IV3is
kuc5vOHsT/GFYnMC4PZn9J9eYKLE6mzr0SY=
-----END X509 CRL-----

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

View File

@@ -42,10 +42,6 @@ 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
KEY="$1"
@@ -65,16 +61,6 @@ 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
@@ -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
@@ -343,64 +315,6 @@ validate_commit_and_parents() {
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
return 0
fi
return 1
}
echo_info "Checking repository integrity..."
#check git repository integrity
if ! git fsck --full --strict --no-progress --no-dangling "$COMMIT_HASH"; then
@@ -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
else
if validate_commit_and_parents "$COMMIT_HASH"; then
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
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