RFC 3161 Client
A Python client library for interacting with RFC 3161 compliant Timestamping Authorities (TSAs). It enables users to request timestamps for data and verify existing RFC 3161 timestamp responses. The library is actively maintained, with regular releases addressing bug fixes, security enhancements, and feature improvements, currently at version 1.0.6.
Common errors
-
requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))cause The Timestamping Authority (TSA) server is unreachable, the URL is incorrect, or a network issue (e.g., firewall) is blocking the connection.fixVerify that the `tsa_url` is correct and the TSA server is online and accessible from your environment. Check network connectivity and local firewall rules. -
rfc3161_client.exceptions.TSAResponseError: An error occurred while parsing the response from the TSA.
cause The TSA responded with data that could not be parsed as a valid RFC 3161 timestamp response, or indicated an error internally. This can happen if the TSA is misconfigured or if the request was malformed.fixReview the `TSAResponseError` message for specific details from the TSA. Ensure your `TimestampRequest` parameters (e.g., `hash_algorithm`) are supported by the TSA. Consult the TSA's documentation or status page. -
rfc3161_client.exceptions.TimestampVerificationError: ...
cause The timestamp response could not be successfully verified. Common causes include an invalid signature, an untrusted certificate chain (e.g., missing root CA), a certificate that is not valid for timestamping, or a mismatch between the provided `hashed_message` and what's in the timestamp token.fixFor production, always supply `trusted_root_certs` for the TSA to the `VerifierBuilder`. Ensure the `hashed_message` and `hash_algorithm` passed to `verifier.verify()` precisely match the data that was timestamped. Review the detailed error message for specific verification failures. -
AttributeError: 'Verifier' object has no attribute 'verify_message'
cause The `verify_message` method, which allows direct verification against the original message instead of its hash, was added in `v1.0.2` and fully exposed in `v1.0.3`. This error occurs if you are attempting to use `verify_message` on an older version of the library.fixUpgrade to `rfc3161-client` `v1.0.3` or newer to use the `verify_message` method. If upgrading is not immediately possible, manually compute the hash of your message and use the `verifier.verify(timestamp_response, hashed_message, hash_algorithm)` method.
Warnings
- gotcha Prior to v1.0.6, the verification process could incorrectly pick the leaf certificate during chain validation, potentially allowing an attacker to spoof a timestamp's origin if they could modify the response. This was a critical security vulnerability in verification.
- gotcha Before v1.0.4, timestamp verification did not correctly use the timestamp's creation time as the reference for certificate chain validity. This could lead to incorrect validation of older timestamps, where a certificate might have expired relative to the current time but was valid at the time the timestamp was issued.
- breaking The return type of `VerifierBuilder.build()` was changed from `_Verifier` (a private class) to `Verifier` in v1.0.2. While `_Verifier` was not intended for direct use, code that type-hinted or explicitly accessed private attributes of `_Verifier` may break.
- gotcha As of v1.0.1, the `Verifier` enforces that the Extended Key Usage (EKU) in the TSA's signing certificate explicitly includes the `id-kp-timeStamping` OID. If a TSA's certificate lacks this OID, verification will now fail where it might have implicitly succeeded in older versions.
Install
-
pip install rfc3161-client
Imports
- TimestampRequest
from rfc3161_client import TimestampRequest
- VerifierBuilder
from rfc3161_client import VerifierBuilder
- HashAlgorithm
from rfc3161_client import HashAlgorithm
- TimestampVerificationError
from rfc3161_client.exceptions import TimestampVerificationError
- TSAResponseError
from rfc3161_client.exceptions import TSAResponseError
Quickstart
import os
import hashlib
from rfc3161_client import TimestampRequest, VerifierBuilder, HashAlgorithm
from rfc3161_client.exceptions import TSAResponseError, TimestampVerificationError
# Use a public TSA URL. For production, ensure this is a trusted service.
# Example: http://timestamp.digicert.com or a URL from your trusted provider.
TSA_URL = os.environ.get('RFC3161_TSA_URL', 'http://timestamp.digicert.com')
# 1. Prepare data to be timestamped
message = b"This is the data to be timestamped."
message_hash = hashlib.sha256(message).digest()
print(f"Attempting to timestamp data using TSA: {TSA_URL}")
# 2. Request a timestamp from the TSA
try:
request = TimestampRequest(
tsa_url=TSA_URL,
hashed_message=message_hash,
hash_algorithm=HashAlgorithm.SHA256,
)
timestamp_response = request.get_timestamp_response()
print("Timestamp received successfully.")
# 3. Verify the timestamp response
# For robust verification, provide 'trusted_root_certs' of the TSA.
# If not provided, the verifier attempts to build a chain from certs
# embedded in the response or system CAs where possible (less secure).
verifier = VerifierBuilder().build()
is_valid = verifier.verify(
timestamp_response=timestamp_response,
hashed_message=message_hash,
hash_algorithm=HashAlgorithm.SHA256,
# trusted_root_certs=[b"-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"],
)
if is_valid:
print("Timestamp verification successful.")
else:
print("Timestamp verification FAILED.")
except TSAResponseError as e:
print(f"Error from TSA: {e}")
except TimestampVerificationError as e:
print(f"Timestamp verification error: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")