docs: publish Preview 19 dogfood evidence

Export the reviewed allowlisted snapshot from private source commit 05928cebd01b586cf9e9d4b8c8537a7605a6068c. This records the exact candidate, bounded capacity result, stateful migration scratch requirement, authenticated batch identity proof, and immediate live acceptance evidence.

AI-Assisted: OpenAI Codex
Signed-off-by: Cole Speelman <crspeelman@gmail.com>
This commit is contained in:
2026-08-18 21:47:08 -04:00
commit 92a66db3df
201 changed files with 38227 additions and 0 deletions
+362
View File
@@ -0,0 +1,362 @@
// SPDX-License-Identifier: AGPL-3.0-only
// Package webpush implements the deliberately narrow Web Push boundary used
// by Observatory. It accepts only validated HTTPS push-service endpoints and
// encrypts one fixed, generic notification payload.
package webpush
import (
"bytes"
"context"
"crypto/aes"
"crypto/cipher"
"crypto/ecdh"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/binary"
"encoding/json"
"errors"
"fmt"
"io"
"math/big"
"net"
"net/http"
"net/netip"
"net/url"
"strings"
"time"
)
const (
GenericMessage = "Gamertan Observatory needs your attention."
maxEndpointBytes = 2048
maxResponseBodyBytes = 4096
)
var ErrSubscriptionGone = errors.New("web push subscription is gone")
type Subscription struct {
Endpoint string
P256DH []byte
Auth []byte
}
type Options struct {
PrivateKey []byte
Subject string
Timeout time.Duration
Client *http.Client
Now func() time.Time
Random io.Reader
}
type Sender struct {
private *ecdh.PrivateKey
subject string
timeout time.Duration
client *http.Client
now func() time.Time
random io.Reader
}
func New(options Options) (*Sender, error) {
private, err := ecdh.P256().NewPrivateKey(options.PrivateKey)
if err != nil {
return nil, errors.New("web push private key is invalid")
}
if err = validateSubject(options.Subject); err != nil {
return nil, err
}
if options.Timeout < time.Second || options.Timeout > 30*time.Second {
return nil, errors.New("web push timeout must be between 1s and 30s")
}
if options.Now == nil {
options.Now = func() time.Time { return time.Now().UTC() }
}
if options.Random == nil {
options.Random = rand.Reader
}
if options.Client == nil {
options.Client = safeClient(options.Timeout)
}
return &Sender{private: private, subject: options.Subject, timeout: options.Timeout, client: options.Client, now: options.Now, random: options.Random}, nil
}
func (s *Sender) PublicKey() string {
return base64.RawURLEncoding.EncodeToString(s.private.PublicKey().Bytes())
}
func (s *Sender) Send(ctx context.Context, subscription Subscription) error {
endpoint, err := ValidateEndpoint(subscription.Endpoint)
if err != nil {
return err
}
body, _, err := encrypt([]byte(GenericMessage), subscription, s.random)
if err != nil {
return err
}
jwt, err := s.vapid(endpoint, s.now(), s.random)
if err != nil {
return err
}
requestContext, cancel := context.WithTimeout(ctx, s.timeout)
defer cancel()
request, err := http.NewRequestWithContext(requestContext, http.MethodPost, endpoint.String(), bytes.NewReader(body))
if err != nil {
return errors.New("create web push request")
}
request.Header.Set("Authorization", "vapid t="+jwt+", k="+s.PublicKey())
request.Header.Set("Content-Encoding", "aes128gcm")
request.Header.Set("Content-Type", "application/octet-stream")
request.Header.Set("TTL", "300")
request.Header.Set("Urgency", "high")
response, err := s.client.Do(request)
if err != nil {
return errors.New("deliver web push notification")
}
defer response.Body.Close()
_, _ = io.Copy(io.Discard, io.LimitReader(response.Body, maxResponseBodyBytes))
if response.StatusCode == http.StatusGone || response.StatusCode == http.StatusNotFound {
return ErrSubscriptionGone
}
if response.StatusCode < 200 || response.StatusCode > 299 {
return fmt.Errorf("web push service returned status %d", response.StatusCode)
}
return nil
}
func ValidateEndpoint(raw string) (*url.URL, error) {
if len(raw) < len("https://a.b/x") || len(raw) > maxEndpointBytes || !strings.HasPrefix(raw, "https://") {
return nil, errors.New("web push endpoint must be a bounded HTTPS URL")
}
parsed, err := url.Parse(raw)
if err != nil || parsed.Scheme != "https" || parsed.Host == "" || parsed.User != nil || parsed.Fragment != "" {
return nil, errors.New("web push endpoint is invalid")
}
if parsed.Port() != "" && parsed.Port() != "443" {
return nil, errors.New("web push endpoint port is not permitted")
}
host := parsed.Hostname()
if net.ParseIP(host) != nil || !validDNSName(host) {
return nil, errors.New("web push endpoint host is invalid")
}
if parsed.Path == "" || parsed.Path[0] != '/' {
return nil, errors.New("web push endpoint path is invalid")
}
return parsed, nil
}
func validateSubject(subject string) error {
if len(subject) < 8 || len(subject) > 512 || strings.ContainsAny(subject, "\r\n\t ") {
return errors.New("web push subject is invalid")
}
parsed, err := url.Parse(subject)
if err != nil || parsed.Fragment != "" || parsed.RawQuery != "" {
return errors.New("web push subject is invalid")
}
if parsed.Scheme == "mailto" && parsed.Opaque != "" && strings.Contains(parsed.Opaque, "@") {
return nil
}
if parsed.Scheme == "https" && parsed.Host != "" && parsed.User == nil {
return nil
}
return errors.New("web push subject must be a mailto address or HTTPS URL")
}
func validDNSName(host string) bool {
if host == "" || len(host) > 253 || strings.HasSuffix(host, ".") || strings.EqualFold(host, "localhost") {
return false
}
labels := strings.Split(host, ".")
if len(labels) < 2 {
return false
}
for _, label := range labels {
if label == "" || len(label) > 63 || label[0] == '-' || label[len(label)-1] == '-' {
return false
}
for _, character := range label {
if character > 127 || !(character == '-' || character >= '0' && character <= '9' || character >= 'A' && character <= 'Z' || character >= 'a' && character <= 'z') {
return false
}
}
}
return true
}
func safeClient(timeout time.Duration) *http.Client {
dialer := &net.Dialer{Timeout: timeout, KeepAlive: 30 * time.Second}
transport := &http.Transport{
Proxy: nil,
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
host, port, err := net.SplitHostPort(address)
if err != nil || port != "443" || !validDNSName(host) {
return nil, errors.New("web push dial target is invalid")
}
addresses, err := net.DefaultResolver.LookupIPAddr(ctx, host)
if err != nil || len(addresses) == 0 {
return nil, errors.New("resolve web push endpoint")
}
var last error
for _, candidate := range addresses {
if !publicIP(candidate.IP) {
return nil, errors.New("web push endpoint resolved to a non-public address")
}
connection, dialErr := dialer.DialContext(ctx, network, net.JoinHostPort(candidate.IP.String(), port))
if dialErr == nil {
return connection, nil
}
last = dialErr
}
if last != nil {
return nil, errors.New("connect to web push endpoint")
}
return nil, errors.New("web push endpoint has no usable address")
},
ForceAttemptHTTP2: true,
TLSHandshakeTimeout: timeout,
ResponseHeaderTimeout: timeout,
MaxIdleConns: 16,
MaxIdleConnsPerHost: 4,
IdleConnTimeout: 30 * time.Second,
}
return &http.Client{Transport: transport, Timeout: timeout, CheckRedirect: func(*http.Request, []*http.Request) error {
return errors.New("web push redirects are disabled")
}}
}
func publicIP(ip net.IP) bool {
if ip == nil || ip.IsUnspecified() || ip.IsLoopback() || ip.IsPrivate() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() || ip.IsMulticast() {
return false
}
address, ok := netip.AddrFromSlice(ip)
if !ok {
return false
}
address = address.Unmap()
for _, prefix := range deniedPushPrefixes {
if prefix.Contains(address) {
return false
}
}
return true
}
var deniedPushPrefixes = []netip.Prefix{
netip.MustParsePrefix("0.0.0.0/8"),
netip.MustParsePrefix("100.64.0.0/10"),
netip.MustParsePrefix("192.0.0.0/24"),
netip.MustParsePrefix("192.0.2.0/24"),
netip.MustParsePrefix("198.18.0.0/15"),
netip.MustParsePrefix("198.51.100.0/24"),
netip.MustParsePrefix("203.0.113.0/24"),
netip.MustParsePrefix("240.0.0.0/4"),
netip.MustParsePrefix("2001:db8::/32"),
}
func encrypt(payload []byte, subscription Subscription, random io.Reader) ([]byte, []byte, error) {
if len(payload) == 0 || len(payload) > 2048 || len(subscription.P256DH) != 65 || subscription.P256DH[0] != 4 || len(subscription.Auth) != 16 {
return nil, nil, errors.New("web push subscription keys are invalid")
}
serverPrivate, err := ecdh.P256().GenerateKey(random)
if err != nil {
return nil, nil, errors.New("generate web push content key")
}
salt := make([]byte, 16)
if _, err = io.ReadFull(random, salt); err != nil {
return nil, nil, errors.New("generate web push salt")
}
return encryptWithMaterial(payload, subscription, serverPrivate, salt)
}
func encryptWithMaterial(payload []byte, subscription Subscription, serverPrivate *ecdh.PrivateKey, salt []byte) ([]byte, []byte, error) {
if len(payload) == 0 || len(payload) > 2048 || len(subscription.P256DH) != 65 || subscription.P256DH[0] != 4 || len(subscription.Auth) != 16 || serverPrivate == nil || len(salt) != 16 {
return nil, nil, errors.New("web push subscription keys are invalid")
}
clientPublic, err := ecdh.P256().NewPublicKey(subscription.P256DH)
if err != nil {
return nil, nil, errors.New("web push subscription public key is invalid")
}
shared, err := serverPrivate.ECDH(clientPublic)
if err != nil {
return nil, nil, errors.New("derive web push content key")
}
serverPublic := serverPrivate.PublicKey().Bytes()
keyInfo := append([]byte("WebPush: info\x00"), subscription.P256DH...)
keyInfo = append(keyInfo, serverPublic...)
prkKey := hkdfExtract(subscription.Auth, shared)
ikm := hkdfExpand(prkKey, keyInfo, 32)
prk := hkdfExtract(salt, ikm)
contentKey := hkdfExpand(prk, []byte("Content-Encoding: aes128gcm\x00"), 16)
nonce := hkdfExpand(prk, []byte("Content-Encoding: nonce\x00"), 12)
block, err := aes.NewCipher(contentKey)
if err != nil {
return nil, nil, errors.New("create web push cipher")
}
aead, err := cipher.NewGCM(block)
if err != nil {
return nil, nil, errors.New("create web push authenticated cipher")
}
plaintext := append(append([]byte(nil), payload...), 2)
ciphertext := aead.Seal(nil, nonce, plaintext, nil)
recordSize := uint32(4096)
body := make([]byte, 0, 16+4+1+len(serverPublic)+len(ciphertext))
body = append(body, salt...)
record := make([]byte, 4)
binary.BigEndian.PutUint32(record, recordSize)
body = append(body, record...)
body = append(body, byte(len(serverPublic)))
body = append(body, serverPublic...)
body = append(body, ciphertext...)
return body, serverPublic, nil
}
func (s *Sender) vapid(endpoint *url.URL, now time.Time, random io.Reader) (string, error) {
header, _ := json.Marshal(struct {
Type string `json:"typ"`
Algorithm string `json:"alg"`
}{"JWT", "ES256"})
audience := endpoint.Scheme + "://" + strings.ToLower(endpoint.Hostname())
payload, _ := json.Marshal(struct {
Audience string `json:"aud"`
Expiry int64 `json:"exp"`
Subject string `json:"sub"`
}{audience, now.UTC().Add(12 * time.Hour).Unix(), s.subject})
unsigned := base64.RawURLEncoding.EncodeToString(header) + "." + base64.RawURLEncoding.EncodeToString(payload)
digest := sha256.Sum256([]byte(unsigned))
d := new(big.Int).SetBytes(s.private.Bytes())
curve := elliptic.P256()
x, y := curve.ScalarBaseMult(s.private.Bytes())
private := &ecdsa.PrivateKey{PublicKey: ecdsa.PublicKey{Curve: curve, X: x, Y: y}, D: d}
r, signatureS, err := ecdsa.Sign(random, private, digest[:])
if err != nil {
return "", errors.New("sign VAPID token")
}
signature := make([]byte, 64)
r.FillBytes(signature[:32])
signatureS.FillBytes(signature[32:])
return unsigned + "." + base64.RawURLEncoding.EncodeToString(signature), nil
}
func hkdfExtract(salt, input []byte) []byte {
mac := hmac.New(sha256.New, salt)
_, _ = mac.Write(input)
return mac.Sum(nil)
}
func hkdfExpand(key, info []byte, length int) []byte {
var output, previous []byte
for counter := byte(1); len(output) < length; counter++ {
mac := hmac.New(sha256.New, key)
_, _ = mac.Write(previous)
_, _ = mac.Write(info)
_, _ = mac.Write([]byte{counter})
previous = mac.Sum(nil)
output = append(output, previous...)
}
return output[:length]
}