taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

commit ce2633b6496f46f394caec08aefba205bd99de4f
parent 6a4e1cc9196799b241bc9a231593472a495e17cc
Author: Christian Grothoff <christian@grothoff.org>
Date:   Wed,  5 Aug 2026 18:28:55 +0200

clarify paivana cookie computation

Diffstat:
Mdesign-documents/076-paywall-proxy.rst | 19++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/design-documents/076-paywall-proxy.rst b/design-documents/076-paywall-proxy.rst @@ -48,14 +48,27 @@ Steps: this client IP address and ``{website}`` at this time. The *Paivana Cookie* is computed as: - ``cur_time || '-' || crock32(SHA512(website || client_ip || paivana_server_secret || cur_time))``. + ``cur_time || '-' || crock32(HKDF(salt=cur_time, ikm=paivana_server_secret, info=website || '\0' || client_ip))``. where ``cur_time`` in the prefix is the expiration time for the cookie (and thus the access to the article) in seconds - (to keep it short) while in the hash it is usually binary GNUnet - timestamp in network byte order. + (to keep it short) while in the salt it is the binary GNUnet + absolute time (microseconds) in network byte order. + ``HKDF`` is GNUnet's HKDF (``GNUNET_CRYPTO_hkdf_gnunet()``, which + extracts with HMAC-SHA-512 and expands with HMAC-SHA-256), and the + output is 512 bits. + Using a keyed PRF instead of a plain hash over the concatenation + ensures that the cookie cannot be forged without the server secret + and that the inputs are unambiguously separated: ``website`` is + terminated by a zero byte before ``client_ip`` is appended, so + different ``(website, client_ip)`` pairs can never yield the same + ``info`` string. ``crock32`` is GNUnet's Crockford-inspired base32 encoding. + The cookie is computed and verified exclusively by paivana-httpd; + the browser only stores and returns it and thus never has to + reconstruct this value. + * If such a cookie is set and valid, the request is reverse-proxied to upstream. *Stop.* * Otherwise, an HTTP 303 See Other to