Timestamping (RFC 3161)
An RFC 3161 Time-Stamp Protocol client — the requester / verifier side, not a TSA. A timestamp authority binds a hash of your data to a trusted time, producing a timestamp token that proves the data existed at that instant: timestamp a release artifact, an audit-log checkpoint, a b.scitt signed statement, a contract.
b.tsa.buildRequest(data, opts) produces the DER TimeStampReq (a message imprint = the hash of your data, plus an optional nonce and a request for the TSA's certificate); b.tsa.parseResponse(der) reads the TimeStampResp, surfacing the PKIStatus (and any failure-info bits) and the token; b.tsa.verifyToken(token, opts) verifies the token against your data and returns the asserted time. The transport (an HTTP POST of application/timestamp-query to the TSA's URL) is the operator's to make — the framework builds the request and verifies the response.
Verification (RFC 3161 §2.4.2 / §2.3) is the security-bearing part and is done in full: the token is a CMS SignedData (b.cms) whose eContentType must be id-ct-TSTInfo; the message imprint inside the TSTInfo must equal the hash of your data (constant-time compare); a sent nonce must round-trip; the signer's certificate must carry the id-kp-timeStamping extended key usage, marked critical and as the only EKU; and the CMS signature over the signed attributes must verify (the messageDigest attribute is checked against the recomputed eContent digest first). An optional trust-anchor set verifies the certificate chain and validity at the asserted time.
Algorithms. Timestamp tokens are third-party artifacts: public TSAs sign with classical RSA (PKCS#1 v1.5 or PSS) or ECDSA over SHA-2, so verification accepts those — the same consume-what-exists stance as b.cose verification. This is not a signing default (the framework is not the TSA); it is verification of externally-produced tokens. The message-imprint hash you request defaults to SHA-512 and may be any of SHA-256 / 384 / 512 or SHA3-256 / 512 the TSA supports.
b.tsa.buildRequest(data, opts?) #
{
{
hashAlg: string, // "SHA-512" (default) | "SHA-256" | "SHA-384" | "SHA3-256" | "SHA3-512"
hashed: boolean, // true means `data` is already the digest (must match hashAlg length)
reqPolicy: string, // request a specific TSA policy OID (dotted)
nonce: Buffer, // explicit nonce bytes, or false to omit (default: random 8 bytes)
certReq: boolean, // ask the TSA to include its cert (default true)
}
}
Build a DER-encoded RFC 3161 TimeStampReq for data. POST the returned bytes to the TSA as application/timestamp-query; keep the returned nonce to pass to verifyToken. By default a random 64-bit nonce is included and the TSA is asked to return its certificate.
var req = b.tsa.buildRequest(releaseTarball, { hashAlg: "SHA-512" });
// POST req.der to the TSA; keep req.nonce for verifyToken
// → { der, nonce, hashAlg, messageImprint }
b.tsa.parseResponse(der) #
Parse a DER RFC 3161 TimeStampResp. Returns the PKIStatus and, when the request was granted, the timestamp token (the DER ContentInfo to pass to verifyToken). A non-granted status surfaces the status integer, any free-text, and the decoded failure-info flags rather than throwing — the caller decides how to react.
var resp = b.tsa.parseResponse(httpBodyBytes);
if (resp.granted) { var out = b.tsa.verifyToken(resp.token, { data: tarball, nonce: req.nonce }); }
// → { granted: true, status: 0, token, statusString: null, failInfo: [] }
b.tsa.verifyToken(token, opts) #
{
{
data: Buffer, // the timestamped data (hashed with hashAlg)
hash: Buffer, // OR a pre-computed digest (with hashAlg)
hashAlg: string, // default "SHA-512" — must match the imprint
nonce: Buffer, // require the token nonce to match (from buildRequest)
trustAnchorsPem: string|string[], // PEM trust root(s) to authenticate the TSA — REQUIRED unless allowUntrustedIssuer
allowUntrustedIssuer: boolean, // accept a token with no trust anchor (result carries issuerTrusted:false)
at: Date, // validity instant for chain check (default: genTime); must be a valid Date
}
}
Verify an RFC 3161 timestamp token against your data and return the asserted time. Performs the full §2.4.2 / §2.3 check: eContentType is id-ct-TSTInfo, the message imprint equals the hash of opts.data (or opts.hash), a sent nonce round-trips, the signer cert's extendedKeyUsage is a critical, sole id-kp-timeStamping, and the CMS signature verifies. The signer certificate is embedded in the token (and therefore attacker-controlled), so opts.trustAnchorsPem is required by default — without it a self-signed token would pass on its self-contained signature alone. To accept an unauthenticated timestamp, set opts.allowUntrustedIssuer:true; the result then carries issuerTrusted:false.
var out = b.tsa.verifyToken(resp.token, { data: tarball, hashAlg: "SHA-512", nonce: req.nonce, trustAnchorsPem: caPem });
// → { genTime, policy, serialHex, accuracy, hashAlg, signerCertPem, issuerTrusted: true }
Last updated 2026-08-08T16:39:49.652Z by seeder.