Reproducible Builds of NSS certutil via Cross-Compiling with rbm
In a previous post where I introduced
tlsrestrict_nss_tool, I mentioned that NSS’s
certutil doesn’t have official binaries for Windows, and that “At some point, we’ll probably need to start cross-compiling NSS ourselves, although I admit I’m not sure I’m going to enjoy that.” Well, we’ve reached that point, and it was an interesting adventure.
Initially, I looked at the NSS build docs themselves, and was rather annoyed to find that there’s no documentation about how to cross-compile NSS. To make matters worse, the only results I could find by Startpaging were people saying that they couldn’t figure out how to cross-compile NSS (including some well-known software projects’ developers).
However, it just so happens that there’s a very high-profile free software project whom I was certain is definitely cross-compiling NSS: The Tor Project. Tor cross-compiles Firefox (including NSS) as part of their Tor Browser build scripts, so it seemed near-certain that their build scripts could be modified to build
certutil. However, Tor’s build scripts are rather nonstandard, since they build everything with rbm. rbm is a container-based build system that’s superficially similar to the Gitian build system that Bitcoin Core and Namecoin Core use (indeed, The Tor Project used to use Gitian before they migrated to rbm). I’ve been intending to get my feet wet with rbm for quite a while now, so this seemed like a great excuse to play with rbm a bit.
First off, I wanted to build Firefox in rbm without any changes. This was actually quite easy – The Tor Project’s documentation is quite good, and I didn’t run into any snags (besides the issue that I initially assigned too little storage to the VM where I was doing this – The Tor Project should probably document the expected storage requirements). The build command I used was:
./rbm/rbm build firefox --target nightly --target torbrowser-windows-i686
Next, I looked at Tor’s Firefox build script… and I was delighted to see that Tor is already building
certutil. In fact, you can download
certutil binaries from The Tor Project’s download server right now! (You want the
mar-tools-*.zip packages.) Except… their build script discards the
certutil binaries for all non-GNU/Linux targets. How sad.
Modifying the build script to also output
certutil.exe for Windows was reasonably straightforward – rbm even worked without erroring on the first try. I did, however, need to try for a few iterations to make sure that I was outputting all of the needed
.dll files. However, once I had all the required
.dll files, a rather odd symptom occurred when I tested it on a Windows machine. When I ran
certutil.exe from a command prompt, it would immediately exit without printing anything. Stranger, when I double-clicked
certutil.exe in Windows Explorer, it didn’t even pop up with a command prompt window before it exited. In addition, I noticed that if I passed command line arguments to
certutil.exe telling it to create a new database, it actually did create the database – but it still didn’t display any output.
This seemed to indicate that something was wrong not with
certutil.exe’s actual functionality, but with its PE metadata: Windows was probably treating it as a GUI application rather than a console application. Checking the PE metadata confirmed this: Tor’s build scripts were producing a
certutil.exe whose PE metadata was marking it as a GUI application. Some more quick searching revealed a StackOverflow post providing a short Python2 script that could edit that part of the PE metadata. I ran that script against
certutil.exe… and now
certutil.exe works properly. Yay!
The lack of
certutil.exe binaries was one of the major blockers for releasing negative TLS certificate overrides for Firefox on Windows. Now that this barrier is behind us, I can get around to testing
tlsrestrict_nss_tool on Windows, and hopefully do a release (with NSIS installer support). And as a side bonus,
certutil.exe builds reproducibly, and I’ve now gotten some experience with rbm (meaning that reproducible builds for ncdns and our other Go software may be coming soon).
This work was funded by NLnet Foundation’s Internet Hardening Fund.