From c17311fc6a5b0110712a12fe7b02503d21fe72bf Mon Sep 17 00:00:00 2001 From: SoonHin Khor Date: Wed, 21 Oct 2026 04:19:48 +0000 Subject: [PATCH 1/2] fix: update action runtime and distrust compromised CA chains Build the checked-in Dockerfile with maintained Ruby and a minimum Debian CA security update, rather than pulling the stale prebuilt action image. Add offline trust regression checks and CI, preserving package glob expansion. Amp-Thread-ID: https://ampcode.com/threads/T-6032f029-f131-44a8-84a8-b880691cc1b4 Co-authored-by: Amp --- .github/workflows/test.yml | 21 +++++++++++++ Dockerfile | 32 ++++++++------------ Dockerfile.bullseye | 21 ------------- README.md | 26 +++++++++++++++- action.yml | 2 +- entrypoint-bullseye.sh | 13 -------- entrypoint.sh | 12 +++++--- test/fixtures/emudhra-aaa.pem | 38 ++++++++++++++++++++++++ test/fixtures/emudhra.pem | 56 +++++++++++++++++++++++++++++++++++ test/verify-trust.rb | 33 +++++++++++++++++++++ 10 files changed, 194 insertions(+), 60 deletions(-) create mode 100644 .github/workflows/test.yml delete mode 100644 Dockerfile.bullseye delete mode 100755 entrypoint-bullseye.sh create mode 100644 test/fixtures/emudhra-aaa.pem create mode 100644 test/fixtures/emudhra.pem create mode 100644 test/verify-trust.rb diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..19f2efe --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,21 @@ +name: Test action image + +on: + pull_request: + push: + branches: [master] + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Build with updated certificates + run: docker build --pull -t packagecloud-action:test . + - name: Verify runtime certificate trust + run: docker run --rm --entrypoint ruby -v "$PWD/test:/test:ro" packagecloud-action:test /test/verify-trust.rb + - name: Verify CLI starts + run: docker run --rm --entrypoint package_cloud packagecloud-action:test version diff --git a/Dockerfile b/Dockerfile index e56ce3c..27742ae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,26 +1,18 @@ -FROM ubuntu:focal -SHELL ["/bin/bash", "-l", "-c"] +FROM ruby:3.4-slim-bookworm -RUN apt-get update +# Debian's security update removes both emSign ECC Root CA - G3 and +# AAA Certificate Services, covering the compromised intermediates' cross-signs. +# https://security-tracker.debian.org/tracker/DLA-4845-1 +RUN apt-get update \ + && apt-get install -y --no-install-recommends ca-certificates build-essential \ + && dpkg --compare-versions "$(dpkg-query -W -f='${Version}' ca-certificates)" ge '20250419~deb12u2' \ + && update-ca-certificates \ + && rm -rf /var/lib/apt/lists/* -# Required to download things from internet -RUN apt-get install -y curl +ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt \ + SSL_CERT_DIR=/etc/ssl/certs -# Install build tools required for building native extensions -RUN apt-get install -y build-essential +RUN gem install package_cloud --version 0.3.15 --no-document -# Required for apt-add-repository -RUN DEBIAN_FRONTEND=noninteractive apt-get install -y software-properties-common - -# Install rvm -RUN gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB -RUN curl -sSL https://get.rvm.io | bash -s stable --ruby -RUN source /usr/local/rvm/scripts/rvm -RUN rvm install 2.7.5 -RUN rvm use 2.7.5 && gem install package_cloud - -# Copies your code file from your action repository to the filesystem path `/` of the container COPY entrypoint.sh /entrypoint.sh - -# Code file to execute when the docker container starts up (`entrypoint.sh`) ENTRYPOINT ["/entrypoint.sh"] diff --git a/Dockerfile.bullseye b/Dockerfile.bullseye deleted file mode 100644 index 249fa30..0000000 --- a/Dockerfile.bullseye +++ /dev/null @@ -1,21 +0,0 @@ -FROM ruby:3.0.4-bullseye - -RUN apt-get update - -# Required to download things from internet -RUN apt-get install -y curl - -# Install build tools required for building native extensions -RUN apt-get install -y build-essential - -# Required for apt-add-repository -RUN DEBIAN_FRONTEND=noninteractive apt-get install -y software-properties-common - -# Install package_cloud -RUN gem install package_cloud - -# Copies your code file from your action repository to the filesystem path `/` of the container -COPY entrypoint-bullseye.sh /entrypoint-bullseye.sh - -# Code file to execute when the docker container starts up (`entrypoint.sh`) -ENTRYPOINT ["/entrypoint-bullseye.sh"] diff --git a/README.md b/README.md index bb5b6a2..cdd45cb 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ jobs: ##### MODIFY: Add steps to build package or copy package to github action container ##### so it is available to github action to upload to packagecloud - name: push package to packagecloud.io - uses: computology/packagecloud-github-action + uses: computology/packagecloud-github-action@master with: ##### MODIFY: Change to packagecloud username, reponame, distro type ##### To understand the available distro type, see @@ -58,6 +58,30 @@ jobs: PACKAGECLOUD-TOKEN: ${{ secrets.packagecloud_token }} ``` +### Runtime and certificate updates + +The action builds the checked-in Dockerfile on the GitHub runner instead of +pulling the old prebuilt Docker Hub image. This adds image-build time to each +workflow run, but ensures the action uses the runtime and certificate policy in +the selected Git revision. Prefer pinning a reviewed full commit SHA or release +containing this change rather than the moving `master` example above. Existing +older action tags still reference the old image and do not receive this fix. + +The image uses Ruby 3.4 and Debian Bookworm's system certificate store. Builds +require `ca-certificates` version `20250419~deb12u2` or newer, which removes trust +in `emSign ECC Root CA - G3` and `AAA Certificate Services` following the +[eMudhra intermediate CA compromise](https://emudhra.we-have-a-problem.com/). +Certificate and hostname verification remain enabled; the action does not add a +custom certificate blocklist or modify the runner host's trust store. + +To build and check the image locally without uploading a package: + +```bash +docker build --pull -t packagecloud-action:test . +docker run --rm --entrypoint ruby -v "$PWD/test:/test:ro" packagecloud-action:test /test/verify-trust.rb +docker run --rm --entrypoint package_cloud packagecloud-action:test version +``` + ## Example * https://github.com/computology/python-github-action-example diff --git a/action.yml b/action.yml index 93610e6..d19b86c 100644 --- a/action.yml +++ b/action.yml @@ -21,7 +21,7 @@ inputs: required: true runs: using: 'docker' - image: 'docker://packagecloud/packagecloud-github-action:0.0.2' + image: 'Dockerfile' env: PACKAGE_NAME: ${{ inputs.package-name }} PACKAGECLOUD_USERNAME: ${{ inputs.packagecloud-username }} diff --git a/entrypoint-bullseye.sh b/entrypoint-bullseye.sh deleted file mode 100755 index e0ce367..0000000 --- a/entrypoint-bullseye.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -l - -echo "PACKAGECLOUD_USERNAME=${PACKAGECLOUD_USERNAME}" -echo "PACKAGECLOUD_REPONAME=${PACKAGECLOUD_REPONAME}" -echo "PACKAGECLOUD_DISTRO=${PACKAGECLOUD_DISTRO}" -echo "PACKAGE_NAME=${PACKAGE_NAME}" - -UPLOAD_PATH="${PACKAGECLOUD_USERNAME}/${PACKAGECLOUD_REPONAME}/${PACKAGECLOUD_DISTRO}" - -echo "Pushing package: ${PACKAGE_NAME}" -echo "To repository: ${UPLOAD_PATH}" - -/usr/local/bundle/bin/package_cloud push ${UPLOAD_PATH} ${PACKAGE_NAME} diff --git a/entrypoint.sh b/entrypoint.sh index ec6d375..253485a 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,6 +1,9 @@ -#!/bin/bash -l +#!/bin/bash -echo "PACKAGECLOUD_REPO=${PACKAGECLOUD_REPO}" +set -euo pipefail + +echo "PACKAGECLOUD_USERNAME=${PACKAGECLOUD_USERNAME}" +echo "PACKAGECLOUD_REPONAME=${PACKAGECLOUD_REPONAME}" echo "PACKAGECLOUD_DISTRO=${PACKAGECLOUD_DISTRO}" echo "PACKAGE_NAME=${PACKAGE_NAME}" @@ -9,5 +12,6 @@ UPLOAD_PATH="${PACKAGECLOUD_USERNAME}/${PACKAGECLOUD_REPONAME}/${PACKAGECLOUD_DI echo "Pushing package: ${PACKAGE_NAME}" echo "To repository: ${UPLOAD_PATH}" -source /usr/local/rvm/scripts/rvm -rvm use 2.7.5 && package_cloud push ${UPLOAD_PATH} ${PACKAGE_NAME} +# Expand package patterns such as dist/*.tar.gz, as in the action's documented use. +# shellcheck disable=SC2086 +exec package_cloud push "$UPLOAD_PATH" ${PACKAGE_NAME} diff --git a/test/fixtures/emudhra-aaa.pem b/test/fixtures/emudhra-aaa.pem new file mode 100644 index 0000000..10f6cbd --- /dev/null +++ b/test/fixtures/emudhra-aaa.pem @@ -0,0 +1,38 @@ +-----BEGIN CERTIFICATE----- +MIICQDCCAcagAwIBAgIUU3mgjls/8ZJ8upmukdlSQR1IF/UwCgYIKoZIzj0EAwIw +PzELMAkGA1UEBhMCTkwxEzARBgNVBAoMCmVNdWRocmEgQlYxGzAZBgNVBAMMEkVN +IERWIFRMUyBDQSAtIEczQjAeFw0yNjEwMjAwMjIyNDFaFw0yNzA1MDMwMjI3NDFa +MDMxMTAvBgNVBAMMKGR2LWczYi1hYWEtZW11ZGhyYS53ZS1oYXZlLWEtcHJvYmxl +bS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATK3sfcOxxtM2Vdq9Qbw/GR +NsHlJcnqINEInXO3fkWhw/FYT80hkqGk0jSN/EKib3YZJsr5GyfkYcpEiA2rwMgm +o4GrMIGoMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoG +CCsGAQUFBwMBMDMGA1UdEQQsMCqCKGR2LWczYi1hYWEtZW11ZGhyYS53ZS1oYXZl +LWEtcHJvYmxlbS5jb20wHQYDVR0OBBYEFDggfJFz1eeToKmzFBSYkMCvpAu0MB8G +A1UdIwQYMBaAFOIeL+ccGTkOVUtiwSAkVzUkiiUUMAoGCCqGSM49BAMCA2gAMGUC +MDqDDOt7K313QIH0rhn/ZKnzFu8+/9W8OlTuFtDfVCTRDfRmqdyfsCfLsEk7xqHq +uQIxAJqyLERABmU98U46OCuT5bp5h0ytuSEIGM7orTpKci5S1u1B/AOmwv162U7R +TcVPHA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDzjCCAragAwIBAgIRAKAk/fS6Zlx4XOSgIEg4WLcwDQYJKoZIhvcNAQELBQAw +ezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV +BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0yNTA1MTQwMDAwMDBaFw0y +ODEyMzEyMzU5NTlaMD8xCzAJBgNVBAYTAk5MMRMwEQYDVQQKDAplTXVkaHJhIEJW +MRswGQYDVQQDDBJFTSBEViBUTFMgQ0EgLSBHM0IwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAATnntnASpdzxHNeUREdqFrCvV5kqzdLgOEsvCA47B5PDjuBL8mFnh5nr7BO +L4vJf3SFumWqkR7opORbYtXMA9Vr5nizw4y03JN8okYOI4RTyJKTXSnUT5HhVga2 +PM7atGijggE1MIIBMTAfBgNVHSMEGDAWgBSgEQojPpbxB+zirynvgqV/0DCktDAd +BgNVHQ4EFgQU4h4v5xwZOQ5VS2LBICRXNSSKJRQwDgYDVR0PAQH/BAQDAgEGMBIG +A1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC +MDEGA1UdIAQqMCgwCAYGZ4EMAQIBMA0GCysGAQQBg44hAQABMA0GCysGAQQBg44h +AQJkMEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL0FB +QUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEF +BQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMA0GCSqGSIb3DQEBCwUAA4IB +AQBzQ1IoqpdotM6gFrR4Q3YrKifOLeaj5XXunldpVE/vZn2TxC2y0s8oYiLR5ICE +wqVXSB7N6BM1Mp+Nif7Jbhb2IswAfSR4Iik8+B0iRmi7lYoNlycCgHjmsjOmZaxM +QkPmjXAJbG5f4V41OsvJZmS7lI3r0IuvEDVX3GAZ13on6IImSs9ybNpHQ7NCqkMQ +7wH4uAO1dtpFycgJSdHaCOhHjrox2BTYGLdpUrYwY3EOAjlZ8UGgsxs7mG+xquMl +bN1LFURwfnkVMP3T/DBIZ/ys2+lNFyxK3FlArrV4/000uTnVB1lO8oGORYdXoT5V +GUyRCEIDhF5TBUuKF4E3kf1h +-----END CERTIFICATE----- diff --git a/test/fixtures/emudhra.pem b/test/fixtures/emudhra.pem new file mode 100644 index 0000000..ad8f25d --- /dev/null +++ b/test/fixtures/emudhra.pem @@ -0,0 +1,56 @@ +-----BEGIN CERTIFICATE----- +MIICOTCCAb6gAwIBAgIUY1R/PHrtXShV0uhLJ5EyjsHvMi0wCgYIKoZIzj0EAwIw +PzELMAkGA1UEBhMCTkwxEzARBgNVBAoMCmVNdWRocmEgQlYxGzAZBgNVBAMMEkVN +IERWIFRMUyBDQSAtIEczQjAeFw0yNjEwMjAwMDU5MzZaFw0yNzA1MDMwMTA0MzZa +MC8xLTArBgNVBAMMJGR2LWczYi1lbXVkaHJhLndlLWhhdmUtYS1wcm9ibGVtLmNv +bTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFpE24ACBFHQLzpg+7D767thJ3+Q +NIoJJugUMT/OftEz6G6uDdxlS+9VfXYBDglHjJirjEPFNglOGJoQNQuiz7Gjgacw +gaQwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYB +BQUHAwEwLwYDVR0RBCgwJoIkZHYtZzNiLWVtdWRocmEud2UtaGF2ZS1hLXByb2Js +ZW0uY29tMB0GA1UdDgQWBBT4r5v4etYNuG21BqBqs273OkcHiDAfBgNVHSMEGDAW +gBTiHi/nHBk5DlVLYsEgJFc1JIolFDAKBggqhkjOPQQDAgNpADBmAjEAlxNF+/8l +APpgibawACy15yn5bcvTksz2Zw0R9z9nUK9e3MSSk+hXagg7LVb7V4NtAjEA4qyR +laFPkaokrnTjqQieq8CgDQ6tIz3FjBvj3D7vkhKXHaml6zD2zT5ih2Y+lD2h +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDaDCCAu6gAwIBAgIQAKSu5njyM2K0wORgt3LyFDAKBggqhkjOPQQDAzBWMQsw +CQYDVQQGEwJJTjElMCMGA1UECgwcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRl +ZDEgMB4GA1UEAwwXZW1TaWduIFJvb3QgVExTIENBIC0gRzMwHhcNMjUwNDMwMTU1 +NDA4WhcNNDAwNDI4MTgzMDAwWjA/MQswCQYDVQQGEwJOTDETMBEGA1UECgwKZU11 +ZGhyYSBCVjEbMBkGA1UEAwwSRU0gRFYgVExTIENBIC0gRzNCMHYwEAYHKoZIzj0C +AQYFK4EEACIDYgAE557ZwEqXc8RzXlERHahawr1eZKs3S4DhLLwgOOweTw47gS/J +hZ4eZ6+wTi+LyX90hbplqpEe6KTkW2LVzAPVa+Z4s8OMtNyTfKJGDiOEU8iSk10p +1E+R4VYGtjzO2rRoo4IBljCCAZIwHwYDVR0jBBgwFoAU4TqrIXzx401UrtRyt/2L +WUIgkFQwHQYDVR0OBBYEFOIeL+ccGTkOVUtiwSAkVzUkiiUUMB0GA1UdJQQWMBQG +CCsGAQUFBwMBBggrBgEFBQcDAjBdBgNVHSAEVjBUMDkGCysGAQQBg44hAQABMCow +KAYIKwYBBQUHAgEWHGh0dHA6Ly9yZXBvc2l0b3J5LmVtc2lnbi5jb20wDQYLKwYB +BAGDjiEBAmQwCAYGZ4EMAQIBMHUGCCsGAQUFBwEBBGkwZzAkBggrBgEFBQcwAYYY +aHR0cDovL29jc3AtYi5lbXNpZ24uY29tMD8GCCsGAQUFBzAChjNodHRwOi8vcmVw +b3NpdG9yeS5lbXNpZ24uY29tL2NlcnRzL0VNRFZUTFNDQUczQi5wN2MwNwYDVR0f +BDAwLjAsoCqgKIYmaHR0cDovL2NybC5lbXNpZ24uY29tLz9yb290dGxzY2FnMy5j +cmwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwCgYIKoZIzj0E +AwMDaAAwZQIwLmsGXi6oFMJ2klkcEMXMug6gvxQWZWkewiDWVzQyl2L6z6DuQfPO +Ibh1grvdULDCAjEAxZvLlxUavG69J6wnSjC8XBbqNIQsJ6CE2QdNOe84Ptxb6VG8 +gt2TlfJbHii+KNvK +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDdDCCAvmgAwIBAgIQAJYaPvsTWVdu0EAFtGhKWzAKBggqhkjOPQQDAzBrMQsw +CQYDVQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhy +YSBUZWNobm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290 +IENBIC0gRzMwHhcNMjQwNzExMTU0MzM2WhcNMzkwNzA5MTgzMDAwWjBWMQswCQYD +VQQGEwJJTjElMCMGA1UECgwcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEg +MB4GA1UEAwwXZW1TaWduIFJvb3QgVExTIENBIC0gRzMwdjAQBgcqhkjOPQIBBgUr +gQQAIgNiAARfD9w/q1cWxL6D9bMGH6CQ4u+gAV6GN9s+PwQx9Bl4hC+0iU8QOk8m +WO/RwXQy10DCSxT8vSIJClHKp+Ao4qJKdYeV0SwZ7LMQziyLfxIUOY6Grja/sQFw +LKYf8EdDXAyjggF1MIIBcTAfBgNVHSMEGDAWgBR8XQKEE9TMipuBzhccLikenEhj +QjAdBgNVHQ4EFgQU4TqrIXzx401UrtRyt/2LWUIgkFQwHQYDVR0lBBYwFAYIKwYB +BQUHAwEGCCsGAQUFBwMCMD0GA1UdIAQ2MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIB +FhxodHRwOi8vcmVwb3NpdG9yeS5lbXNpZ24uY29tMHgGCCsGAQUFBwEBBGwwajAi +BggrBgEFBQcwAYYWaHR0cDovL29jc3AuZW1zaWduLmNvbTBEBggrBgEFBQcwAoY4 +aHR0cDovL3JlcG9zaXRvcnkuZW1zaWduLmNvbS9jZXJ0cy9lbVNpZ25FQ0NSb290 +Q0FHMy5jcnQwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbXNpZ24uY29t +P1Jvb3RDQUczLmNybDAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIB +ATAKBggqhkjOPQQDAwNpADBmAjEAt9CIpRGp46QHQYDUBnLKw+vvK0/h9vmilEAg +TroUl/anH4x2rXHqiCtBTBfgKDegAjEA8WpG1LTZdAIL0FSYqxXeREaeTSxEofM0 +1jJH3jGvCXC79LU9UPJ2o3TU+UIj2gMV +-----END CERTIFICATE----- diff --git a/test/verify-trust.rb b/test/verify-trust.rb new file mode 100644 index 0000000..1f6ee38 --- /dev/null +++ b/test/verify-trust.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require "openssl" + +store = OpenSSL::X509::Store.new +store.set_default_paths +store.purpose = OpenSSL::X509::PURPOSE_SSL_SERVER + +# Keep the published probe certificates within their validity period so that +# expiration cannot hide a regression that restores trust in their issuers. +store.time = Time.utc(2026, 10, 21) + +# Public probe chains from https://emudhra.we-have-a-problem.com/chains.zip, +# captured on October 20, 2026. Cover both the emSign and Sectigo trust paths. +%w[emudhra.pem emudhra-aaa.pem].each do |filename| + path = File.join(__dir__, "fixtures", filename) + chain = File.read(path).scan(/-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----/m).map do |pem| + OpenSSL::X509::Certificate.new(pem) + end + + accepted = store.verify(chain.first, chain.drop(1)) + unless !accepted && store.error == OpenSSL::X509::V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY + abort "FAIL: #{File.basename(path)}: accepted=#{accepted}, #{store.error_string}" + end + puts "PASS: #{File.basename(path)} rejected because its issuer is untrusted" +end + +# A missing or empty trust store must not make the rejection checks pass. +amazon_root = OpenSSL::X509::Certificate.new( + File.read("/usr/share/ca-certificates/mozilla/Amazon_Root_CA_1.crt") +) +abort "FAIL: Amazon Root CA 1 is no longer trusted" unless store.verify(amazon_root) +puts "PASS: Amazon Root CA 1 remains trusted" From 45d4ca8017459fabd0b2940771b739493da31ab1 Mon Sep 17 00:00:00 2001 From: nethsix Date: Wed, 21 Oct 2026 14:24:52 +0900 Subject: [PATCH 2/2] Remove incident-specific certificate regression test Keep image-build and CLI-startup checks, and remove the certificate fixtures and their documentation references. --- .github/workflows/test.yml | 2 -- README.md | 1 - test/fixtures/emudhra-aaa.pem | 38 ------------------------ test/fixtures/emudhra.pem | 56 ----------------------------------- test/verify-trust.rb | 33 --------------------- 5 files changed, 130 deletions(-) delete mode 100644 test/fixtures/emudhra-aaa.pem delete mode 100644 test/fixtures/emudhra.pem delete mode 100644 test/verify-trust.rb diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 19f2efe..5afa8cd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,5 @@ jobs: - uses: actions/checkout@v4 - name: Build with updated certificates run: docker build --pull -t packagecloud-action:test . - - name: Verify runtime certificate trust - run: docker run --rm --entrypoint ruby -v "$PWD/test:/test:ro" packagecloud-action:test /test/verify-trust.rb - name: Verify CLI starts run: docker run --rm --entrypoint package_cloud packagecloud-action:test version diff --git a/README.md b/README.md index cdd45cb..bdf7c76 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,6 @@ To build and check the image locally without uploading a package: ```bash docker build --pull -t packagecloud-action:test . -docker run --rm --entrypoint ruby -v "$PWD/test:/test:ro" packagecloud-action:test /test/verify-trust.rb docker run --rm --entrypoint package_cloud packagecloud-action:test version ``` diff --git a/test/fixtures/emudhra-aaa.pem b/test/fixtures/emudhra-aaa.pem deleted file mode 100644 index 10f6cbd..0000000 --- a/test/fixtures/emudhra-aaa.pem +++ /dev/null @@ -1,38 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICQDCCAcagAwIBAgIUU3mgjls/8ZJ8upmukdlSQR1IF/UwCgYIKoZIzj0EAwIw -PzELMAkGA1UEBhMCTkwxEzARBgNVBAoMCmVNdWRocmEgQlYxGzAZBgNVBAMMEkVN -IERWIFRMUyBDQSAtIEczQjAeFw0yNjEwMjAwMjIyNDFaFw0yNzA1MDMwMjI3NDFa -MDMxMTAvBgNVBAMMKGR2LWczYi1hYWEtZW11ZGhyYS53ZS1oYXZlLWEtcHJvYmxl -bS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATK3sfcOxxtM2Vdq9Qbw/GR -NsHlJcnqINEInXO3fkWhw/FYT80hkqGk0jSN/EKib3YZJsr5GyfkYcpEiA2rwMgm -o4GrMIGoMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoG -CCsGAQUFBwMBMDMGA1UdEQQsMCqCKGR2LWczYi1hYWEtZW11ZGhyYS53ZS1oYXZl -LWEtcHJvYmxlbS5jb20wHQYDVR0OBBYEFDggfJFz1eeToKmzFBSYkMCvpAu0MB8G -A1UdIwQYMBaAFOIeL+ccGTkOVUtiwSAkVzUkiiUUMAoGCCqGSM49BAMCA2gAMGUC -MDqDDOt7K313QIH0rhn/ZKnzFu8+/9W8OlTuFtDfVCTRDfRmqdyfsCfLsEk7xqHq -uQIxAJqyLERABmU98U46OCuT5bp5h0ytuSEIGM7orTpKci5S1u1B/AOmwv162U7R -TcVPHA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDzjCCAragAwIBAgIRAKAk/fS6Zlx4XOSgIEg4WLcwDQYJKoZIhvcNAQELBQAw -ezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV -BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0yNTA1MTQwMDAwMDBaFw0y -ODEyMzEyMzU5NTlaMD8xCzAJBgNVBAYTAk5MMRMwEQYDVQQKDAplTXVkaHJhIEJW -MRswGQYDVQQDDBJFTSBEViBUTFMgQ0EgLSBHM0IwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAATnntnASpdzxHNeUREdqFrCvV5kqzdLgOEsvCA47B5PDjuBL8mFnh5nr7BO -L4vJf3SFumWqkR7opORbYtXMA9Vr5nizw4y03JN8okYOI4RTyJKTXSnUT5HhVga2 -PM7atGijggE1MIIBMTAfBgNVHSMEGDAWgBSgEQojPpbxB+zirynvgqV/0DCktDAd -BgNVHQ4EFgQU4h4v5xwZOQ5VS2LBICRXNSSKJRQwDgYDVR0PAQH/BAQDAgEGMBIG -A1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC -MDEGA1UdIAQqMCgwCAYGZ4EMAQIBMA0GCysGAQQBg44hAQABMA0GCysGAQQBg44h -AQJkMEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL0FB -QUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEF -BQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMA0GCSqGSIb3DQEBCwUAA4IB -AQBzQ1IoqpdotM6gFrR4Q3YrKifOLeaj5XXunldpVE/vZn2TxC2y0s8oYiLR5ICE -wqVXSB7N6BM1Mp+Nif7Jbhb2IswAfSR4Iik8+B0iRmi7lYoNlycCgHjmsjOmZaxM -QkPmjXAJbG5f4V41OsvJZmS7lI3r0IuvEDVX3GAZ13on6IImSs9ybNpHQ7NCqkMQ -7wH4uAO1dtpFycgJSdHaCOhHjrox2BTYGLdpUrYwY3EOAjlZ8UGgsxs7mG+xquMl -bN1LFURwfnkVMP3T/DBIZ/ys2+lNFyxK3FlArrV4/000uTnVB1lO8oGORYdXoT5V -GUyRCEIDhF5TBUuKF4E3kf1h ------END CERTIFICATE----- diff --git a/test/fixtures/emudhra.pem b/test/fixtures/emudhra.pem deleted file mode 100644 index ad8f25d..0000000 --- a/test/fixtures/emudhra.pem +++ /dev/null @@ -1,56 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICOTCCAb6gAwIBAgIUY1R/PHrtXShV0uhLJ5EyjsHvMi0wCgYIKoZIzj0EAwIw -PzELMAkGA1UEBhMCTkwxEzARBgNVBAoMCmVNdWRocmEgQlYxGzAZBgNVBAMMEkVN -IERWIFRMUyBDQSAtIEczQjAeFw0yNjEwMjAwMDU5MzZaFw0yNzA1MDMwMTA0MzZa -MC8xLTArBgNVBAMMJGR2LWczYi1lbXVkaHJhLndlLWhhdmUtYS1wcm9ibGVtLmNv -bTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFpE24ACBFHQLzpg+7D767thJ3+Q -NIoJJugUMT/OftEz6G6uDdxlS+9VfXYBDglHjJirjEPFNglOGJoQNQuiz7Gjgacw -gaQwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYB -BQUHAwEwLwYDVR0RBCgwJoIkZHYtZzNiLWVtdWRocmEud2UtaGF2ZS1hLXByb2Js -ZW0uY29tMB0GA1UdDgQWBBT4r5v4etYNuG21BqBqs273OkcHiDAfBgNVHSMEGDAW -gBTiHi/nHBk5DlVLYsEgJFc1JIolFDAKBggqhkjOPQQDAgNpADBmAjEAlxNF+/8l -APpgibawACy15yn5bcvTksz2Zw0R9z9nUK9e3MSSk+hXagg7LVb7V4NtAjEA4qyR -laFPkaokrnTjqQieq8CgDQ6tIz3FjBvj3D7vkhKXHaml6zD2zT5ih2Y+lD2h ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDaDCCAu6gAwIBAgIQAKSu5njyM2K0wORgt3LyFDAKBggqhkjOPQQDAzBWMQsw -CQYDVQQGEwJJTjElMCMGA1UECgwcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRl -ZDEgMB4GA1UEAwwXZW1TaWduIFJvb3QgVExTIENBIC0gRzMwHhcNMjUwNDMwMTU1 -NDA4WhcNNDAwNDI4MTgzMDAwWjA/MQswCQYDVQQGEwJOTDETMBEGA1UECgwKZU11 -ZGhyYSBCVjEbMBkGA1UEAwwSRU0gRFYgVExTIENBIC0gRzNCMHYwEAYHKoZIzj0C -AQYFK4EEACIDYgAE557ZwEqXc8RzXlERHahawr1eZKs3S4DhLLwgOOweTw47gS/J -hZ4eZ6+wTi+LyX90hbplqpEe6KTkW2LVzAPVa+Z4s8OMtNyTfKJGDiOEU8iSk10p -1E+R4VYGtjzO2rRoo4IBljCCAZIwHwYDVR0jBBgwFoAU4TqrIXzx401UrtRyt/2L -WUIgkFQwHQYDVR0OBBYEFOIeL+ccGTkOVUtiwSAkVzUkiiUUMB0GA1UdJQQWMBQG -CCsGAQUFBwMBBggrBgEFBQcDAjBdBgNVHSAEVjBUMDkGCysGAQQBg44hAQABMCow -KAYIKwYBBQUHAgEWHGh0dHA6Ly9yZXBvc2l0b3J5LmVtc2lnbi5jb20wDQYLKwYB -BAGDjiEBAmQwCAYGZ4EMAQIBMHUGCCsGAQUFBwEBBGkwZzAkBggrBgEFBQcwAYYY -aHR0cDovL29jc3AtYi5lbXNpZ24uY29tMD8GCCsGAQUFBzAChjNodHRwOi8vcmVw -b3NpdG9yeS5lbXNpZ24uY29tL2NlcnRzL0VNRFZUTFNDQUczQi5wN2MwNwYDVR0f -BDAwLjAsoCqgKIYmaHR0cDovL2NybC5lbXNpZ24uY29tLz9yb290dGxzY2FnMy5j -cmwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwCgYIKoZIzj0E -AwMDaAAwZQIwLmsGXi6oFMJ2klkcEMXMug6gvxQWZWkewiDWVzQyl2L6z6DuQfPO -Ibh1grvdULDCAjEAxZvLlxUavG69J6wnSjC8XBbqNIQsJ6CE2QdNOe84Ptxb6VG8 -gt2TlfJbHii+KNvK ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDdDCCAvmgAwIBAgIQAJYaPvsTWVdu0EAFtGhKWzAKBggqhkjOPQQDAzBrMQsw -CQYDVQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhy -YSBUZWNobm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290 -IENBIC0gRzMwHhcNMjQwNzExMTU0MzM2WhcNMzkwNzA5MTgzMDAwWjBWMQswCQYD -VQQGEwJJTjElMCMGA1UECgwcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEg -MB4GA1UEAwwXZW1TaWduIFJvb3QgVExTIENBIC0gRzMwdjAQBgcqhkjOPQIBBgUr -gQQAIgNiAARfD9w/q1cWxL6D9bMGH6CQ4u+gAV6GN9s+PwQx9Bl4hC+0iU8QOk8m -WO/RwXQy10DCSxT8vSIJClHKp+Ao4qJKdYeV0SwZ7LMQziyLfxIUOY6Grja/sQFw -LKYf8EdDXAyjggF1MIIBcTAfBgNVHSMEGDAWgBR8XQKEE9TMipuBzhccLikenEhj -QjAdBgNVHQ4EFgQU4TqrIXzx401UrtRyt/2LWUIgkFQwHQYDVR0lBBYwFAYIKwYB -BQUHAwEGCCsGAQUFBwMCMD0GA1UdIAQ2MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIB -FhxodHRwOi8vcmVwb3NpdG9yeS5lbXNpZ24uY29tMHgGCCsGAQUFBwEBBGwwajAi -BggrBgEFBQcwAYYWaHR0cDovL29jc3AuZW1zaWduLmNvbTBEBggrBgEFBQcwAoY4 -aHR0cDovL3JlcG9zaXRvcnkuZW1zaWduLmNvbS9jZXJ0cy9lbVNpZ25FQ0NSb290 -Q0FHMy5jcnQwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbXNpZ24uY29t -P1Jvb3RDQUczLmNybDAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIB -ATAKBggqhkjOPQQDAwNpADBmAjEAt9CIpRGp46QHQYDUBnLKw+vvK0/h9vmilEAg -TroUl/anH4x2rXHqiCtBTBfgKDegAjEA8WpG1LTZdAIL0FSYqxXeREaeTSxEofM0 -1jJH3jGvCXC79LU9UPJ2o3TU+UIj2gMV ------END CERTIFICATE----- diff --git a/test/verify-trust.rb b/test/verify-trust.rb deleted file mode 100644 index 1f6ee38..0000000 --- a/test/verify-trust.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -require "openssl" - -store = OpenSSL::X509::Store.new -store.set_default_paths -store.purpose = OpenSSL::X509::PURPOSE_SSL_SERVER - -# Keep the published probe certificates within their validity period so that -# expiration cannot hide a regression that restores trust in their issuers. -store.time = Time.utc(2026, 10, 21) - -# Public probe chains from https://emudhra.we-have-a-problem.com/chains.zip, -# captured on October 20, 2026. Cover both the emSign and Sectigo trust paths. -%w[emudhra.pem emudhra-aaa.pem].each do |filename| - path = File.join(__dir__, "fixtures", filename) - chain = File.read(path).scan(/-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----/m).map do |pem| - OpenSSL::X509::Certificate.new(pem) - end - - accepted = store.verify(chain.first, chain.drop(1)) - unless !accepted && store.error == OpenSSL::X509::V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY - abort "FAIL: #{File.basename(path)}: accepted=#{accepted}, #{store.error_string}" - end - puts "PASS: #{File.basename(path)} rejected because its issuer is untrusted" -end - -# A missing or empty trust store must not make the rejection checks pass. -amazon_root = OpenSSL::X509::Certificate.new( - File.read("/usr/share/ca-certificates/mozilla/Amazon_Root_CA_1.crt") -) -abort "FAIL: Amazon Root CA 1 is no longer trusted" unless store.verify(amazon_root) -puts "PASS: Amazon Root CA 1 remains trusted"