The remaining P3 tail is done: - §13.5: three TOTP codes for the shared RFC secret computed by an independent implementation (Python stdlib, anchored to RFC 4226 App D counter 0 = 755224) at recorded wall-clock Unix seconds, pinned in platform/auth TestInteropCapturePythonTOTP — the Go code must produce identical codes at the same instants and VerifyWindow(0) must accept each at its capture time (cross-implementation agreement). - §14.4: a full WebAuthn ceremony through real Chrome (navigator.credentials with a CDP virtual authenticator: ctap2/internal, resident key, UV, ES256) against a live go-auth instance — registration + passwordless login both completed via the RP handlers. The raw browser-produced blobs (clientDataJSON, attestationObject, authenticatorData, signature) are stored verbatim as a golden fixture and replayed by TestInteropCaptureChromeRegistration/Assertion: the parser must decode the real CBOR/COSE/authenticator-data, and the real ECDSA signature must verify over SHA-256(authData ‖ clientDataJSON) with the parsed key. Plan doc §13.5/§14.4 updated with the recorded values; P3 row marked complete. Both new suites green. 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
40 lines
1.2 KiB
Go
40 lines
1.2 KiB
Go
package auth
|
|
|
|
// §13.5 interop capture (2026-09-01): three codes computed by an independent
|
|
// Python-stdlib TOTP implementation at recorded wall-clock Unix seconds, for
|
|
// the shared RFC secret. Cross-implementation agreement — the Python code
|
|
// also reproduced RFC 4226 App D counter 0 = 755224, anchoring it to the
|
|
// same algorithm. The Go implementation must produce identical codes at the
|
|
// same instants, and VerifyWindow(0) must accept each at its capture time.
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestInteropCapturePythonTOTP(t *testing.T) {
|
|
captures := []struct {
|
|
unix int64
|
|
code string
|
|
}{
|
|
{1788266430, "398267"},
|
|
{1788266460, "060110"},
|
|
{1788266490, "612712"},
|
|
}
|
|
for _, c := range captures {
|
|
at := time.Unix(c.unix, 0)
|
|
step := Counter(at, 30*time.Second)
|
|
got, err := HOTP(totpSecret, step, 6)
|
|
if err != nil {
|
|
t.Fatalf("HOTP t=%d: %v", c.unix, err)
|
|
}
|
|
if got != c.code {
|
|
t.Errorf("t=%d: Go produced %s, independent impl produced %s", c.unix, got, c.code)
|
|
}
|
|
// window=0: the code must verify at exactly its capture instant.
|
|
if _, err := VerifyWindow(0, totpSecret, c.code, at); err != nil {
|
|
t.Errorf("t=%d: capture code %s failed window-0 verify: %v", c.unix, c.code, err)
|
|
}
|
|
}
|
|
}
|