Skip to content
Merged
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
31 changes: 8 additions & 23 deletions scripts/ci/_common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3701,27 +3701,19 @@ verify_windows_authenticode_signatures() {
printf '%s\n' "$(to_windows_path "${file}")" >> "${files_manifest}"
done

# Keep the expected identity fields and file list in the environment. Passing
# Keep the expected identity field and file list in the environment. Passing
# them as positional args through Git Bash into pwsh can split values that
# contain spaces. Microsoft Trusted Signing can issue from multiple numbered
# ID-verified code-signing CAs, so the default verifies the issuer family
# instead of pinning one rotating CA number.
# contain spaces. Get-AuthenticodeSignature validates the certificate chain;
# this check only asserts that the trusted signer identity is ours.
# shellcheck disable=SC2016
if ! MAPLE_WINDOWS_AUTHENTICODE_FILES="$(to_windows_path "${files_manifest}")" \
MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_CN="${expected_cn}" \
Comment on lines +3704 to 3710

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Keep issuer-family validation while allowing EOC.

This now accepts any Status=Valid Authenticode certificate with the same subject CN, not specifically the Microsoft Trusted Signing AOC/EOC CA family described by the PR objective. Reintroduce a configurable issuer-family regex that accepts both AOC and EOC instead of dropping issuer validation entirely.

🛡️ Proposed fix
   local expected_cn
+  local expected_issuer_pattern
   expected_cn="${MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_CN:-Mutiny Wallet Inc. dba OpenSecret}"
+  expected_issuer_pattern="${MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_ISSUER_PATTERN:-(^|,\s*)CN=Microsoft ID Verified CS (AOC|EOC) CA [0-9]+(\s*,|$)}"
@@
-  # Keep the expected identity field and file list in the environment. Passing
+  # Keep the expected identity fields and file list in the environment. Passing
@@
   if ! MAPLE_WINDOWS_AUTHENTICODE_FILES="$(to_windows_path "${files_manifest}")" \
     MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_CN="${expected_cn}" \
+    MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_ISSUER_PATTERN="${expected_issuer_pattern}" \
     pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -Command '
@@
     $expectedCn = $env:MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_CN
+    $expectedIssuerPattern = $env:MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_ISSUER_PATTERN
@@
     if ([string]::IsNullOrWhiteSpace($expectedCn)) {
       throw "MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_CN is required to verify the Windows signer identity."
     }
+    if ([string]::IsNullOrWhiteSpace($expectedIssuerPattern)) {
+      throw "MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_ISSUER_PATTERN is required to verify the Windows signer issuer."
+    }
@@
       $expectedCnPattern = "(^|,\s*)CN=$([regex]::Escape($expectedCn))(\s*,|$)"
       if (-not [regex]::IsMatch($subject, $expectedCnPattern)) {
         throw "Authenticode signer subject CN mismatch for $file. Actual=$subject Issuer=$issuer"
       }
+      if (-not [regex]::IsMatch($issuer, $expectedIssuerPattern)) {
+        throw "Authenticode signer issuer mismatch for $file. Subject=$subject Issuer=$issuer"
+      }

Also applies to: 3735-3737

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/ci/_common.sh` around lines 3704 - 3710, The Authenticode check in
the Windows signature validation flow is dropping issuer-family validation and
only matching the subject CN, which is too broad. Update the signature
verification logic around the existing Get-AuthenticodeSignature check in the
shell script to keep a configurable issuer-family regex, and make it accept both
AOC and EOC certificate families instead of removing issuer validation. Use the
existing identity/file environment setup and the validation branch that compares
the signer certificate so the fix stays localized.

MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_ISSUER="${MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_ISSUER:-}" \
MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_ISSUER_PATTERN="${MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_ISSUER_PATTERN:-^CN=Microsoft ID Verified CS AOC CA [0-9]+,\s*O=Microsoft Corporation,\s*C=US$}" \
pwsh -NoLogo -NoProfile -ExecutionPolicy Bypass -Command '
Comment on lines +3704 to 3711

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🚩 Removal of issuer verification reduces defense-in-depth for code signing identity

The old code verified both the subject CN AND the issuer (either by exact match or regex pattern against Microsoft's Trusted Signing CA hierarchy). The new code only verifies the subject CN, relying on Get-AuthenticodeSignature's Status -eq 'Valid' check for chain validation. While Get-AuthenticodeSignature does validate the certificate chain against the Windows trust store, the explicit issuer check previously provided an additional layer: even if a different trusted CA issued a certificate with the same CN (unlikely but possible in certificate misissuance scenarios), the old code would reject it. The comment at scripts/ci/_common.sh:3706-3707 explains the rationale ('Get-AuthenticodeSignature validates the certificate chain; this check only asserts that the trusted signer identity is ours'), which is a reasonable security trade-off given that Microsoft Trusted Signing rotates intermediate CA numbers. This is a deliberate security posture simplification rather than a bug.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

$ErrorActionPreference = "Stop"
$expectedCn = $env:MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_CN
if ([string]::IsNullOrWhiteSpace($expectedCn)) {
throw "MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_CN is required to verify the Windows signer identity."
}
$expectedIssuer = $env:MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_ISSUER
$expectedIssuerPattern = $env:MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_ISSUER_PATTERN
if ([string]::IsNullOrWhiteSpace($expectedIssuer) -and [string]::IsNullOrWhiteSpace($expectedIssuerPattern)) {
throw "MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_ISSUER or MAPLE_WINDOWS_AUTHENTICODE_EXPECTED_ISSUER_PATTERN is required to verify the Windows signer identity."
}
$filesManifest = $env:MAPLE_WINDOWS_AUTHENTICODE_FILES
if ([string]::IsNullOrWhiteSpace($filesManifest)) {
throw "MAPLE_WINDOWS_AUTHENTICODE_FILES is required to verify Windows signed artifacts."
Expand All @@ -3735,23 +3727,16 @@ verify_windows_authenticode_signatures() {
if ($signature.Status -ne "Valid") {
throw "Authenticode signature is not valid for $file. Status=$($signature.Status) Message=$($signature.StatusMessage)"
}
$subject = ""
$issuer = ""
if ($null -ne $signature.SignerCertificate) {
$subject = $signature.SignerCertificate.Subject
$issuer = $signature.SignerCertificate.Issuer
}
if (-not [string]::IsNullOrWhiteSpace($expectedIssuer) -and $issuer -ne $expectedIssuer) {
throw "Authenticode signer issuer mismatch for $file. ActualIssuer=$issuer Subject=$subject"
}
if ([string]::IsNullOrWhiteSpace($expectedIssuer) -and -not [regex]::IsMatch($issuer, $expectedIssuerPattern)) {
throw "Authenticode signer issuer pattern mismatch for $file. ActualIssuer=$issuer Subject=$subject"
if ($null -eq $signature.SignerCertificate) {
throw "Authenticode signature is valid but no signer certificate was returned for $file."
}
$subject = $signature.SignerCertificate.Subject
$issuer = $signature.SignerCertificate.Issuer
$expectedCnPattern = "(^|,\s*)CN=$([regex]::Escape($expectedCn))(\s*,|$)"
if (-not [regex]::IsMatch($subject, $expectedCnPattern)) {
throw "Authenticode signer subject CN mismatch for $file. Actual=$subject Issuer=$issuer"
}
Write-Output ("verified-windows-authenticode {0} thumbprint={1}" -f $file, $signature.SignerCertificate.Thumbprint)
Write-Output ("verified-windows-authenticode {0} subject={1} issuer={2} thumbprint={3}" -f $file, $subject, $issuer, $signature.SignerCertificate.Thumbprint)
}
'; then
rm -f "${files_manifest}"
Expand Down
Loading