Add support for linking NSS statically on macOS

This is an attmept to link with NSS statically on macOS (both Intel and
 Apple M1).

 Statically linking with NSS is a total mess and completely
undocumented. There are 20+ .a files to link with, and their linking
order matters. The main reference for this commit is a Mozilla Rust code
responsible for statically linking NSS:

    b2690fd2e4/components/support/rc_crypto/nss/nss_b    uild_common/src/lib.rs#L94

Unfortunately, even with that in hand, a lot of hacking is needed to
make it all work.
This commit is contained in:
lwthiker
2022-04-22 19:57:46 +03:00
parent 3f1c350132
commit 59209c19c7
6 changed files with 90 additions and 15 deletions

View File

@@ -82,11 +82,7 @@ ARG NSS_URL=https://ftp.mozilla.org/pub/security/nss/releases/NSS_3_75_RTM/src/n
RUN curl -o ${NSS_VERSION}.tar.gz ${NSS_URL} RUN curl -o ${NSS_VERSION}.tar.gz ${NSS_URL}
RUN tar xf ${NSS_VERSION}.tar.gz && \ RUN tar xf ${NSS_VERSION}.tar.gz && \
cd ${NSS_VERSION}/nss && \ cd ${NSS_VERSION}/nss && \
{{#alpine}} ./build.sh -o --disable-tests --static --python=python3
# Hack to make nss compile on alpine with python3
ln -sf python3 /usr/bin/python && \
{{/alpine}}
./build.sh -o --disable-tests --static
{{/firefox}} {{/firefox}}
{{#chrome}} {{#chrome}}
# BoringSSL doesn't have versions. Choose a commit that is used in a stable # BoringSSL doesn't have versions. Choose a commit that is used in a stable

View File

@@ -16,7 +16,7 @@ Install dependencies for building all the components:
``` ```
sudo apt install build-essential pkg-config cmake ninja-build curl autoconf automake libtool sudo apt install build-essential pkg-config cmake ninja-build curl autoconf automake libtool
# For the Firefox version only # For the Firefox version only
sudo apt install python3-pip python-is-python3 sudo apt install python3-pip
pip install gyp-next pip install gyp-next
export PATH="$PATH:~/.local/bin" # Add gyp to PATH export PATH="$PATH:~/.local/bin" # Add gyp to PATH
# For the Chrome version only # For the Chrome version only

View File

@@ -126,7 +126,10 @@ $(NSS_VERSION).tar.gz:
$(nss_static_libs): $(NSS_VERSION).tar.gz $(nss_static_libs): $(NSS_VERSION).tar.gz
tar xf $(NSS_VERSION).tar.gz tar xf $(NSS_VERSION).tar.gz
cd $(NSS_VERSION)/nss cd $(NSS_VERSION)/nss
./build.sh -o --disable-tests --static ./build.sh -o --disable-tests --static --python=python3
# Hack for macOS: Remove dynamic libraries to force the linker to use the
# static ones when linking curl.
rm -Rf $(nss_install_dir)/lib/*.dylib
boringssl.zip: boringssl.zip:

View File

@@ -48,7 +48,7 @@ ARG NSS_URL=https://ftp.mozilla.org/pub/security/nss/releases/NSS_3_75_RTM/src/n
RUN curl -o ${NSS_VERSION}.tar.gz ${NSS_URL} RUN curl -o ${NSS_VERSION}.tar.gz ${NSS_URL}
RUN tar xf ${NSS_VERSION}.tar.gz && \ RUN tar xf ${NSS_VERSION}.tar.gz && \
cd ${NSS_VERSION}/nss && \ cd ${NSS_VERSION}/nss && \
./build.sh -o --disable-tests --static ./build.sh -o --disable-tests --static --python=python3
ARG NGHTTP2_VERSION=nghttp2-1.46.0 ARG NGHTTP2_VERSION=nghttp2-1.46.0
ARG NGHTTP2_URL=https://github.com/nghttp2/nghttp2/releases/download/v1.46.0/nghttp2-1.46.0.tar.bz2 ARG NGHTTP2_URL=https://github.com/nghttp2/nghttp2/releases/download/v1.46.0/nghttp2-1.46.0.tar.bz2

View File

@@ -41,9 +41,7 @@ ARG NSS_URL=https://ftp.mozilla.org/pub/security/nss/releases/NSS_3_75_RTM/src/n
RUN curl -o ${NSS_VERSION}.tar.gz ${NSS_URL} RUN curl -o ${NSS_VERSION}.tar.gz ${NSS_URL}
RUN tar xf ${NSS_VERSION}.tar.gz && \ RUN tar xf ${NSS_VERSION}.tar.gz && \
cd ${NSS_VERSION}/nss && \ cd ${NSS_VERSION}/nss && \
# Hack to make nss compile on alpine with python3 ./build.sh -o --disable-tests --static --python=python3
ln -sf python3 /usr/bin/python && \
./build.sh -o --disable-tests --static
ARG NGHTTP2_VERSION=nghttp2-1.46.0 ARG NGHTTP2_VERSION=nghttp2-1.46.0
ARG NGHTTP2_URL=https://github.com/nghttp2/nghttp2/releases/download/v1.46.0/nghttp2-1.46.0.tar.bz2 ARG NGHTTP2_URL=https://github.com/nghttp2/nghttp2/releases/download/v1.46.0/nghttp2-1.46.0.tar.bz2

View File

@@ -954,19 +954,86 @@ index 8ac15d407..68d01b219 100644
Libs.private: @LIBCURL_LIBS@ Libs.private: @LIBCURL_LIBS@
Cflags: -I${includedir} @CPPFLAG_CURL_STATICLIB@ Cflags: -I${includedir} @CPPFLAG_CURL_STATICLIB@
diff --git a/m4/curl-nss.m4 b/m4/curl-nss.m4 diff --git a/m4/curl-nss.m4 b/m4/curl-nss.m4
index 397ba71b1..abc09a91c 100644 index 397ba71b1..922cb9a07 100644
--- a/m4/curl-nss.m4 --- a/m4/curl-nss.m4
+++ b/m4/curl-nss.m4 +++ b/m4/curl-nss.m4
@@ -74,7 +74,7 @@ if test "x$OPT_NSS" != xno; then @@ -74,7 +74,74 @@ if test "x$OPT_NSS" != xno; then
# Without pkg-config, we'll kludge in some defaults # Without pkg-config, we'll kludge in some defaults
AC_MSG_WARN([Using hard-wired libraries and compilation flags for NSS.]) AC_MSG_WARN([Using hard-wired libraries and compilation flags for NSS.])
addld="-L$OPT_NSS/lib" addld="-L$OPT_NSS/lib"
- addlib="-lssl3 -lsmime3 -lnss3 -lplds4 -lplc4 -lnspr4" - addlib="-lssl3 -lsmime3 -lnss3 -lplds4 -lplc4 -lnspr4"
+ addlib="-Wl,-Bstatic -Wl,--start-group -lssl -lnss_static -lpk11wrap_static -lcertdb -lcerthi -lsmime -lnsspki -lnssdev -lsoftokn_static -lfreebl_static -lsha-x86_c_lib -lgcm-aes-x86_c_lib -lhw-acc-crypto-avx -lhw-acc-crypto-avx2 -lnssutil -lnssb -lcryptohi -l:libplc4.a -l:libplds4.a -l:libnspr4.a -lsqlite -Wl,--end-group -Wl,-Bdynamic -pthread -ldl" +
+ # curl-impersonate: Link NSS statically.
+ # NSS is poorly documented in this regard and a lot of trial and error
+ # was made to come up with the correct list of linking flags. The
+ # libraries have circular dependencies which makes their order extremely
+ # difficult to find out.
+
+ # Some references:
+ # https://github.com/mozilla/application-services/blob/b2690fd2e4cc3e8e10b6868ab0de8b79c89d3a93/components/support/rc_crypto/nss/nss_build_common/src/lib.rs#L94
+ # and
+ # https://hg.mozilla.org/mozilla-central/file/tip/security/nss/lib/freebl/freebl.gyp
+
+ # On Linux we can use special linker flags to force static linking
+ # (-l:libplc4.a etc.), otherwise the linker will prefer to use
+ # libplc4.so. On other systems the dynamic libraries would have to be
+ # removed manually from the NSS directory before building curl.
+ case $host_os in
+ linux*)
+ addlib="-lssl -lnss_static -lpk11wrap_static -lcertdb -lcerthi -lnsspki -lnssdev -lsoftokn_static -lfreebl_static -lnssutil -lnssb -lcryptohi -l:libplc4.a -l:libplds4.a -l:libnspr4.a -lsqlite"
+ ;;
+ darwin*)
+ addlib="-lssl -lnss_static -lpk11wrap_static -lcertdb -lcerthi -lnsspki -lnssdev -lsoftokn_static -lfreebl_static -lnssutil -lnssb -lcryptohi -lplc4 -lplds4 -lnspr4"
+ ;;
+ *)
+ addlib="-lssl -lnss_static -lpk11wrap_static -lcertdb -lcerthi -lnsspki -lnssdev -lsoftokn_static -lfreebl_static -lnssutil -lnssb -lcryptohi -lplc4 -lplds4 -lnspr4 -lsqlite"
+ ;;
+ esac
+
+ case $host_cpu in
+ arm)
+ addlib="$addlib -larmv8_c_lib"
+ ;;
+ aarch64)
+ addlib="$addlib -larmv8_c_lib -lgcm-aes-aarch64_c_lib"
+ ;;
+ x86)
+ addlib="$addlib -lgcm-aes-x86_c_lib"
+ ;;
+ x86_64)
+ addlib="$addlib -lgcm-aes-x86_c_lib -lhw-acc-crypto-avx -lhw-acc-crypto-avx2 -lsha-x86_c_lib"
+ case $host_os in
+ linux*)
+ addlib="$addlib -lintel-gcm-wrap_c_lib -lintel-gcm-s_lib"
+ ;;
+ esac
+ ;;
+ esac
+
+ # curl-impersonate:
+ # On Linux these linker flags are necessary to resolve
+ # the symbol mess and circular dependencies of NSS .a libraries
+ # to make the AC_CHECK_LIB test below pass.
+ case $host_os in
+ linux*)
+ addlib="-Wl,--start-group $addlib -Wl,--end-group"
+ ;;
+ esac
+
+ # External dependencies for nss
+ case $host_os in
+ linux*)
+ addlib="$addlib -pthread -ldl"
+ ;;
+ darwin*)
+ addlib="$addlib -lsqlite3"
+ ;;
+ esac
+
addcflags="-I$OPT_NSS/include" addcflags="-I$OPT_NSS/include"
version="unknown" version="unknown"
nssprefix=$OPT_NSS nssprefix=$OPT_NSS
@@ -91,7 +91,7 @@ if test "x$OPT_NSS" != xno; then @@ -91,7 +158,7 @@ if test "x$OPT_NSS" != xno; then
fi fi
dnl The function SSL_VersionRangeSet() is needed to enable TLS > 1.0 dnl The function SSL_VersionRangeSet() is needed to enable TLS > 1.0
@@ -975,6 +1042,17 @@ index 397ba71b1..abc09a91c 100644
[ [
AC_DEFINE(USE_NSS, 1, [if NSS is enabled]) AC_DEFINE(USE_NSS, 1, [if NSS is enabled])
AC_SUBST(USE_NSS, [1]) AC_SUBST(USE_NSS, [1])
@@ -101,9 +168,7 @@ if test "x$OPT_NSS" != xno; then
test nss != "$DEFAULT_SSL_BACKEND" || VALID_DEFAULT_SSL_BACKEND=yes
],
[
- LDFLAGS="$CLEANLDFLAGS"
- LIBS="$CLEANLIBS"
- CPPFLAGS="$CLEANCPPFLAGS"
+ AC_MSG_ERROR([Failed linking NSS statically])
])
if test "x$USE_NSS" = "xyes"; then
diff --git a/src/Makefile.am b/src/Makefile.am diff --git a/src/Makefile.am b/src/Makefile.am
index c8abc93b1..fcecb10d0 100644 index c8abc93b1..fcecb10d0 100644
--- a/src/Makefile.am --- a/src/Makefile.am