# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Build NSS uses GYP + Ninja as its primary build system, driven by `build.sh` (or the `mach` wrapper): ```sh ./build.sh # debug build → ../dist/Debug/ ./build.sh -o # optimized build → ../dist/Release/ ./build.sh -c # clean + build ./mach build # equivalent wrapper ``` Common flags: - `--asan` / `--msan` / `--ubsan` — sanitizer builds - `--fuzz` / `--fuzz=tls` — fuzzing builds - `--enable-fips` — FIPS-140 mode - `--disable-tests` — skip building test binaries - `-t ` — cross-compile (x64, ia32, aarch64, …) Output lands in `out/[Debug|Release]/` (build artifacts) and `../dist/[Debug|Release]/` (headers, libs, binaries). A legacy Make-based build (`make nss_build_all`) also exists via `coreconf/` but GYP is preferred for new work. ## Tests ```sh cd tests && ./all.sh # full test suite NSS_TESTS=ssl_gtests ./all.sh # single suite NSS_TESTS=ssl_gtests NSS_CYCLES=standard ./all.sh # skip stress cycles ./mach tests ssl_gtests # mach wrapper ``` Available suites: `cipher`, `ssl`, `ssl_gtests`, `gtests`, `cert`, `smime`, `fips`, `ec`, `bogo`, `interop`, `policy`, and others. See `tests/all.sh` for the full list. GTest binaries require a certificate database. Helper scripts create one and then invoke the binary: ```sh # SSL gtests ./tests/ssl_gtests/ssl_gtest_db.sh ./ssl_gtest_certdb ../dist/Debug/bin/certutil ../dist/Debug/bin/ssl_gtests -d ./ssl_gtest_certdb # Other gtests ./tests/gtests/gtest_db.sh ./gtest_certdb ../dist/Debug/bin/certutil ../dist/Debug/bin/pkcs11testmodule_gtest -d ./gtest_certdb # example ``` ## Code formatting and linting ```sh ./mach clang-format # format changed files ./mach clang-format path/to/file.c # format specific file ./mach clang-tidy # static analysis ./mach clang-tidy --fix # auto-fix where possible ``` ## Architecture NSS is a layered cryptographic library. The dependency flows roughly bottom-up: **`lib/freebl/`** — standalone cryptographic primitives (ciphers, hashes, RNG, EC). No NSS dependencies; can be linked independently. Hardware acceleration (AES-NI, CLMUL, AVX, etc.) is selected at this layer. **`lib/softoken/`** — software PKCS#11 token built on freebl. This is the default cryptographic "device" NSS uses. Legacy database support is in `lib/softoken/legacydb/`. **`lib/pk11wrap/`** — PKCS#11 abstraction layer. All cryptographic operations above freebl go through here, allowing hardware tokens and HSMs to be swapped in transparently. **`lib/certdb/` + `lib/certhigh/`** — certificate database (SQLite via `lib/sqlite/`, or legacy DBM via `lib/dbm/`) and high-level certificate operations. **`lib/cryptohi/`** — high-level signing, verification, and hashing APIs layered over pk11wrap. **`lib/ssl/`** — TLS 1.2, TLS 1.3, and DTLS implementation. Depends on cryptohi, certdb, and pk11wrap. **`lib/nss/`** — top-level initialization and the public NSS API surface. **`lib/smime/`, `lib/pkcs7/`, `lib/pkcs12/`** — higher-level protocol/format support built on the certificate and crypto layers. **`lib/mozpkix/`** — Mozilla's standalone C++ PKIX certificate chain validation library (also used by Firefox directly). **`lib/ckfw/`** — Cryptoki Framework: infrastructure for building PKCS#11 modules. The `cmd/` directory contains command-line tools (`certutil`, `modutil`, `bltest`, etc.) that exercise the public API and are also used by the test suite. GTests live in `gtests/` (unit tests per module) and `tests/ssl_gtests/` (SSL integration gtests). Shell-based integration tests are in `tests/`. ## mach `./mach` is a Python 3 script that wraps common tasks: ```sh ./mach commands # list all available commands ./mach coverage ssl_gtests # source coverage report for a suite ./mach fuzz-coverage # coverage for fuzzing targets ``` ## Try server `./mach try` pushes the current changeset to the `nss-try` Taskcluster branch to validate a change against CI before landing. Run it with no arguments to print the current set of valid platform/test/tool tokens; pass try syntax after `--`: ```sh ./mach try # print help + valid tokens ./mach try -- -b do -p all -u all -t all # everything: both build types, all platforms/tests/tools ./mach try -- -p linux-x64 -u ssl,gtest # a targeted subset ``` Flags: `-b` build type (`d`/`o`/`do`), `-p` platforms, `-u` unit tests, `-t` tools, `-e all` extra builds. See `doc/src/try.md` for the full flag reference and how the try syntax is implemented. **Working from a git checkout — install git-cinnabar:** NSS's canonical repository is Mercurial, and its `mach try` drives `hg` directly (`hg status`, `hg push nss-try`, `hg strip`, …) — unlike Firefox's `mach try`, which supports git/git-cinnabar natively. If you work from a git checkout, install [git-cinnabar](https://github.com/glandium/git-cinnabar), the git⇆Mercurial bridge Mozilla uses, so git can talk to the `hg.mozilla.org` servers: ```sh pip install git-cinnabar # other install methods: see the project README git cinnabar download # fetch the prebuilt helper binary ``` Either way, the working tree must be clean (uncommitted changes are refused) and the `nss-try` push path must be configured. ## Bugzilla and Phabricator NSS tracks bugs in Bugzilla and uses Phabricator for code review. The `moz` MCP server gives direct access to both. The server is defined in `.mcp.json`; to enable it, create `.claude/settings.local.json` if it doesn't exist: ```json { "enableAllProjectMcpServers": true, "enabledMcpjsonServers": ["moz"] } ``` - `@moz:bugzilla://bug/{bug_id}` — retrieve a bug and its comments - `@moz:phabricator://revision/D{revision_id}` — retrieve a Phabricator revision and its review comments To find the Phabricator revision ID for a local commit, look for a `Differential Revision: https://phabricator.services.mozilla.com/D` line in the commit message: ```sh git log -v -l 10 # git hg log -l 10 # mercurial ``` Never submit or update a Phabricator revision without explicit user approval. ## NSPR NSS depends on NSPR (Netscape Portable Runtime) for OS abstraction. By default the build looks for it at `../nspr/`. Alternatives: - `--system-nspr` — use the system-installed NSPR - `--with-nspr=` — specify a path explicitly