No summary available
Project Links
Meta
Author: Trail of Bits
Requires Python: >=3.9
Classifiers
Development Status
- 5 - Production/Stable
Programming Language
- Rust
- Python :: 3
- Python :: Implementation :: CPython
- Python :: Implementation :: PyPy
Intended Audience
- Developers
License
- OSI Approved :: Apache Software License
Typing
- Typed
rfc3161-client
rfc3161-client is a Python library implementing the Time-Stamp Protocol (TSP)
described in RFC 3161.
It is composed of three subprojects:
- :crab: tsp-asn1: A Rust crate using
rust-asn1to create the types used by the Time-Stamp protocol. This crate depends onrust-asn1andcryptographyto minimize the amount of duplicated code. While it is usable as a standalone crate, this is not officially supported. Drop us a message if you are interested in using it. - :crab: rfc3161-client: Another Rust crate that
provides Python bindings to the
tsp-asn1crate using PyO3. - :snake: rfc3161-client A Python library using the crate above to provide a usable API to create Timestamp Request and read Timestamp Response.
Goals and anti-goals
- This library should be correct and provide an accurate implementation of protocol described in the RFC 3161.
- This library does not perform any network activity, it simply provides primitive to build and verify objects. Network activity must be handled separately.
Usage
There are two parts to timestamping: retrieving + verifying the timestamp.
1. Retrieving a timestamp
The below code uses requests to get the timestamp from the Identrust TSA server:
# /// script
# dependencies = [
# "requests",
# "rfc3161-client",
# ]
# ///
import requests
from rfc3161_client import (
decode_timestamp_response,
TimestampRequestBuilder,
VerifierBuilder,
VerificationError,
)
# the data to sign. Could be a hash or any message. Should be bytes
message = b"Hello, World!"
# build the timestamp request
timestamp_request = (
TimestampRequestBuilder().data(message).build()
# Note: you could also add .hash_algorithm(XXX) to specify a specific hash algorithm
)
# TSA servers must be RFC 3161 compliant (see https://github.com/trailofbits/rfc3161-client/issues/46
# for a list of working servers)
tsa_server = "http://timestamp.identrust.com"
# make the request, remember to set content-type headers appropriately
response = requests.post(
tsa_server,
data=timestamp_request.as_bytes(),
headers={"Content-Type": "application/timestamp-query"},
)
response.raise_for_status()
# if successful, should give a valid TimeStampResponse object
timestamp_response = decode_timestamp_response(response.content)
Verifying a timestamp
The second part is to verify the timestamp, this is done against a set of
root certificates. In this example, we'll Mozilla's list of root certs
provided in the certifi package:
import certifi
from cryptography import x509
import hashlib
# get trusted root certs from certifi
with open(certifi.where(), "rb") as f:
cert_authorities = x509.load_pem_x509_certificates(f.read())
# for each of the root certs we have, try to verify the TSR with it
root_cert = None
for certificate in cert_authorities:
verifier = VerifierBuilder().add_root_certificate(certificate).build()
try:
verifier.verify_message(timestamp_response, message)
root_cert = certificate
break
except VerificationError:
continue
# if successful, the TSR was verified and we should have the root cert that signed this TSR :)
print("Here's the root cert that signed your TSR:")
print(root_cert)
License
Copyright 2024 Trail of Bits
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Authors
Trail of Bits
1.0.5
Sep 23, 2025
1.0.4
Aug 11, 2025
1.0.3
Jun 20, 2025
1.0.2
May 19, 2025
1.0.1
Mar 26, 2025
1.0.0
Dec 31, 2024
0.1.2
Dec 11, 2024
0.1.1
Dec 10, 2024
0.1.0
Oct 18, 2024
0.0.4
Nov 19, 2024
0.0.3
Nov 06, 2024
0.0.2
Oct 30, 2024
Wheel compatibility matrix
Files in release
rfc3161_client-1.0.5-cp39-abi3-macosx_10_12_x86_64.whl (462.8KiB)
rfc3161_client-1.0.5-cp39-abi3-macosx_11_0_arm64.whl (447.5KiB)
rfc3161_client-1.0.5-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.3MiB)
rfc3161_client-1.0.5-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (1.7MiB)
rfc3161_client-1.0.5-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl (2.0MiB)
rfc3161_client-1.0.5-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.0MiB)
rfc3161_client-1.0.5-cp39-abi3-musllinux_1_2_aarch64.whl (2.6MiB)
rfc3161_client-1.0.5-cp39-abi3-musllinux_1_2_armv7l.whl (2.0MiB)
rfc3161_client-1.0.5-cp39-abi3-musllinux_1_2_i686.whl (2.1MiB)
rfc3161_client-1.0.5-cp39-abi3-musllinux_1_2_x86_64.whl (2.2MiB)
rfc3161_client-1.0.5-cp39-abi3-win32.whl (1.8MiB)
rfc3161_client-1.0.5-cp39-abi3-win_amd64.whl (2.2MiB)
rfc3161_client-1.0.5.tar.gz (59.5KiB)