Skip to content
Merged
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
26 changes: 21 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ on:
- 'assets/**'
- 'test/**'
- '.github/workflows/build.yml'
pull_request:
paths:
- 'Dockerfile'
- 'versions/**'
- 'scripts/**'
- 'assets/**'
- 'test/**'
- '.github/workflows/build.yml'
workflow_dispatch:
inputs:
version:
Expand Down Expand Up @@ -68,12 +76,14 @@ jobs:
uses: docker/setup-buildx-action@v3

- name: Login to Docker Hub
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}

- name: Login to GitHub Container Registry
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ghcr.io
Expand Down Expand Up @@ -122,18 +132,23 @@ jobs:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: true
pull: true
push: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
build-args: |
BASE_IMAGE_TAG=${{ matrix.base_image_tag }}
JAVA_VERSION=${{ matrix.java_version }}
JAVA_DETAIL_VERSION=${{ matrix.detail_version }}
VARIANT=${{ matrix.variant }}
JMODS_RELEASE_TAG=${{ matrix.jmods_release_tag }}
JMODS_ARCHIVE_VERSION=${{ matrix.jmods_archive_version }}
JMODS_SHA256_AMD64=${{ matrix.jmods_sha256_amd64 }}
JMODS_SHA256_ARM64=${{ matrix.jmods_sha256_arm64 }}
cache-from: type=gha,scope=${{ matrix.name }}
cache-to: type=gha,mode=max,scope=${{ matrix.name }}

- name: Run Trivy vulnerability scanner
if: steps.build.outcome == 'success'
if: steps.build.outcome == 'success' && github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ env.DOCKER_HUB_IMAGE }}:${{ steps.vars.outputs.version }}
Expand All @@ -143,7 +158,7 @@ jobs:

- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v4
if: steps.build.outcome == 'success'
if: steps.build.outcome == 'success' && github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
with:
sarif_file: 'trivy-results.sarif'

Expand All @@ -152,6 +167,7 @@ jobs:
# =============================================================================
update-readme:
needs: build
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: write
Expand Down Expand Up @@ -206,9 +222,9 @@ jobs:
```bash
# Build specific version (see versions/versions.json for available configurations)
docker build \
--build-arg BASE_IMAGE_TAG=21.0.5_11-jdk-noble \
--build-arg BASE_IMAGE_TAG=21.0.12.1_1-jdk-noble \
--build-arg JAVA_VERSION=21 \
--build-arg JAVA_DETAIL_VERSION=21.0.5 \
--build-arg JAVA_DETAIL_VERSION=21.0.12.1 \
-t my-jdk:21 .
```

Expand Down
34 changes: 26 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
# Parameterized JDK Dockerfile with variant support
#
# Build examples:
# Standard: docker build --build-arg BASE_IMAGE_TAG=21.0.10_7-jdk-noble --build-arg JAVA_VERSION=21 --build-arg JAVA_DETAIL_VERSION=21.0.10 .
# With Docker: docker build --build-arg BASE_IMAGE_TAG=21.0.10_7-jdk-noble --build-arg JAVA_VERSION=21 --build-arg JAVA_DETAIL_VERSION=21.0.10 --build-arg VARIANT=docker .
# With Jacoco: docker build --build-arg BASE_IMAGE_TAG=21.0.10_7-jdk-noble --build-arg JAVA_VERSION=21 --build-arg JAVA_DETAIL_VERSION=21.0.10 --build-arg VARIANT=jacoco .
# Standard: docker build --build-arg BASE_IMAGE_TAG=21.0.12.1_1-jdk-noble --build-arg JAVA_VERSION=21 --build-arg JAVA_DETAIL_VERSION=21.0.12.1 .
# With Docker: docker build --build-arg BASE_IMAGE_TAG=21.0.12.1_1-jdk-noble --build-arg JAVA_VERSION=21 --build-arg JAVA_DETAIL_VERSION=21.0.12.1 --build-arg VARIANT=docker .
# With Jacoco: docker build --build-arg BASE_IMAGE_TAG=21.0.12.1_1-jdk-noble --build-arg JAVA_VERSION=21 --build-arg JAVA_DETAIL_VERSION=21.0.12.1 --build-arg VARIANT=jacoco .

# Default to JDK 21 LTS
ARG BASE_IMAGE_TAG=21.0.10_7-jdk-noble
ARG BASE_IMAGE_TAG=21.0.12.1_1-jdk-noble

# =============================================================================
# Builder Stage: Compile font test
# =============================================================================
FROM public.ecr.aws/docker/library/eclipse-temurin:${BASE_IMAGE_TAG} AS builder
FROM docker.io/library/eclipse-temurin:${BASE_IMAGE_TAG} AS builder

WORKDIR /workspace/app
COPY test/FontTest.java .
RUN javac FontTest.java
COPY scripts/UpdateBlockedCertificates.java test/CertificateBlocklistTest.java test/UpdateBlockedCertificatesTest.java ./
RUN javac FontTest.java UpdateBlockedCertificates.java CertificateBlocklistTest.java UpdateBlockedCertificatesTest.java

# =============================================================================
# Runtime Stage: Final JDK image
# =============================================================================
FROM public.ecr.aws/docker/library/eclipse-temurin:${BASE_IMAGE_TAG}
FROM docker.io/library/eclipse-temurin:${BASE_IMAGE_TAG}

ARG JAVA_VERSION=21
ARG JAVA_DETAIL_VERSION=21.0.10
ARG JAVA_DETAIL_VERSION=21.0.12.1
ARG VARIANT=standard
ARG JMODS_RELEASE_TAG
ARG JMODS_ARCHIVE_VERSION
ARG JMODS_SHA256_AMD64
ARG JMODS_SHA256_ARM64

ENV JAVA_VERSION=${JAVA_VERSION} \
JAVA_DETAIL_VERSION=${JAVA_DETAIL_VERSION} \
Expand All @@ -36,6 +41,19 @@ RUN chmod +x /tmp/scripts/*.sh

# Install base dependencies (always)
RUN /tmp/scripts/install-base.sh
RUN /tmp/scripts/install-jmods.sh

# Apply the upstream CVE-2026-91403 distrust to the effective runtime security file.
COPY assets/security/cve-2026-91403.properties test/fixtures/cve-2026-91403.pem /tmp/java-security/
COPY --from=builder /workspace/app/UpdateBlockedCertificates.class /workspace/app/CertificateBlocklistTest.class /workspace/app/UpdateBlockedCertificatesTest.class /tmp/java-security/
RUN java -cp /tmp/java-security UpdateBlockedCertificatesTest /tmp/java-security/cve-2026-91403.properties \
&& java -cp /tmp/java-security UpdateBlockedCertificates /tmp/java-security/cve-2026-91403.properties \
&& java -cp /tmp/java-security CertificateBlocklistTest /tmp/java-security/cve-2026-91403.pem /tmp/java-security/cve-2026-91403.properties \
&& if command -v jlink >/dev/null 2>&1; then \
jlink --add-modules java.base,jdk.crypto.ec --output /tmp/java-security/linked \
&& /tmp/java-security/linked/bin/java -cp /tmp/java-security CertificateBlocklistTest /tmp/java-security/cve-2026-91403.pem /tmp/java-security/cve-2026-91403.properties; \
fi \
&& rm -rf /tmp/java-security

# Cleanup installation scripts
RUN rm -rf /tmp/scripts
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ Multi-platform JDK Docker images based on Eclipse Temurin.

| JDK Version | Version | Docker Hub Tags | GitHub Package Tags |
|-------------|---------|-----------------|---------------------|
| jdk8 | 8 | `ringcentral/jdk:8` `ringcentral/jdk:8u482` | `ghcr.io/ringcentral-docker/jdk:8` `ghcr.io/ringcentral-docker/jdk:8u482` |
| jdk11 | 11 | `ringcentral/jdk:11` `ringcentral/jdk:11.0.30` | `ghcr.io/ringcentral-docker/jdk:11` `ghcr.io/ringcentral-docker/jdk:11.0.30` |
| jdk17 | 17 | `ringcentral/jdk:17` `ringcentral/jdk:17.0.18` | `ghcr.io/ringcentral-docker/jdk:17` `ghcr.io/ringcentral-docker/jdk:17.0.18` |
| jdk21 | 21 | `ringcentral/jdk:21` `ringcentral/jdk:21.0.10` | `ghcr.io/ringcentral-docker/jdk:21` `ghcr.io/ringcentral-docker/jdk:21.0.10` |
| jdk25 | 25 | `ringcentral/jdk:25` `ringcentral/jdk:25.0.2` | `ghcr.io/ringcentral-docker/jdk:25` `ghcr.io/ringcentral-docker/jdk:25.0.2` |
| jdk8 | 8 | `ringcentral/jdk:8` `ringcentral/jdk:8u504` | `ghcr.io/ringcentral-docker/jdk:8` `ghcr.io/ringcentral-docker/jdk:8u504` |
| jdk11 | 11 | `ringcentral/jdk:11` `ringcentral/jdk:11.0.32.1` | `ghcr.io/ringcentral-docker/jdk:11` `ghcr.io/ringcentral-docker/jdk:11.0.32.1` |
| jdk17 | 17 | `ringcentral/jdk:17` `ringcentral/jdk:17.0.20.1` | `ghcr.io/ringcentral-docker/jdk:17` `ghcr.io/ringcentral-docker/jdk:17.0.20.1` |
| jdk21 | 21 | `ringcentral/jdk:21` `ringcentral/jdk:21.0.12.1` | `ghcr.io/ringcentral-docker/jdk:21` `ghcr.io/ringcentral-docker/jdk:21.0.12.1` |
| jdk25 | 25 | `ringcentral/jdk:25` `ringcentral/jdk:25.0.4.1` | `ghcr.io/ringcentral-docker/jdk:25` `ghcr.io/ringcentral-docker/jdk:25.0.4.1` |

## Usage

Expand All @@ -35,9 +35,9 @@ docker run -it ringcentral/jdk:21 java -version
```bash
# Build specific version (see versions/versions.json for available configurations)
docker build \
--build-arg BASE_IMAGE_TAG=21.0.5_11-jdk-noble \
--build-arg BASE_IMAGE_TAG=21.0.12.1_1-jdk-noble \
--build-arg JAVA_VERSION=21 \
--build-arg JAVA_DETAIL_VERSION=21.0.5 \
--build-arg JAVA_DETAIL_VERSION=21.0.12.1 \
-t my-jdk:21 .
```

Expand Down
37 changes: 37 additions & 0 deletions assets/security/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# CVE-2026-91403 certificate distrust

The Temurin base versions in `versions/versions.json` still require the
[official certificate-blocklist mitigation](https://ops.java/emudhra).
Updating OS CA packages alone does not update the JDK blocklist.

`cve-2026-91403.properties` contains the 48 new SHA-256 fingerprints from
[OpenJDK commit 22bc7357ce6bc5f1ed2f1e83e0544b2c25f781d4](https://github.com/openjdk/jdk/commit/22bc7357ce6bc5f1ed2f1e83e0544b2c25f781d4).
They cover all 16 PEM certificates added by that commit, including the
alternative AlgorithmIdentifier and ECDSA signature encodings emitted by its
fixed `BlockedCertsConverter`. The supplement SHA-256 is
`e16ed9c4ea8a140402ceaf15a859d66c0a66952024fc25740573acff6bf851fb`.

The source `blocked.certs.pem` SHA-256 is
`23daaddff18ed3800bf38937b51cd91045777719baa19437d812afeb9b44b64e`.
Generating the full upstream list produces 86 fingerprints (SHA-256
`2596bb6dda83c66d96c5a252d7b2ae1f24cc1ae3f1890223b4f3591a8d52bf10`).
Only the 48 newly added fingerprints are appended, preserving the base image's
existing blocklist and any custom entries.

During every image build, `UpdateBlockedCertificates` locates the security file
under the running JVM's `java.home`: `blacklisted.certs` for Java 8 and
`blocked.certs` for newer releases. It also updates the blocklist inside
`jmods/java.base.jmod` so runtimes produced by `jlink` inherit the same distrust.
Temurin 25 omits JMODs; its linkable runtime rejects a modified `blocked.certs`.
The build restores matching official Temurin JMODs with architecture-specific
SHA-256 checksums pinned in `versions/versions.json`, then updates that copy too.
This preserves ordinary `jlink` behavior and its runtime integrity checks.
It fails the build if the existing file does
not use SHA-256. Tests check preservation and idempotence, then exercise PKIX
validation against all 48 encodings in `test/fixtures/cve-2026-91403.pem` and an
unaffected ISRG Root X1 trust anchor. On Java 11+, the build repeats the PKIX test
using a freshly generated `jlink` runtime. No network revocation service is required.

The fixture contains public CA certificates, never private keys. It is used only
for build-time validation and is removed from the final image along with the
test classes.
49 changes: 49 additions & 0 deletions assets/security/cve-2026-91403.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Algorithm=SHA-256
0164D7CEAE5BB909C272AF151FF44B1177AE9B47D9424B94F1D9558C30934D19
10E7E5BFDB55CFB78D0C21366654046182087A1960C079682513795665AA0C6B
169A0523C5E071AA4E298286DBD4EE0E40C8C06ABB6B0C077D132F001FA19240
21182E577E5106B669322ABE6086FFF6B101E8C83FD2D01DC32D854961AAC832
33C1BCDC6DA52DF950B3B14121127DA1955F7F31F828497A7608986EB2DDCC09
37E866582D43C35D7C17D47794B974F291B3047B868DC123382477F7A08AEFA8
3B88E4B77FC53C45CA216700E39FC0EA7621A0A40FCB268215082E35D2BD5829
3C5456D4219BA2372273867FAC9A07104600391E96C7FDCDE3B4420C0F1F69BF
42C4ACCD12C4F59597925E1A08A7A90102608543809308D50EC427E118BA1493
432EC25F0D28DE9006D97BF752F17BBB2CD41F669933FCB072D9A1148D0261F3
45A883F349AEDFD5F3A649B5498FFB121712BA8B448F3F2A91DBC5A766FCDDBE
4B2460A466F95FD40113BCDCCA2CEB29B3B093921DE45474DA7DF48874C630B1
4DED6F955374E40B8558A611A9719B2AB69AA6852AC50966EDC4B07DE4D4277C
50E71B08B9AC407B93D50EE90100CB6B6B41C956DC7AA86C5BAA38AE713CFD6A
558EC6CA13DA9B800FEDC9ACC3C18CA98BB19768F1309B60B5BB89793B3481CB
579480AEA166290BD3C643589E795FC0D0E54E86505D180F1DFF99EFD3199512
59CC5FD35A737B84682EDA26AD23F5ADE8AA847D5BEB3B38AB6CD62347925A66
5D8FC3ECDDB4DDB243AEE5C306BCFDE670ADF2D66B193DD3AA2D6B2FB91869BE
5F1DED4DD590AF74631290CF073B122A2AAC6A1FA479778A0BD43579BD832699
62B7F9868263F72F6911FC78CEAF72C1979158B7368BF648683BB2AA39B02E72
7485B51C0ED192878FA1D2F948FB529AE1842CC5086C4B67F7BE5B2039DE9489
75D8853BE99C87678E6C7BF9F684B31454D81DEB1C7F37B9FBC026A268337536
7BA62FEC54E9D040556FCA70A6A88F03761C178FA1F7CB8390A73076849F55A2
84112972B8E59D14560AE7E7119654474AAD119990CF3722BFC1E3B91615E1FD
8F580C6E34CEE7EE57B93BA9C0AC5FAEDD7BF3085F5EE9C6C0175A2555B111D0
8FED925362F62FFF90DD835BE6ADC32B02DEC8DF5E82D83E512F1C977D066E82
912A48745BFF2F14D1798B27858613DE1C0EB03C2BDE630AFD0DDD5251E1EBE1
98B896625C0C230ADEEC3EB2CF6AAD5001ECF9156A68644E82374CE5833BC25B
9E39DE2881273ACC225A149C72BA3E0F51424963669AB633EE1DC7DF5DB067B4
9E7617035CFF537C837E078A7CDC7FD9EB77BCE7DDF3DC6DBD5C50AAFC1F1FA7
A0ED2032C5249EE1A653F1F88005D9E779E385DF533B5C521137CEE5176CD7FC
A104B1314DF8E02F7DE27DDC287D0961D6E6824AD4DAFC3D11064F24C1B653D5
A4328E058C867AF9CA8D468C388B72C250CE84BDB6BAF7F8C47C9A0B1CB35EEC
A496E23AC0CAB8155FC9B117B97EAE368EFCBB9041AEC8804D5A308D2D01C2D8
A4B72DBD37256324B557B9176F8CBA4310DDFFBCC4609977E2463F3504A716C8
A61FE79B019062DD3C6420BC20EAF64702CC1063C546A084DD0A0BCB915A14A9
AB7292F82267333031F512379FDBADA949DFA49D3C046CC8FA7F34117C342986
B7121039CAF13E03E52507F42DB56FA802FF119DA7591ABA8A2E842133DB7C9C
B75104427B6A5BE55033AF50DC0FE3102181BE130E761D487A4E8178C93317DD
C5F1531C6331659C75A6411A088A65DAD7518FD91F57B64537A651B6DCD76AE0
C65CBC98295549BA940494A6214B9706E7115E64F3FE269412C5B48AEACB2222
C93F7B1EEF27CFD0F227DFE3F057D63833533890B7230B1821A424BD40848E33
CB6E15165AC802E9B3F993F16C25D41F4E81C21EBDE71AE1B012AC00BF9C7C3F
CD740652E552D93EE64D7C9D1CC25228E466895889CEE25A11C962AB09906978
D8A50FA0068E9558E6C3BEE18CDB03B7EECBC3C56C1B2336B98AEE11644994B8
E7568FE6E12331F4FD7DE61DA4C7559D0F8EB192A218D4741A3BA75184333838
EF34030C01B13BF42B534072DCC3C75B13C009DC9241119ADA39E2C15E2AFD2E
FD9D5C2DBBD4995AB69B8D50C439D9527B00529199C2FD01B2174EB58F07021F
Loading
Loading