|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +nss-rs provides a safe, idiomatic Rust interface to Mozilla's NSS (Network Security Services) cryptographic library. It originated from neqo-crypto in mozilla-central and is primarily for use in Gecko, though it supports standalone use. API stability is NOT a goal. |
| 8 | + |
| 9 | +## Build Prerequisites |
| 10 | + |
| 11 | +- NSS libraries must be available. The build system resolves NSS in this order: |
| 12 | + 1. `NSS_DIR` env var (absolute path to NSS source; will build NSS from source unless `NSS_PREBUILT=1`) |
| 13 | + 2. `pkg-config` (uses system-installed NSS) |
| 14 | + 3. Falls back to cloning NSS/NSPR from hg.mozilla.org and building from source |
| 15 | +- Minimum NSS version: defined in `min_version.txt` (currently 3.121) |
| 16 | +- Rust edition 2024, MSRV 1.90.0 |
| 17 | +- On macOS, build.rs auto-detects Xcode's libclang. On Windows, set `LIBCLANG_PATH` or `MOZBUILD_STATE_PATH`. |
| 18 | + |
| 19 | +## Common Commands |
| 20 | + |
| 21 | +```bash |
| 22 | +# Build |
| 23 | +cargo build |
| 24 | + |
| 25 | +# Run all tests |
| 26 | +cargo test |
| 27 | + |
| 28 | +# Run a single test |
| 29 | +cargo test <test_name> |
| 30 | + |
| 31 | +# Clippy (CI runs with -D warnings and feature powerset) |
| 32 | +cargo clippy --workspace --all-targets -- -D warnings |
| 33 | +cargo hack clippy --feature-powerset --no-dev-deps --exclude-features gecko -- -D warnings |
| 34 | + |
| 35 | +# Format |
| 36 | +cargo fmt |
| 37 | +cargo fmt --check |
| 38 | + |
| 39 | +# Doc check (matches CI) |
| 40 | +RUSTDOCFLAGS="--deny rustdoc::broken_intra_doc_links --deny warnings" cargo doc --workspace --no-deps --document-private-items |
| 41 | + |
| 42 | +# Dependency check |
| 43 | +cargo machete |
| 44 | +``` |
| 45 | + |
| 46 | +## Architecture |
| 47 | + |
| 48 | +**Single crate** (`nss-rs`) with a `test-fixture` helper crate for tests. |
| 49 | + |
| 50 | +### Build System (`build.rs`) |
| 51 | +- Uses `bindgen` to generate Rust FFI bindings from C headers in `bindings/` |
| 52 | +- Binding configuration is in `bindings/bindings.toml` — each section maps to a `.h` file and specifies which types/functions/variables to expose |
| 53 | +- Handles three modes: Gecko (`gecko` feature + mozbuild), standalone with NSS_DIR, or pkg-config |
| 54 | +- Debug builds link statically; release builds link dynamically |
| 55 | + |
| 56 | +### Key Source Modules |
| 57 | +- `lib.rs` — NSS initialization (`init()`, `init_db()`), re-exports public API |
| 58 | +- `agent.rs`, `agentio.rs` — TLS agent (client/server) implementation |
| 59 | +- `aead.rs`, `hkdf.rs`, `hp.rs`, `hmac.rs`, `hash.rs` — Cryptographic primitives |
| 60 | +- `p11.rs`, `pk11_utils.rs` — PKCS#11 key management wrappers |
| 61 | +- `err.rs`, `result.rs` — Error types and `Res<T>` alias |
| 62 | +- `ssl.rs`, `secrets.rs` — SSL options and secret management |
| 63 | +- `ech.rs` — Encrypted Client Hello support |
| 64 | +- `selfencrypt.rs` — Self-encryption utilities |
| 65 | +- `ext.rs` — TLS extension handling |
| 66 | +- `time.rs` — Time abstraction (Instant::now() is denied project-wide) |
| 67 | + |
| 68 | +### FFI Pattern |
| 69 | +Generated bindings are organized into internal modules (`nss_prelude`, `nss`, `ssl`, etc.) via `include!(concat!(env!("OUT_DIR"), "/<name>.rs"))`. Public types like `SECItem`, `SECStatus` are re-exported from `nss_prelude`. |
| 70 | + |
| 71 | +### Features |
| 72 | +- `gecko` — Build within Gecko/mozilla-central (uses mozbuild) |
| 73 | +- `disable-encryption` / `disable-random` — Testing features |
| 74 | +- `deny-warnings` — Treat warnings as errors |
| 75 | +- `bench` — Benchmark support |
| 76 | + |
| 77 | +## Lint Configuration |
| 78 | + |
| 79 | +Extensive clippy lints are configured in `Cargo.toml`. Key policies: |
| 80 | +- `clippy::unwrap_used` and `clippy::get_unwrap` are **warn** — prefer `expect()` or proper error handling |
| 81 | +- `clippy::pedantic` and `clippy::nursery` lint groups are enabled |
| 82 | +- `Instant::now()` usage is denied — use the `time` module abstraction instead |
| 83 | + |
| 84 | +## Test Fixture |
| 85 | + |
| 86 | +Tests use `test-fixture` crate which initializes NSS with a test database (`test-fixture/db/`). Call `fixture_init()` or use helpers like `now()` and `anti_replay()` that auto-initialize. |
0 commit comments