SPB Git forge
15commits 1branches 0releases
29.7 MBsize
maindefault branch
10 days agolast push
TypeScript 36.3% Python 31.8% Go 18% JavaScript 9.8% Shell 1.9% SQL 1.4% CSS 0.5%
3.2 KB · 93 lines go
Raw Blame History
1package signer23import (4	"net/http"5	"net/url"6	"strings"7	"testing"8)910// Test vectors — kept in sync with README.md ("How signing works") so the Python server can cross-check.11//12//	key        = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f  (32 bytes)13//	timestamp  = 1789189804                                                        (2026-09-12T05:10:04Z)14//	POST /ingest/v1/batch  body = {"probe_id":"ca-qc-01","agent_version":"0.1.0","measurements":[]}15//	GET  /ingest/v1/config body = ""16const (17	vecKey  = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"18	vecTS   = int64(1789189804)19	vecBody = `{"probe_id":"ca-qc-01","agent_version":"0.1.0","measurements":[]}`2021	// sha256 of vecBody / of the empty string.22	vecBodyHash  = "9fd6962cedcf4a7aedb13c38f7f63137fdbbbf3703b447ebd761234981847c65"23	vecEmptyHash = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"2425	// Expected signatures — computed independently with Python (hmac + hashlib) before this package existed.26	vecPostSig = "111075ee8d4c20723598c8f75d5ad89433f0385ff965f123302d2b9411280723"27	vecGetSig  = "3798599e7f1bed2dab170d2aacf5f5288ec7cc591a64bd37285d3ea3c3450a8b"28)2930func TestBodyHash(t *testing.T) {31	if got := BodyHash([]byte(vecBody)); got != vecBodyHash {32		t.Fatalf("body hash = %s, want %s", got, vecBodyHash)33	}34	if got := BodyHash(nil); got != vecEmptyHash {35		t.Fatalf("empty hash = %s, want %s", got, vecEmptyHash)36	}37}3839func TestCanonicalForm(t *testing.T) {40	c := Canonical("GET", "/ingest/v1/config", vecTS, nil)41	want := "GET\n/ingest/v1/config\n1789189804\n" + vecEmptyHash42	if c != want {43		t.Fatalf("canonical mismatch:\n got %q\nwant %q", c, want)44	}45}4647func TestVectors(t *testing.T) {48	s, err := New("ca-qc-01", vecKey)49	if err != nil {50		t.Fatal(err)51	}52	if got := s.Sign("POST", "/ingest/v1/batch", vecTS, []byte(vecBody)); got != vecPostSig {53		t.Errorf("POST signature = %s, want %s", got, vecPostSig)54	}55	if got := s.Sign("GET", "/ingest/v1/config", vecTS, nil); got != vecGetSig {56		t.Errorf("GET signature = %s, want %s", got, vecGetSig)57	}58}5960func TestApplyIgnoresQueryString(t *testing.T) {61	s, _ := New("ca-qc-01", vecKey)62	u, _ := url.Parse("https://www.internetpressure.io/ingest/v1/config?x=1")63	req, _ := http.NewRequest("GET", u.String(), nil)64	s.Apply(req, vecTS, nil)65	if req.Header.Get(HeaderProbe) != "ca-qc-01" || req.Header.Get(HeaderTimestamp) != "1789189804" {66		t.Fatalf("bad headers: %v", req.Header)67	}68	if req.Header.Get(HeaderSignature) != vecGetSig {69		t.Fatalf("signature with query string should equal the path-only signature")70	}71	if !s.Verify("GET", "/ingest/v1/config", vecTS, nil, req.Header.Get(HeaderSignature)) {72		t.Fatal("verify failed")73	}74	if s.Verify("GET", "/ingest/v1/config", vecTS+1, nil, req.Header.Get(HeaderSignature)) {75		t.Fatal("verify should fail with a different timestamp")76	}77}7879func TestNewRejectsBadKeys(t *testing.T) {80	if _, err := New("p", "zz"); err == nil {81		t.Fatal("non-hex key accepted")82	}83	if _, err := New("p", "0011"); err == nil {84		t.Fatal("short key accepted")85	}86	if _, err := New("", vecKey); err == nil {87		t.Fatal("empty probe id accepted")88	}89	if _, err := New("p", strings.Repeat("ab", 32)); err != nil {90		t.Fatal(err)91	}92}93