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 areclientStarting→clientFirst→clientFinal→clientDoneServerConversation(server_conv.go): States areserverFirst→serverFinal→serverDone
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/randderivedKeys: Struct caching ClientKey, StoredKey, ServerKeyKeyFactors: Salt + iteration count, used as cache keyStoredCredentials: What servers must store for each userCredentialLookup: 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.