Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ jobs:
- setup: al2023-x86_64-aws_lc
docker-compose-run: "-f docker/docker-compose.al2023.yaml run build"
docker-bake-args: "-f docker-compose.al2023.yaml"
# boringssl-static on a current toolchain, and the only CI leg that builds the FIPS
# profile (it needs clang; see docker/Dockerfile.debian13). Neither is a release
# artifact. Before these legs the FIPS profile had no CI at all, so a change to the
# release profiles that was not ported to it went unnoticed until a downstream build.
- setup: debian13-x86_64
docker-compose-run: "-f docker/docker-compose.debian-13.yaml run build"
docker-bake-args: "-f docker-compose.debian-13.yaml"
- setup: debian13-x86_64-fips
docker-compose-run: "-f docker/docker-compose.debian-13.yaml run build-fips"
docker-bake-args: "-f docker-compose.debian-13.yaml"

name: ${{ matrix.setup }}
permissions:
Expand Down Expand Up @@ -219,6 +229,28 @@ jobs:
drop-elftools: "0"
build-service: runtime-setup
run-service: verify
# The Debian 13-built jars: the FIPS artifact is the one that matters (its power-on
# self-test and integrity check run inside an ELF constructor at dlopen, so only a
# real load proves the patchelf'd library is still intact), and the default-profile
# one shows what a modern-gcc build looks like on musl. bare x86_64 only: aarch64
# would need an arm64 FIPS build leg, and the gcompat/nolibgcc variants add nothing
# the CentOS 6 legs do not already establish.
- setup: alpine-x86_64-fips
os: ubuntu-24.04
jars: build-debian13-x86_64-fips-jars
variant: bare
extra-pkgs: ""
drop-elftools: "1"
build-service: runtime-setup
run-service: verify
- setup: alpine-x86_64-debian13
os: ubuntu-24.04
jars: build-debian13-x86_64-jars
variant: bare
extra-pkgs: ""
drop-elftools: "1"
build-service: runtime-setup
run-service: verify
- setup: glibc-control-x86_64
os: ubuntu-24.04
jars: build-centos6-x86_64-jars
Expand Down
32 changes: 32 additions & 0 deletions .github/workflows/ci-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ jobs:
- setup: al2023-x86_64-aws_lc
docker-compose-run: "-f docker/docker-compose.al2023.yaml run build"
docker-bake-args: "-f docker-compose.al2023.yaml"
# boringssl-static on a current toolchain, and the only CI leg that builds the FIPS
# profile (it needs clang; see docker/Dockerfile.debian13). Neither is a release
# artifact. Before these legs the FIPS profile had no CI at all, so a change to the
# release profiles that was not ported to it went unnoticed until a downstream build.
- setup: debian13-x86_64
docker-compose-run: "-f docker/docker-compose.debian-13.yaml run build"
docker-bake-args: "-f docker-compose.debian-13.yaml"
- setup: debian13-x86_64-fips
docker-compose-run: "-f docker/docker-compose.debian-13.yaml run build-fips"
docker-bake-args: "-f docker-compose.debian-13.yaml"

name: ${{ matrix.setup }}
permissions:
Expand Down Expand Up @@ -280,6 +290,28 @@ jobs:
drop-elftools: "0"
build-service: runtime-setup
run-service: verify
# The Debian 13-built jars: the FIPS artifact is the one that matters (its power-on
# self-test and integrity check run inside an ELF constructor at dlopen, so only a
# real load proves the patchelf'd library is still intact), and the default-profile
# one shows what a modern-gcc build looks like on musl. bare x86_64 only: aarch64
# would need an arm64 FIPS build leg, and the gcompat/nolibgcc variants add nothing
# the CentOS 6 legs do not already establish.
- setup: alpine-x86_64-fips
os: ubuntu-24.04
jars: build-pr-debian13-x86_64-fips-jars
variant: bare
extra-pkgs: ""
drop-elftools: "1"
build-service: runtime-setup
run-service: verify
- setup: alpine-x86_64-debian13
os: ubuntu-24.04
jars: build-pr-debian13-x86_64-jars
variant: bare
extra-pkgs: ""
drop-elftools: "1"
build-service: runtime-setup
run-service: verify
# Control: anything failing on Alpine must pass here, or the check is at fault rather
# than the artifact.
- setup: glibc-control-x86_64
Expand Down
75 changes: 54 additions & 21 deletions boringssl-static/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -116,40 +116,51 @@
<profile>
<id>fips-boringssl-static</id>
<properties>
<boringsslCheckoutDir>${project.build.directory}/boringssl-${boringsslBranch}/boringssl</boringsslCheckoutDir>
<boringsslCheckoutDir>${project.build.directory}/boringssl-${boringsslFipsBranch}/boringssl</boringsslCheckoutDir>
<boringsslBuildDir>${boringsslCheckoutDir}/build</boringsslBuildDir>
<!-- Latest FIPS compliant boringSSL commit -->
<boringsslBranch>6d503ae1cf8b2e25162435225610b8c1f063d6f4</boringsslBranch>
<!-- Source: the head of BoringSSL's newest FIPS branch. Google cuts a fips-YYYYMMDD
branch for every module it submits to NIST; see
https://boringssl.googlesource.com/boringssl/+/refs/heads/main/crypto/fipsmodule/FIPS.md
Pinned to a sha, like the default profile's source, so the build is reproducible.
This module holds no certificate yet. Bump both properties together. -->
<boringsslFipsBranch>fips-20260721</boringsslFipsBranch>
<boringsslFipsCommitSha>b2f6124823a1b1611e66c94dc38a5eb21db0f5c7</boringsslFipsCommitSha>
<linkStatic>true</linkStatic>
<msvcSslIncludeDirs>${boringsslCheckoutDir}/include</msvcSslIncludeDirs>
<msvcSslLibDirs>${boringsslBuildDir}/ssl;${boringsslBuildDir}/crypto;${boringsslBuildDir}/decrepit</msvcSslLibDirs>
<msvcSslLibs>ssl.lib;crypto.lib;decrepit.lib</msvcSslLibs>
<jniArch>${os.detected.arch}</jniArch>
<project.artifactId>netty-tcnative-boringssl-static-fips</project.artifactId>
<!-- Compiler for BoringSSL itself; FIPS.md asks for clang. tcnative and APR are built
with the host cc. The CI image pins the version (docker/Dockerfile.debian13). -->
<fipsCC>clang</fipsCC>
<fipsCXX>clang++</fipsCXX>
</properties>

<build>
<plugins>

<!-- Download the BoringSSL source -->
<!-- Check BoringSSL out from git, as the default profile does. The tarballs on
commondatastorage.googleapis.com/chromium-boringssl-fips are no longer public. -->
<plugin>
<groupId>com.googlecode.maven-download-plugin</groupId>
<artifactId>download-maven-plugin</artifactId>
<version>1.6.8</version>
<artifactId>maven-scm-plugin</artifactId>
<executions>
<execution>
<id>install-fips-boringssl</id>
<phase>process-sources</phase>
<id>get-fips-boringssl</id>
<phase>generate-sources</phase>
<goals>
<goal>wget</goal>
<goal>checkout</goal>
</goals>
<configuration>
<checkoutDirectory>${boringsslCheckoutDir}</checkoutDirectory>
<connectionType>developerConnection</connectionType>
<developerConnectionUrl>scm:git:${boringsslRepository}</developerConnectionUrl>
<scmVersion>${boringsslFipsBranch}</scmVersion>
<scmVersionType>branch</scmVersionType>
<skipCheckoutIfExists>true</skipCheckoutIfExists>
</configuration>
</execution>
</executions>
<configuration>
<url>https://commondatastorage.googleapis.com/chromium-boringssl-fips/boringssl-${boringsslBranch}.tar.xz</url>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the tar bundle that's actually FIPS validated, isn't it? I'm not sure we can just jump to the latest commit on the boringssl fips branch.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From https://boringssl.googlesource.com/boringssl/+/refs/heads/main/crypto/fipsmodule/FIPS.md
The last validated module is 2024-08-05 (fips-20240805), certificate (#5244, issued April 2026)

It was updated already to fips-20251031 previously in netty-tcnative. I believe this had more to do to get newer API and avoid compilation problem. So the current version is not fips validated.

FIPS.md recommand to use main directly.

Also to be noted, https://commondatastorage.googleapis.com/chromium-boringssl-fips is not working anymore, we need to fetch git commits directly on the upstream repo.

<unpack>true</unpack>
<outputDirectory>${project.build.directory}/boringssl-${boringsslBranch}</outputDirectory>
</configuration>
</plugin>

<plugin>
Expand Down Expand Up @@ -177,8 +188,8 @@
<configuration>
<instructions>
<Apr-Version>${aprVersion}</Apr-Version>
<BoringSSL-Revision>${boringsslBuildNumber}</BoringSSL-Revision>
<BoringSSL-Branch>${boringsslBranch}</BoringSSL-Branch>
<BoringSSL-Revision>${boringsslFipsCommitSha}</BoringSSL-Revision>
<BoringSSL-Branch>${boringsslFipsBranch}</BoringSSL-Branch>
<BoringSSL-FIPS-Compliant>true</BoringSSL-FIPS-Compliant>
</instructions>
</configuration>
Expand Down Expand Up @@ -207,6 +218,12 @@
<else>
<echo message="Building BoringSSL" />

<!-- Use the known SHA of the commit, as the default profile does -->
<exec executable="git" failonerror="true" dir="${boringsslCheckoutDir}" resolveexecutable="true">
<arg value="checkout" />
<arg value="${boringsslFipsCommitSha}" />
</exec>

<mkdir dir="${boringsslBuildDir}" />

<if>
Expand Down Expand Up @@ -234,11 +251,18 @@
<property name="cmakeCxxFlags" value="-O3 -fno-omit-frame-pointer" />
</else>
</if>
<!-- The static archives end up inside a shared library, so they must be
PIC, same as the default profile asks. Without it the aarch64 link
fails on libcrypto.a(crypto.cc.o): "relocation
R_AARCH64_ADR_PREL_PG_HI21 against symbol stderr ... can not be used
when making a shared object; recompile with -fPIC". delocate is
written for PIC input, so this does not affect the FIPS module. -->
<exec executable="cmake" failonerror="true" dir="${boringsslBuildDir}" resolveexecutable="true">
<arg value="-DCMAKE_POSITION_INDEPENDENT_CODE=TRUE" />
<arg value="-DCMAKE_BUILD_TYPE=Release" />
<arg value="-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded" />
<arg value="-DCMAKE_C_COMPILER=clang-12" />
<arg value="-DCMAKE_CXX_COMPILER=clang++-12" />
<arg value="-DCMAKE_C_COMPILER=${fipsCC}" />
<arg value="-DCMAKE_CXX_COMPILER=${fipsCXX}" />
<arg value="-DFIPS=1" />
<arg value="-GNinja" />
<arg value="${boringsslCheckoutDir}" />
Expand All @@ -257,8 +281,14 @@
<if>
<equals arg1="${os.detected.name}" arg2="linux" />
<then>
<!-- This is needed to generate bssl execute file to verify isfips property-->
<!-- Only what the link and the isfips gate below need. A bare `ninja`
builds every target, and the test binaries alone are most of the
wall-clock time of this profile. -->
<exec executable="${ninjaExecutable}" failonerror="true" dir="${boringsslBuildDir}" resolveexecutable="true">
<arg value="crypto" />
<arg value="ssl" />
<arg value="decrepit" />
<arg value="bssl" />
</exec>
<exec executable="./bssl" failonerror="false" dir="${boringsslBuildDir}" outputproperty="boringssl.isfips.result">
<arg value="isfips" />
Expand Down Expand Up @@ -413,7 +443,10 @@
<configureArg>--libdir=${project.build.directory}/native-build/target/lib</configureArg>
<configureArg>CFLAGS=-O3 -Werror -fno-omit-frame-pointer -fvisibility=hidden -Wunused -Wno-unused-value</configureArg>
<configureArg>CPPFLAGS=-DHAVE_OPENSSL -I${boringsslCheckoutDir}/include</configureArg>
<configureArg>LDFLAGS=-L${boringsslBuildDir} -lssl -lcrypto -ldecrepit -l:libstdc++.a -l:libgcc.a -l:libgcc_eh.a</configureArg>
<!-- gc-sections: this BoringSSL drags in libstdc++'s std::random_device, which nothing
calls and which imports arc4random (glibc 2.36+, absent from musl). Dropping
the dead code removes the import. See docs/musl-compatibility.md -->
<configureArg>LDFLAGS=-L${boringsslBuildDir} -Wl,--gc-sections -lssl -lcrypto -ldecrepit -l:libstdc++.a -l:libgcc.a -l:libgcc_eh.a</configureArg>
</configureArgs>
</configuration>
</execution>
Expand Down
1 change: 1 addition & 0 deletions docker/Dockerfile.arch
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ RUN pacman -Sy --noconfirm --needed \
lsb-release \
make \
ninja \
patchelf \
perl \
tar \
unzip \
Expand Down
82 changes: 82 additions & 0 deletions docker/Dockerfile.debian13
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Everything in this image is pinned: the base by digest, the Debian archive by a
# snapshot.debian.org timestamp, clang by version, Go by version and checksum. To refresh it,
# bump the four values below together and rebuild.
ARG debian_image=debian:13.7@sha256:9cc080028c43b27d2074d63a5f9caf7166d731494965616c1a6d2827a004585c
FROM $debian_image
ARG debian_snapshot=20260915T000000Z
ARG clang_version=19
ARG go_version=1.27.1
ARG go_sha256_amd64=63d339f0da5ab53635a56f2490a7984dfe12dfcff22ad749f63edaf590168445
ARG go_sha256_arm64=3450b45a3f9ee8568792736a5c5e70a1f2e9b36c35a8f74958c03e51d7d92bec
ENV DEBIAN_FRONTEND noninteractive

# A modern glibc builder for boringssl-static, and the only in-tree image that can build the
# fips-boringssl-static profile, which compiles BoringSSL with clang. Google's FIPS.md asks for
# recent stable Clang, Go, Ninja and CMake: clang, ninja and cmake are Debian 13's own. Go is
# not: BoringSSL's go.mod floor (1.25.8 on the pinned fips-20260721) is ahead of trixie's 1.24,
# so it comes from go.dev, checksum-verified. patchelf 0.18 has --remove-needed; APR's
# buildconf wants the `libtool` script, which is in libtool-bin.
#
# No JDK 8 in trixie: the build runs on JDK 21. The pom compiles with --release 8, so the
# class files are still Java 8.
#
# Not pinned to linux/amd64 like the older images, so it can also be built natively on an
# arm64 host for a quick local run. CI builds it on amd64 runners.
#
# Unlike the CentOS 6 image this is NOT a release builder: its artifact needs a newer glibc than
# the release ones. It exists to give the boringssl-static and FIPS builds CI coverage on a
# current toolchain.

# Freeze the archive. snapshot.debian.org serves the archive as it was at that instant, so the
# same package versions install no matter when the image is built; Valid-Until has long passed
# by then, hence check-valid-until=no.
RUN rm -f /etc/apt/sources.list.d/debian.sources \
&& echo "deb [check-valid-until=no] http://snapshot.debian.org/archive/debian/$debian_snapshot trixie main" > /etc/apt/sources.list \
&& echo "deb [check-valid-until=no] http://snapshot.debian.org/archive/debian/$debian_snapshot trixie-updates main" >> /etc/apt/sources.list \
&& echo "deb [check-valid-until=no] http://snapshot.debian.org/archive/debian-security/$debian_snapshot trixie-security main" >> /etc/apt/sources.list

RUN apt-get update && apt-get install -y --no-install-recommends \
autoconf \
automake \
bzip2 \
ca-certificates \
clang-$clang_version \
cmake \
curl \
g++ \
gcc \
git \
gnupg \
libapr1-dev \
libtool \
libtool-bin \
make \
ninja-build \
openjdk-21-jdk-headless \
patch \
patchelf \
perl \
pkg-config \
tar \
unzip \
wget \
xz-utils \
zip \
&& rm -rf /var/lib/apt/lists/* \
&& ln -s clang-$clang_version /usr/bin/clang && ln -s clang++-$clang_version /usr/bin/clang++

# dpkg's amd64/arm64 spelling matches go.dev's and the JVM directory name.
RUN ARCH=$(dpkg --print-architecture) \
&& case $ARCH in amd64) GO_SHA256=$go_sha256_amd64;; arm64) GO_SHA256=$go_sha256_arm64;; esac \
&& wget -q https://go.dev/dl/go$go_version.linux-$ARCH.tar.gz \
&& echo "$GO_SHA256 go$go_version.linux-$ARCH.tar.gz" | sha256sum -c - \
&& tar -C /opt -xzf go$go_version.linux-$ARCH.tar.gz && rm go$go_version.linux-$ARCH.tar.gz \
&& ln -s /opt/go/bin/go /usr/local/bin/go && ln -s /opt/go/bin/gofmt /usr/local/bin/gofmt \
&& ln -s /usr/lib/jvm/java-21-openjdk-$ARCH /usr/lib/jvm/java-21 \
&& go version && clang --version && ninja --version && cmake --version
ENV JAVA_HOME /usr/lib/jvm/java-21
# Use exactly the pinned Go; never let it fetch another toolchain.
ENV GOTOOLCHAIN local

# /code is a bind mount owned by the host user; newer git refuses to touch it otherwise.
RUN git config --global --add safe.directory '*'
1 change: 1 addition & 0 deletions docker/Dockerfile.opensuse
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ RUN zypper install --force-resolution --no-recommends --no-confirm \
make \
ninja \
patch \
patchelf \
perl \
tar \
unzip \
Expand Down
14 changes: 14 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ docker compose -f docker/docker-compose.opensuse.yaml -f docker/docker-compose.o
docker compose -f docker/docker-compose.centos-7.yaml run cross-compile-aarch64-build
```

## Debian 13 with java 21: boringssl-static on a current toolchain, and the FIPS profile

Not a release builder: its artifacts need a newer glibc than the release ones. It is the one
image that can build the `fips-boringssl-static` profile, which compiles BoringSSL with clang.
Everything is pinned: the base image by digest, the Debian archive by a snapshot.debian.org
timestamp, clang by version, Go by version and checksum. Both services stop at `package`,
which is where the musl compatibility check runs. Not pinned to amd64, so on an arm64 host it
builds natively.

```
docker compose -f docker/docker-compose.debian-13.yaml run build
docker compose -f docker/docker-compose.debian-13.yaml run build-fips
```

etc, etc


Expand Down
46 changes: 46 additions & 0 deletions docker/docker-compose.debian-13.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
version: "3"

# Debian 13 builder. Two things run here that no other image covers, see Dockerfile.debian13:
# build boringssl-static (default profile) on a current gcc, so the Linux native
# build is exercised somewhere other than the CentOS 6 release image
# build-fips the fips-boringssl-static profile, which needs clang
# Both stop at `package`, which is where the native-jar musl check runs.

services:

runtime-setup:
image: netty-tcnative-debian:13
build:
context: ../
dockerfile: docker/Dockerfile.debian13
cache_from:
- type=registry,ref=ghcr.io/netty/netty-tcnative-build-cache:debian13
cache_to:
- type=registry,ref=ghcr.io/netty/netty-tcnative-build-cache:debian13,mode=max,ignore-error=true

common: &common
image: netty-tcnative-debian:13
depends_on: [runtime-setup]
environment:
- MAVEN_OPTS
volumes:
- ~/.m2/repository:/root/.m2/repository
- ..:/code:delegated
working_dir: /code

build:
<<: *common
command: /bin/bash -cl "./mvnw -am -pl boringssl-static clean package"

build-fips:
<<: *common
command: /bin/bash -cl "./mvnw -Pfips-boringssl-static -am -pl boringssl-static clean package"

shell:
<<: *common
volumes:
- ~/.m2/repository:/root/.m2/repository
- ~/.gitconfig:/root/.gitconfig:delegated
- ~/.gitignore:/root/.gitignore:delegated
- ..:/code:delegated
entrypoint: /bin/bash
Loading
Loading