Hacking NSS: Difference between revisions

From Libreswan
Jump to navigation Jump to search
(fill in the rpm section)
(simplify build deps)
 
(17 intermediate revisions by the same user not shown)
Line 5: Line 5:
It includes both the error symbol name and the error message (the former is really useful when reading the code^D^D^D^D documentation when tracking down why the error was returned).
It includes both the error symbol name and the error message (the former is really useful when reading the code^D^D^D^D documentation when tracking down why the error was returned).


== Debugging NSS ==
== Building Libreswan using custom NSS RPMs ==


== Linking libreswan against a custom NSS build ==
=== Building NSS RPMs on the guest ===


== Building and Installing a Custom NSS RPMs ==
Here, we use the <tt>build</tt> machine (it has lots of memory and network access) and the 9p mounted directory <tt>/pool</tt> (aka <tt>$(KVM_POOLDIR)</tt>, but /testing and /root should also work).  Just remember that any changes to build aren't permanent, we'll get to that later.


Below are notes on building the latest Fedora RPM on the build machine.  
Prepare the machine (<tt>xmlto</tt> is hacked so that it doesn't try to preserve permissions when copying files within the 9p file system):
$ ./kvm sh build
build# dnf install -y fedpkg
build# dnf builddep -y nss
  build# sed -i -e 's/ -p / /' \
    /usr/share/xmlto/format/docbook/man \
    /usr/share/xmlto/format/docbook/html


=== Build Custom NSS RPM ===
Get the sources (drop <tt>--branch f32</tt> if trying to build rawhide):
build# cd /pool
build# cat /etc/fedora-release
Fedora release 32 (Thirty Two)
build# fedpkg clone --branch f32 --anonymous nss
build# cd nss


==== ... using <tt>fedpkg local</tt> and the build machine ====
hack <tt>nss.spec</tt>so that it has a unique suffix, and check result:
build# sed -i -e '/global baserelease/ s/$/lsw/' nss.spec
build# sed -i -e '/global nspr_release/ s/$/lsw/' nss.spec
build# fedpkg verrel
nss-3.63.0-1lsw.fc32
if <tt>fedpkg verrel</tt> fails more hacks may be required


log into the build machine:
hobble running tests during the build (optional):
$ ./kvm sh build
  build# sed -i -e 's/bcond_without tests/bcond_with tests/' nss.spec
install fedpkg (if not already):
  # dnf install -y fedpkg
pick somewhere to build (here I'm using /pool aka KVM_POOLDIR, but /testing and /root should all work) and download:
# cd /pool
# fedpkg clone --anonymous nss
# cd nss


In theory, all that's left is install the dependencies and kick off the build.  Unfortunately, not so easy:
finally build:
- disable tests (so --without tests isn't needed)
build# fedpkg local --without tests:
- fix %[expr] which seems to be new
or:
- tone down optimization
build# fedpkg prep --without tests
- screw around with compiler flags
build# fedpkg compile --short-circuit --without tests
- ignore xmlto's exit code
Here's a diff of what might need to be changed:


continuing, pull in the dependencies (something better?):
the RPMs are under <tt>x86_64</tt>.
# dnf builddep nss
and build:
# fedpkg local --without tests:
or, breaking it down:
# fedpkg prep --without tests
# fedpkg compile --short-circuit --without tests


==== ... using <tt>fedpkg mock</tt> and the Fedora host ====
=== Building NSS RPMs on the host ===


Hmm, something goes here!
Hmm, something goes here!
Line 48: Line 50:
  fedpkg mockbuild
  fedpkg mockbuild


=== Install Custom NSS RPMs ===
=== Installing the NSS RPMs (and making them stick) ===
 
The NSS RPMs can either be installed manually on <tt>build</tt> (which means they only stick around until <tt>./kvm uninstall</tt>), or they can be made more permenant by installing them into the base domain.
 
To install the RPMs on the base domain, add the following lines to Makefile.inc.local:
# Prepend the directory containing the RPMs, include /
KVM_NSS_RPMDIR = /pool/nss/x86_64/
KVM_NSPR_RPMDIR = /pool/nss/x86_64/
# Append the actual RPM version
KVM_NSS_VERSION = -3.71.0-1lsw.fc32.x86_64.rpm
KVM_NSPR_VERSION = -4.32.0-3lsw.fc32.x86_64.rpm
 
and then upgrade the base domain:
$ ./kvm upgrade
...
  Upgrading        : nss-util-3.63.0-1_lsw.fc32.x86_64                    1/20
...
 
finally, confirm:
$ ./kvm install
$ ./kvm sh east
east# rpm -q nss
nss-3.63.0-1_lsw.fc32.x86_64
 
If needed, the the customized domains can be reverted.  In Makefile.inc.local, comment out the lines added above, and then run:
$ ./kvm downgrade
$ ./kvm upgrade
...
  Installing      : nss-util-3.63.0-1.fc32.x86_64                      13/330
 
=== Distributing Custom NSS RPMs ===
 
Tar up both the .rpm and .srpm files into a single archive and make that available.  That way, who ever downloads the archive always gets the source code.
 
=== Building a Newer Version Of NSS ===


Typically this isn't needed as Fedora will back-port the latest release of NSS to all supported releases, and even when the release isn't up-to-date, the code hasn't changed much so patches still work.


However, here are some notes on the problems encountered when building <tt>fedpkg co rawhide</tt> on f32:
'''crypto-policies was too old'''
* the dependency can be broken by editing the <tt>Requires:</tt> line, however ...
* the test ikev2-x509-ecdsa-01 fails on east with:
: SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED: The certificate was signed using a signature algorithm that is disabled because it is not secure.
:* a fix is force the upgrade of crypto-policies and crypto-policies-scripts, however ...
* this breaks SSH, which breaks any test using SSH as an endpoint
== Building Libreswan using a scratch NSS+NSPR build ==
=== Building NSS+NSPR From Scratch ===
Prepare the machine:
$ ./kvm sh build
build# #
build# dnf install -y gcc-c++ perl-interpreter    # aka dnf builddep -y nss
build# dnf install -y hg python gyp ninja-build  # used by build scripts
build# sed -i -e 's/ -p / /' \
    /usr/share/xmlto/format/docbook/man \
    /usr/share/xmlto/format/docbook/html
* <tt>xmlto</tt> is hacked so that it doesn't try to preserve permissions when copying files within the 9p file system
: any build in <tt>/</tt> will be lost the next time the domain is rebuilt
* the dependencies can be automated by adding <tt>KVM_UPGRADE_PACKAGES += ...</tt> to <tt>Makefile.inc.local</tt>
* this doesn't solve the problem with xmlto
Download and build using [https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Building Building NSS] as a guide:
build# cd /source
build# hg clone https://hg.mozilla.org/projects/nspr
build# hg clone https://hg.mozilla.org/projects/nss
build# ./nss/build.sh -cc # clean without building
build# ./nss/build.sh --enable-libpkix --enable-fips
testing (for comparison, [https://treeherder.mozilla.org/jobs?repo=nss NSS build farm]):
build# HOST=localhost DOMSUF=localdomain USE_64=1 nss/tests/all.sh
however, of most interest is PKIX:
( cd nss/tests/cert/ ; USE_64=1 NSS_ENABLE_PKIX_VERIFY=1 DOMSUF=localdomain TESTDIR=/tmp/nss-test-results ./cert.sh )
* need to point TESTDIR at something local as <tt>cat >>EOF</tt> breaks with 9p
=== Linking with libreswan ===
finally, to link nss against the build, add the following to Makefile.inc.local (how correct is this?):
KVM_NSS_CFLAGS = -I/source/nspr/Debug/dist/include/nspr -I/source/dist/public/nss
KVM_NSS_LDFLAGS = -L/source/dist/Debug/lib/ -Wl,-rpath,/source/dist/Debug/lib/ -lnss3
and then build as per normal:
$ ./kvm install
and confirm it worked:
$ ./kvm sh build
build# ldd /usr/local/libexec/ipsec/pluto  # should show above path


=== Distribute Custom NSS RPMs ===
= Debugging NSS =


For legal reasons, tar up both the .rpm and .srpm files into a single archive and make that available - it forces whoever is using the RPMs to also download the sources.
NSS_ENABLE_PKIX_VERIFY=1 LD_LIBRARY_PATH=$(cd ../dist/Debug/lib && pwd) gdb --args $(cd ../dist/Debug/bin && pwd)/certutil -V -n PasswordCert -u S -d ../tests_results/security/build.1/dbpass
(gdb) break PKIX_Shutdown
(gdb) break cert_VerifyCertChainPkix

Latest revision as of 19:47, 5 November 2021

Using NSS from Pluto

use lsw_nss_error*() to report errors

It includes both the error symbol name and the error message (the former is really useful when reading the code^D^D^D^D documentation when tracking down why the error was returned).

Building Libreswan using custom NSS RPMs

Building NSS RPMs on the guest

Here, we use the build machine (it has lots of memory and network access) and the 9p mounted directory /pool (aka $(KVM_POOLDIR), but /testing and /root should also work). Just remember that any changes to build aren't permanent, we'll get to that later.

Prepare the machine (xmlto is hacked so that it doesn't try to preserve permissions when copying files within the 9p file system):

$ ./kvm sh build
build# dnf install -y fedpkg
build# dnf builddep -y nss
build# sed -i -e 's/ -p / /' \
   /usr/share/xmlto/format/docbook/man \
   /usr/share/xmlto/format/docbook/html

Get the sources (drop --branch f32 if trying to build rawhide):

build# cd /pool
build# cat /etc/fedora-release
Fedora release 32 (Thirty Two)
build# fedpkg clone --branch f32 --anonymous nss
build# cd nss

hack nss.specso that it has a unique suffix, and check result:

build# sed -i -e '/global baserelease/ s/$/lsw/' nss.spec
build# sed -i -e '/global nspr_release/ s/$/lsw/' nss.spec
build# fedpkg verrel
nss-3.63.0-1lsw.fc32

if fedpkg verrel fails more hacks may be required

hobble running tests during the build (optional):

build# sed -i -e 's/bcond_without tests/bcond_with tests/' nss.spec

finally build:

build# fedpkg local --without tests:

or:

build# fedpkg prep --without tests
build# fedpkg compile --short-circuit --without tests

the RPMs are under x86_64.

Building NSS RPMs on the host

Hmm, something goes here!

fedpkg mock-config
fedpkg mockbuild

Installing the NSS RPMs (and making them stick)

The NSS RPMs can either be installed manually on build (which means they only stick around until ./kvm uninstall), or they can be made more permenant by installing them into the base domain.

To install the RPMs on the base domain, add the following lines to Makefile.inc.local:

# Prepend the directory containing the RPMs, include /
KVM_NSS_RPMDIR = /pool/nss/x86_64/
KVM_NSPR_RPMDIR = /pool/nss/x86_64/
# Append the actual RPM version
KVM_NSS_VERSION = -3.71.0-1lsw.fc32.x86_64.rpm
KVM_NSPR_VERSION = -4.32.0-3lsw.fc32.x86_64.rpm

and then upgrade the base domain:

$ ./kvm upgrade
...
 Upgrading        : nss-util-3.63.0-1_lsw.fc32.x86_64                     1/20 
...

finally, confirm:

$ ./kvm install
$ ./kvm sh east
east# rpm -q nss
nss-3.63.0-1_lsw.fc32.x86_64

If needed, the the customized domains can be reverted. In Makefile.inc.local, comment out the lines added above, and then run:

$ ./kvm downgrade
$ ./kvm upgrade
...
 Installing       : nss-util-3.63.0-1.fc32.x86_64                       13/330 

Distributing Custom NSS RPMs

Tar up both the .rpm and .srpm files into a single archive and make that available. That way, who ever downloads the archive always gets the source code.

Building a Newer Version Of NSS

Typically this isn't needed as Fedora will back-port the latest release of NSS to all supported releases, and even when the release isn't up-to-date, the code hasn't changed much so patches still work.

However, here are some notes on the problems encountered when building fedpkg co rawhide on f32:

crypto-policies was too old

  • the dependency can be broken by editing the Requires: line, however ...
  • the test ikev2-x509-ecdsa-01 fails on east with:
SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED: The certificate was signed using a signature algorithm that is disabled because it is not secure.
  • a fix is force the upgrade of crypto-policies and crypto-policies-scripts, however ...
  • this breaks SSH, which breaks any test using SSH as an endpoint

Building Libreswan using a scratch NSS+NSPR build

Building NSS+NSPR From Scratch

Prepare the machine:

$ ./kvm sh build
build# #
build# dnf install -y gcc-c++ perl-interpreter    # aka dnf builddep -y nss
build# dnf install -y hg python gyp ninja-build   # used by build scripts
build# sed -i -e 's/ -p / /' \
   /usr/share/xmlto/format/docbook/man \
   /usr/share/xmlto/format/docbook/html
  • xmlto is hacked so that it doesn't try to preserve permissions when copying files within the 9p file system
any build in / will be lost the next time the domain is rebuilt
  • the dependencies can be automated by adding KVM_UPGRADE_PACKAGES += ... to Makefile.inc.local
  • this doesn't solve the problem with xmlto

Download and build using Building NSS as a guide:

build# cd /source
build# hg clone https://hg.mozilla.org/projects/nspr
build# hg clone https://hg.mozilla.org/projects/nss
build# ./nss/build.sh -cc # clean without building
build# ./nss/build.sh --enable-libpkix --enable-fips

testing (for comparison, NSS build farm):

build# HOST=localhost DOMSUF=localdomain USE_64=1 nss/tests/all.sh

however, of most interest is PKIX:

( cd nss/tests/cert/ ; USE_64=1 NSS_ENABLE_PKIX_VERIFY=1 DOMSUF=localdomain TESTDIR=/tmp/nss-test-results ./cert.sh )
  • need to point TESTDIR at something local as cat >>EOF breaks with 9p

Linking with libreswan

finally, to link nss against the build, add the following to Makefile.inc.local (how correct is this?):

KVM_NSS_CFLAGS = -I/source/nspr/Debug/dist/include/nspr -I/source/dist/public/nss
KVM_NSS_LDFLAGS = -L/source/dist/Debug/lib/ -Wl,-rpath,/source/dist/Debug/lib/ -lnss3

and then build as per normal:

$ ./kvm install

and confirm it worked:

$ ./kvm sh build
build# ldd /usr/local/libexec/ipsec/pluto  # should show above path

Debugging NSS

NSS_ENABLE_PKIX_VERIFY=1 LD_LIBRARY_PATH=$(cd ../dist/Debug/lib && pwd) gdb --args $(cd ../dist/Debug/bin && pwd)/certutil -V -n PasswordCert -u S -d ../tests_results/security/build.1/dbpass
(gdb) break PKIX_Shutdown
(gdb) break cert_VerifyCertChainPkix