This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
NSS uses GYP + Ninja as its primary build system, driven by build.sh (or the mach wrapper):
./build.sh # debug build → ../dist/Debug/
./build.sh -o # optimized build → ../dist/Release/
./build.sh -c # clean + build
./mach build # equivalent wrapperCommon flags:
--asan/--msan/--ubsan— sanitizer builds--fuzz/--fuzz=tls— fuzzing builds--enable-fips— FIPS-140 mode--disable-tests— skip building test binaries-t <arch>— 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.
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 wrapperAvailable 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:
# 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./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 possibleNSS 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 is a Python 3 script that wraps common tasks:
./mach commands # list all available commands
./mach coverage ssl_gtests # source coverage report for a suite
./mach fuzz-coverage # coverage for fuzzing targets./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 --:
./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 subsetFlags: -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, the git⇆Mercurial bridge
Mozilla uses, so git can talk to the hg.mozilla.org servers:
pip install git-cinnabar # other install methods: see the project README
git cinnabar download # fetch the prebuilt helper binaryEither way, the working tree must be clean (uncommitted changes are refused) and
the nss-try push path must be configured.
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:
{
"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<N> line in the commit message:
git log -v -l 10 # git
hg log -l 10 # mercurialNever submit or update a Phabricator revision without explicit user approval.
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=<path>— specify a path explicitly