Files
web/server/vendor/github.com/xdg-go/scram/CLAUDE.md

3.3 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

This is a Go library implementing SCRAM (Salted Challenge Response Authentication Mechanism) per RFC-5802 and RFC-7677. It provides both client and server implementations supporting SHA-1, SHA-256, and SHA-512 hash functions.

Development Commands

Run tests:

go test ./...

Run tests with race detection (CI configuration):

go test -race ./...

Build (module-only, no binaries):

go build ./...

Run single test:

go test -run TestName ./...

Architecture

Core Components

Hash factory pattern: The HashGeneratorFcn type (scram.go:23) is the entry point for creating clients and servers. Package-level variables SHA1, SHA256, SHA512 provide pre-configured hash functions. All client/server creation flows through these hash generators.

Client (client.go): Holds authentication configuration for a username/password/authzID tuple. Maintains a cache of derived keys (PBKDF2 results) indexed by KeyFactors (salt + iteration count). Thread-safe via RWMutex. Creates ClientConversation instances for individual auth attempts.

Server (server.go): Holds credential lookup callback and nonce generator. Creates ServerConversation instances for individual auth attempts.

Conversations: State machines implementing the SCRAM protocol exchange:

  • ClientConversation (client_conv.go): States are clientStartingclientFirstclientFinalclientDone
  • ServerConversation (server_conv.go): States are serverFirstserverFinalserverDone

Both use a Step(string) (string, error) method to advance through protocol stages.

Message parsing (parse.go): Parses SCRAM protocol messages into structs. Separate parsers for client-first, server-first, client-final, and server-final messages.

Shared utilities (common.go):

  • NonceGeneratorFcn: Default uses base64-encoded 24 bytes from crypto/rand
  • derivedKeys: Struct caching ClientKey, StoredKey, ServerKey
  • KeyFactors: Salt + iteration count, used as cache key
  • StoredCredentials: What servers must store for each user
  • CredentialLookup: Callback type servers use to retrieve stored credentials

Key Design Patterns

Dependency injection: Server requires a CredentialLookup callback, making storage mechanism pluggable.

Caching: Client caches expensive PBKDF2 results in a map keyed by KeyFactors. This optimizes reconnection scenarios where salt/iteration count remain constant.

Factory methods: Hash generators provide .NewClient() and .NewServer() methods that handle SASLprep normalization. Alternative .NewClientUnprepped() exists for custom normalization.

Configuration via chaining: Both Client and Server support .WithNonceGenerator() for custom nonce generation (primarily for testing).

Security Considerations

  • Default minimum PBKDF2 iterations: 4096 (client.go:45)
  • All string comparisons use hmac.Equal() for constant-time comparison
  • SASLprep normalization applied by default via xdg-go/stringprep dependency
  • Nonce generation uses crypto/rand

Testing

Tests include conversation state machine tests (client_conv_test.go, server_conv_test.go), integration tests, and examples (doc_test.go). Test data in testdata_test.go.