Time-Stamp Protocol (RFC 3161)

Implementation in wolfCrypt
OpenSSL compatibility layer in wolfSSL
Added tests, certificates, examples.
This commit is contained in:
Sean Parkinson
2026-06-25 21:59:57 +10:00
parent 0ecc0c5973
commit ae023a5643
73 changed files with 18311 additions and 27 deletions
+2
View File
@@ -1209,6 +1209,7 @@ my @p7t_encrypted_data = ( 1, 2, 840, 113549, 1, 7, 6 );
my @p7t_compressed_data = ( 1, 2, 840, 113549, 1, 9, 16, 1, 9 );
my @p7t_firmware_pkg_data = ( 1, 2, 840, 113549, 1, 9, 16, 1, 16 );
my @p7t_auth_env_data = ( 1, 2, 840, 113549, 1, 9, 16, 1, 23 );
my @p7t_tstinfo_data = ( 1, 2, 840, 113549, 1, 9, 16, 1, 4 );
my @p7t_encrypted_key_package = ( 2, 16, 840, 1, 101, 2, 1, 2, 78, 2 );
my @pkcs7_types = (
@@ -1222,6 +1223,7 @@ my @pkcs7_types = (
{ name => "ENCRYPTED_DATA", oid => \@p7t_encrypted_data },
{ name => "FIRMWARE_PKG_DATA", oid => \@p7t_firmware_pkg_data },
{ name => "AUTH_ENVELOPED_DATA", oid => \@p7t_auth_env_data },
{ name => "TSTINFO_DATA", oid => \@p7t_tstinfo_data },
{ name => "ENCRYPTED_KEY_PACKAGE", oid => \@p7t_encrypted_key_package },
);
+2
View File
@@ -124,6 +124,8 @@ EXTRA_DIST+= scripts/multi-msg-record.py
dist_noinst_SCRIPTS+= scripts/pem.test
dist_noinst_SCRIPTS+= scripts/tsp.test
EXTRA_DIST += scripts/sniffer-static-rsa.pcap \
scripts/sniffer-ipv6.pcap \
scripts/sniffer-tls13-dh.pcap \
+130
View File
@@ -0,0 +1,130 @@
#!/usr/bin/env bash
# tsp.test
# Time-Stamp Protocol (RFC 3161) tests using the ts example tools, with
# OpenSSL interoperability when an openssl binary is available.
TSP_QUERY=./examples/tsp/tsp_query
TSP_REPLY=./examples/tsp/tsp_reply
TSP_VERIFY=./examples/tsp/tsp_verify
RESULT=0
# Check the examples were built and are usable - can't test without them.
# A feature-disabled stub prints a build hint rather than a usage line.
if [ ! -x "$TSP_QUERY" ] || [ ! -x "$TSP_REPLY" ] || [ ! -x "$TSP_VERIFY" ]; then
echo "ts examples not found -- skipping tsp.test."
exit 77
fi
# The round trip exercises every role, so all three tools must be usable. A
# single-role build (e.g. --enable-tsp with only the responder) leaves the
# others as feature-disabled stubs - skip rather than fail in that case.
for tool in "$TSP_QUERY" "$TSP_REPLY" "$TSP_VERIFY"; do
if ! "$tool" 2>&1 | grep -q "usage:"; then
echo "ts examples not usable (need requester, responder and verifier"\
"roles) -- skipping tsp.test."
exit 77
fi
done
SRC_DIR="$(dirname "$0")/.."
CERTS_DIR="${SRC_DIR}/certs"
if [ ! -f "${CERTS_DIR}/tsa-cert.der" ]; then
echo "TSA certificate not found at ${CERTS_DIR} -- skipping tsp.test."
exit 77
fi
WORK_DIR=./tsp_test.$$
mkdir "$WORK_DIR" || exit 1
cleanup() {
rm -rf "$WORK_DIR"
}
trap cleanup EXIT
fail() {
echo "FAIL: $1"
RESULT=1
}
pass() {
echo "PASS: $1"
}
DATA="$WORK_DIR/data.txt"
REQ="$WORK_DIR/request.tsq"
RESP="$WORK_DIR/response.tsr"
echo "data to be time-stamped" > "$DATA"
# Choose a TSA credential this build supports: RSA when available,
# otherwise the ECC credential (e.g. a --disable-rsa build).
CERT="${CERTS_DIR}/tsa-cert.der"
KEY="${CERTS_DIR}/tsa-key.der"
CAFILE="${CERTS_DIR}/tsa-cert.pem"
KEYTYPE=
"$TSP_QUERY" "$DATA" "$REQ" >/dev/null 2>&1
if ! "$TSP_REPLY" "$REQ" "$CERT" "$KEY" "$RESP" >/dev/null 2>&1; then
CERT="${CERTS_DIR}/tsa-ecc-cert.der"
KEY="${CERTS_DIR}/tsa-ecc-key.der"
CAFILE="${CERTS_DIR}/tsa-ecc-cert.pem"
KEYTYPE=ecc
fi
# wolfSSL round trip: query -> reply -> verify.
"$TSP_QUERY" "$DATA" "$REQ" >/dev/null &&
"$TSP_REPLY" "$REQ" "$CERT" "$KEY" "$RESP" $KEYTYPE >/dev/null &&
"$TSP_VERIFY" "$DATA" "$REQ" "$RESP" "$CERT" \
>/dev/null
if [ $? -eq 0 ]; then
pass "wolfSSL round trip"
else
fail "wolfSSL round trip"
fi
# Tampered data must not verify.
echo "tampered" >> "$DATA"
if "$TSP_VERIFY" "$DATA" "$REQ" "$RESP" "$CERT" \
>/dev/null 2>&1; then
fail "tampered data detected"
else
pass "tampered data detected"
fi
echo "data to be time-stamped" > "$DATA"
# A request that does not parse gets a rejection response.
head -c 20 "$REQ" > "$WORK_DIR/bad.tsq"
"$TSP_REPLY" "$WORK_DIR/bad.tsq" "$CERT" \
"$KEY" "$WORK_DIR/reject.tsr" $KEYTYPE >/dev/null
if [ $? -eq 0 ] && [ -f "$WORK_DIR/reject.tsr" ]; then
pass "rejection response written"
else
fail "rejection response written"
fi
# OpenSSL interoperability - skipped without an openssl supporting ts.
if openssl ts -query -data "$DATA" -sha256 -cert \
-out "$WORK_DIR/ossl.tsq" >/dev/null 2>&1; then
# OpenSSL verifies a wolfSSL response.
if openssl ts -verify -queryfile "$REQ" -in "$RESP" \
-CAfile "$CAFILE" >/dev/null 2>&1; then
pass "OpenSSL verifies wolfSSL response"
else
fail "OpenSSL verifies wolfSSL response"
fi
# wolfSSL answers an OpenSSL request and OpenSSL verifies it.
"$TSP_REPLY" "$WORK_DIR/ossl.tsq" "$CERT" \
"$KEY" "$WORK_DIR/ossl.tsr" $KEYTYPE >/dev/null &&
"$TSP_VERIFY" "$DATA" "$WORK_DIR/ossl.tsq" "$WORK_DIR/ossl.tsr" \
"$CERT" >/dev/null &&
openssl ts -verify -data "$DATA" -in "$WORK_DIR/ossl.tsr" \
-CAfile "$CAFILE" >/dev/null 2>&1
if [ $? -eq 0 ]; then
pass "wolfSSL answers OpenSSL request"
else
fail "wolfSSL answers OpenSSL request"
fi
else
echo "openssl ts not usable -- skipping interoperability tests."
fi
exit $RESULT