Skip to content

Instantly share code, notes, and snippets.

@Manouchehri
Last active March 16, 2025 08:46
Show Gist options
  • Save Manouchehri/fd754e402d98430243455713efada710 to your computer and use it in GitHub Desktop.
Save Manouchehri/fd754e402d98430243455713efada710 to your computer and use it in GitHub Desktop.
List of free rfc3161 servers.
https://rfc3161.ai.moda
https://rfc3161.ai.moda/adobe
https://rfc3161.ai.moda/microsoft
https://rfc3161.ai.moda/apple
https://rfc3161.ai.moda/any
http://rfc3161.ai.moda
http://timestamp.digicert.com
http://timestamp.globalsign.com/tsa/r6advanced1
http://rfc3161timestamp.globalsign.com/advanced
http://timestamp.sectigo.com
http://timestamp.apple.com/ts01
http://tsa.mesign.com
http://time.certum.pl
https://freetsa.org
http://tsa.startssl.com/rfc3161
http://dse200.ncipher.com/TSS/HttpTspServer
http://zeitstempel.dfn.de
https://ca.signfiles.com/tsa/get.aspx
http://services.globaltrustfinder.com/adss/tsa
https://tsp.iaik.tugraz.at/tsp/TspRequest
http://timestamp.entrust.net/TSS/RFC3161sha2TS
http://timestamp.acs.microsoft.com
@vasekkral
Copy link

Thanks for tip.

But once again: we are not able to generate a time stamp unless we have CA root certificate in the local "trusted" list.
Would it be possible to provide a list (URLs) of all available timestamping CA root certificates?

@Manouchehri
Copy link
Author

@vasekkral Sure. Note, these certificates do change over time.

#!/usr/bin/env bash

# Available cryptographic hash algorithms for timestamp requests
# These algorithms are tried sequentially until a successful response is received
hash_algorithms=(
    "sha512" "blake2b512" "blake2s256" "md4" "md5" "md5-sha1" "mdc2" "ripemd"
    "ripemd160" "rmd160" "sha1" "sha224" "sha256" "sha3-224" "sha3-256"
    "sha3-384" "sha3-512" "sha384" "sha512-224" "sha512-256" "shake128"
    "shake256" "sm3" "ssl3-md5" "ssl3-sha1" "whirlpool"
)

# Attempts to obtain a timestamp token from a TSA server using specified parameters
# Returns 0 on success, 1 on failure
try_timestamp_request() {
    local url="$1"          # TSA server endpoint
    local hash_algo="$2"    # Cryptographic hash algorithm
    local tmp_query="$3"    # Path to store the timestamp request
    local tmp_reply="$4"    # Path to store the server's response
    local tmp_token="$5"    # Path to store the extracted timestamp token

    # Process flow:
    # 1. Generate random data as input
    # 2. Create a timestamp query using the specified hash algorithm
    # 3. Send the query to the TSA server
    # 4. Extract the timestamp token from the response
    if openssl rand 512 | \
       openssl ts -query -data - -cert -"$hash_algo" > "$tmp_query" 2>/dev/null && \
       curl -H "Content-Type: application/timestamp-query" \
            -H "Accept: application/timestamp-reply" \
            -s -S --data-binary @"$tmp_query" "$url" -o "$tmp_reply" && \
       openssl ts -reply -in "$tmp_reply" -token_out -out "$tmp_token" 2>/dev/null; then
        return 0    # All operations completed successfully
    else
        return 1    # One or more operations failed
    fi
}

# Main processing loop: Retrieve and process TSA server information
curl -s https://rfc3161.ai.moda/servers.json | \
jq -r '.[] | {name: .name, url: .url} | @json' | \
while read -r line; do
    # Extract server details from JSON response
    name=$(echo "$line" | jq -r '.name')   # Server's friendly name
    url=$(echo "$line" | jq -r '.url')     # Server's API endpoint

    # Create filesystem-safe server name by removing special characters
    safe_name=$(echo "$name" | tr -c '[:alnum:]' '_' | tr -s '_' | sed 's/^_//;s/_$//')

    # Create temporary storage for request/response data
    tmp_query=$(mktemp)
    tmp_reply=$(mktemp)
    tmp_token=$(mktemp)

    success=false           # Tracks if any attempt succeeded
    successful_hash=""      # Records which hash algorithm worked

    # Try each hash algorithm until successful
    for hash_algo in "${hash_algorithms[@]}"; do
        echo "Trying $hash_algo for $name..."
        if try_timestamp_request "$url" "$hash_algo" "$tmp_query" "$tmp_reply" "$tmp_token"; then
            success=true
            successful_hash="$hash_algo"
            break
        fi
    done

    if [ "$success" = true ]; then
        # Extract and save the CA certificate from the successful response
        if openssl pkcs7 -inform DER -in "$tmp_token" -print_certs -outform PEM -out "${safe_name}.pem" 2>/dev/null; then
            echo "Successfully extracted CA certificate for: $name (using $successful_hash)"
            echo "$name,$url,$successful_hash" >> successful_servers.log
        else
            echo "$url" >> failed_ca_certs.log
            echo "Failed to extract CA certificate for: $name"
        fi
    else
        echo "$url" >> failed_ca_certs.log
        echo "Failed to get timestamp response from: $name (tried all hash algorithms)"
    fi

    # Cleanup temporary files to prevent disk space issues
    rm -f "$tmp_query" "$tmp_reply" "$tmp_token"
done

This will dump the full certificate chain for all of the CAs. e.g. this is what my folder looks like after running the script:

APED.pem					Entrust.pem					QuoVadis_China.pem
Adacom.pem					FreeTSA.pem					QuoVadis_EU.pem
Aloaha.pem					GlobalSign.pem					SDA_GOV_GE.pem
Apple.pem					IdenTrust.pem					SEP_Bulgaria.pem
Azure.pem					Instituto_dos_Registos_e_do_Notariado_I_P.pem	SSL_com.pem
BalTstamp.pem					Izenpe.pem					Sectigo.pem
Belgium_Federal_Goverment.pem			Lex_Persona.pem					SwissSign.pem
CNBS.pem					Mahidol_University.pem				Swiss_Goverment.pem
CatCert.pem					MeSign.pem					TSA_SINPE.pem
Certum.pem					Netlock.pem					successful_servers.log
Digicert.pem					QuoVadis.pem

@vasekkral
Copy link

@Manouchehri great, thanks a lot, works perfectly. Now we can call our "time stamper" util with your load balancer.

@HeikoSchlittermann
Copy link

I created a simple time stamp query http(s) client and sent a simple query to the servers mentioned in your list. Here are the simplified results:
Probably some of these URLs need a path (e.g. freetsa.org should be http(s)://freetsa.org/tsr).

http://timestamp.globalsign.com/tsa/r6advanced1: OK
http://timestamp.digicert.com: OK
http://timestamp.acs.microsoft.com: OK 
http://time.certum.pl: OK
http://rfc3161timestamp.globalsign.com/advanced: OK

http://zeitstempel.dfn.de: fail
http://tsa.startssl.com/rfc3161: fail
http://tsa.mesign.com: fail
http://timestamp.sectigo.com: fail
http://timestamp.entrust.net/TSS/RFC3161sha2TS: fail
http://timestamp.apple.com/ts01: fail
https://tsp.iaik.tugraz.at/tsp/TspRequest: fail
https://rfc3161.ai.moda/microsoft: fail
https://rfc3161.ai.moda: fail 
https://rfc3161.ai.moda/apple: fail
https://rfc3161.ai.moda/any: fail
https://rfc3161.ai.moda/adobe: fail
https://freetsa.org: fail
http://services.globaltrustfinder.com/adss/tsa: fail
https://ca.signfiles.com/tsa/get.aspx: fail
http://rfc3161.ai.moda: fail
http://dse200.ncipher.com/TSS/HttpTspServer: fail

@Manouchehri
Copy link
Author

@HeikoSchlittermann Could you please explain how your client works? Those results seem very wrong to me.

@JohnPlanetary
Copy link

The following have stopped working for years:
http://tsa.startssl.com/rfc3161
http://services.globaltrustfinder.com/adss/tsa
http://dse200.ncipher.com/TSS/HttpTspServer

The following, as mentioned, had the URL wrong:
https://freetsa.org it should be: https://freetsa.org/tsr

The rest is working properly.
So something is wrong with thou simple time stamp client.

@kashmirix
Copy link

kashmirix commented Mar 12, 2025

rfc3161 timestamping servers – March 2025 update

[#] = LTV (long-term validity) enabled
[*] = increased sigvalue size; if using Adobe Acrobat on Windows, a registry modification may be required in accordance with these instructions

Working

QUALIFIED (EU Trust List)

http://tss.accv.es:8318/tsa [#]
https://timestamp.aped.gov.gr/qtss [*]
http://tsa.baltstamp.lt [#]
http://tsa.belgium.be/connect [#]
http://ts.cartaodecidadao.pt/tsa/server [LTV]
http://ts.quovadisglobal.com/eu [# *]
http://tsa.izenpe.com [#]
http://timestamp.sectigo.com/qualified

TRUSTED (Adobe Trust List)

http://rfc3161.ai.moda (and other URL variants) [*]
http://timestamp.digicert.com
http://timestamp.comodoca.com (and other URL variants) [*]
http://timestamp.entrust.net/TSS/RFC3161sha2TS
http://timestamp.identrust.com
http://ts.quovadisglobal.com/ch [*]
http://timestamp.sectigo.com
http://ts.ssl.com
http://tsa.swisssign.net [*]
https://tsa.wotrus.com

UNTRUSTED

http://timestamp.apple.com/ts01
http://time.certum.pl [*]
https://tsa.cesnet.cz:3162/tsa
http(s)://zeitstempel.dfn.de [*]
http://tsa.sinpe.fi.cr/tsaHttp/ (trailing slash required)
http://timestamp.globalsign.com/advanced (and other URL variants)
https://freetsa.org/tsr
http://tsa.lex-persona.com/tsa
https://tsa.mahidol.ac.th/tsa/get.aspx
https://time.mconnect.mc
http://timestamp.acs.microsoft.com
http://dss.nowina.lu/pki-factory/tsa/good-tsa
http://timestamp.ssl.trustwave.com

Not working

http://psis.catcert.cat/psis/catcert/tsp (timeout)
http://tsa.mesign.com (timeout/crash, likely moved to https://tsa.wotrus.com)
http://tsa.safecreative.org (timeout/crash)
http://tsa.sep.bg (timeout/gone)
http://sha256timestamp.ws.symantec.com/sha256/timestamp (timeout/error)
https://tsp.iaik.tugraz.at/tsp/TspRequest (error)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment