76 lines
3.3 KiB
Markdown
76 lines
3.3 KiB
Markdown
# 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:**
|
|
```bash
|
|
go test ./...
|
|
```
|
|
|
|
**Run tests with race detection (CI configuration):**
|
|
```bash
|
|
go test -race ./...
|
|
```
|
|
|
|
**Build (module-only, no binaries):**
|
|
```bash
|
|
go build ./...
|
|
```
|
|
|
|
**Run single test:**
|
|
```bash
|
|
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 `clientStarting` → `clientFirst` → `clientFinal` → `clientDone`
|
|
- `ServerConversation` (server_conv.go): States are `serverFirst` → `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/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.
|