Files
br c8df9d7651 erste module drin.
zwischenstand: Architektur aktualisiert, TOFU implementiert,
2026-10-01 22:22:13 +02:00

88 lines
2.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package auth
import (
"bytes"
"crypto/ed25519"
"errors"
"io"
"net/http"
"strings"
"testing"
)
type ed25519PublicKey = ed25519.PublicKey
func TestSign_SetsHeaders(t *testing.T) {
priv, _ := GenerateKey()
s := &Signer{Key: priv}
r, _ := http.NewRequest(http.MethodGet, "https://ingress.example:8443/api/v1/stream", nil)
if err := s.Sign(r); err != nil {
t.Fatalf("Sign: %v", err)
}
if got := r.Header.Get(HeaderKey); got != EncodePublicKey(priv.Public().(ed25519.PublicKey)) {
t.Errorf("%s = %q", HeaderKey, got)
}
for _, h := range []string{HeaderTimestamp, HeaderNonce, HeaderSignature} {
if r.Header.Get(h) == "" {
t.Errorf("Header %s fehlt", h)
}
}
}
func TestSign_FreshNonceEachTime(t *testing.T) {
priv, _ := GenerateKey()
s := &Signer{Key: priv}
seen := map[string]bool{}
for range 100 {
r, _ := http.NewRequest(http.MethodGet, "https://h/x", nil)
if err := s.Sign(r); err != nil {
t.Fatal(err)
}
n := r.Header.Get(HeaderNonce)
if seen[n] {
t.Fatalf("Nonce %q doppelt", n)
}
seen[n] = true
}
}
func TestSign_PreservesBody(t *testing.T) {
priv, _ := GenerateKey()
r, _ := http.NewRequest(http.MethodPost, "https://h/api/v1/state", strings.NewReader(`{"a":1}`))
if err := (&Signer{Key: priv}).Sign(r); err != nil {
t.Fatal(err)
}
body, _ := io.ReadAll(r.Body)
if string(body) != `{"a":1}` {
t.Errorf("Body nach Sign = %q", body)
}
if r.GetBody == nil {
t.Fatal("GetBody fehlt – Redirects/Retries könnten den Body nicht erneut senden")
}
again, _ := r.GetBody()
body, _ = io.ReadAll(again)
if !bytes.Equal(body, []byte(`{"a":1}`)) {
t.Errorf("GetBody liefert %q", body)
}
}
// Kein Signieren für Klartext-Verbindungen: Signatur und Body dürfen nie
// unverschlüsselt über die Leitung gehen.
func TestSign_RefusesPlainHTTP(t *testing.T) {
priv, _ := GenerateKey()
r, _ := http.NewRequest(http.MethodGet, "http://ingress.example:8080/api/v1/stream", nil)
if err := (&Signer{Key: priv}).Sign(r); !errors.Is(err, ErrInsecureTransport) {
t.Errorf("erwartet ErrInsecureTransport, bekommen %v", err)
}
if r.Header.Get(HeaderSignature) != "" {
t.Error("Signatur trotz Klartext gesetzt")
}
}
func TestSign_NoKey(t *testing.T) {
r, _ := http.NewRequest(http.MethodGet, "https://h/x", nil)
if err := (&Signer{}).Sign(r); !errors.Is(err, ErrInvalidKey) {
t.Errorf("erwartet ErrInvalidKey, bekommen %v", err)
}
}