Skip to content

Commit 747fc39

Browse files
committed
Add catalog signing for .js files for VS signing compliance
The .js files in the Emscripten SDK are customer-modifiable toolchain files that cannot be directly Authenticode-signed (modifying a signed file breaks the signature). Instead, generate a .cat catalog file covering all .js files, which is signed with MicrosoftDotNet500 via the existing FileExtensionSignInfo entry for .cat files. The GenerateCatalogFiles target runs after ReallyBuild on Windows only (makecat.exe is a Windows SDK tool). It invokes eng/generate-catalog.ps1 which enumerates all .js files, generates a CDF, runs makecat.exe, and produces emscripten-js.cat in the SDK package directory so it ships alongside the files it covers. This fixes ~14,468 unsigned .js files flagged by VS signing compliance scans.
1 parent f4c434b commit 747fc39

3 files changed

Lines changed: 98 additions & 1 deletion

File tree

eng/Signing.props

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
<FileExtensionSignInfo Include=".pyd" CertificateName="MicrosoftDotNet500" />
99
<FileExtensionSignInfo Include=".cat" CertificateName="MicrosoftDotNet500" />
1010

11-
<!-- We don't need to code sign .js files because they are not used in Windows Script Host. -->
11+
<!-- JS files are customer-modifiable Emscripten toolchain files. They cannot be
12+
Authenticode-signed because modifying a signed file breaks the signature.
13+
Instead, a catalog file (emscripten-js.cat) is generated and signed to provide
14+
integrity verification. See the GenerateCatalogFiles target in eng/emsdk.proj. -->
1215
<FileExtensionSignInfo Update=".js" CertificateName="None" />
1316

1417
<!--

eng/emsdk.proj

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,23 @@
365365
<Delete Files="@(DeleteCacheFiles)" />
366366
</Target>
367367

368+
<!--
369+
Generate a catalog (.cat) file covering all .js files in the SDK package.
370+
The .js files are customer-modifiable Emscripten toolchain files that cannot be
371+
directly Authenticode-signed. The .cat provides integrity verification without
372+
preventing modification. Only runs on Windows (makecat.exe is a Windows SDK tool)
373+
and only the Windows packs are inserted into VS.
374+
-->
375+
<Target Name="GenerateCatalogFiles" AfterTargets="ReallyBuild" Condition="$([MSBuild]::IsOSPlatform('Windows'))">
376+
<PropertyGroup>
377+
<_CatOutputPath>$(ArtifactsObjDir)upstream\emscripten\emscripten-js.cat</_CatOutputPath>
378+
</PropertyGroup>
379+
380+
<Exec Command="powershell.exe -NoProfile -ExecutionPolicy Bypass -File &quot;$(MSBuildThisFileDirectory)generate-catalog.ps1&quot; -RootPath &quot;$(ArtifactsObjDir)upstream&quot; -CatOutputPath &quot;$(_CatOutputPath)&quot;" StandardOutputImportance="High" />
381+
382+
<Message Importance="High" Text="Generated catalog file: $(_CatOutputPath)" />
383+
</Target>
384+
368385
<Target Name="ReallyPack" DependsOnTargets="Build" BeforeTargets="Pack">
369386
<Message Importance="High" Text="Creating nuget packages..." />
370387
<MSBuild Projects="$(MSBuildThisFileDirectory)nuget\Microsoft.NET.Runtime.Emscripten.Node\Microsoft.NET.Runtime.Emscripten.Node.pkgproj" Targets="Build" />

eng/generate-catalog.ps1

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<#
2+
.SYNOPSIS
3+
Generates a catalog definition file (.cdf) and catalog file (.cat) for all .js files
4+
in the specified root directory. Used for VS signing compliance — the .js files are
5+
customer-modifiable and cannot be directly Authenticode-signed.
6+
7+
.PARAMETER RootPath
8+
Root directory to search for .js files recursively.
9+
10+
.PARAMETER CatOutputPath
11+
Full path for the output .cat file.
12+
#>
13+
param(
14+
[Parameter(Mandatory)][string]$RootPath,
15+
[Parameter(Mandatory)][string]$CatOutputPath
16+
)
17+
18+
$ErrorActionPreference = 'Stop'
19+
20+
$cdfPath = [System.IO.Path]::ChangeExtension($CatOutputPath, '.cdf')
21+
22+
$files = Get-ChildItem -Path $RootPath -Recurse -Filter '*.js' -File
23+
if ($files.Count -eq 0) {
24+
Write-Warning "No .js files found under $RootPath — skipping catalog generation."
25+
exit 0
26+
}
27+
28+
$cdf = @()
29+
$cdf += '[CatalogHeader]'
30+
$cdf += "Name=$CatOutputPath"
31+
$cdf += 'CatalogVersion=2'
32+
$cdf += 'HashAlgorithms=SHA256'
33+
$cdf += ''
34+
$cdf += '[CatalogFiles]'
35+
36+
$i = 0
37+
foreach ($f in $files) {
38+
$label = "js_${i}_" + ($f.Name -replace '[^\w\.-]', '_')
39+
$cdf += "<hash>$label=$($f.FullName)"
40+
$i++
41+
}
42+
43+
$cdf | Set-Content -Path $cdfPath -Encoding ASCII
44+
Write-Host "Generated CDF with $($files.Count) .js files at $cdfPath"
45+
46+
$catDir = [System.IO.Path]::GetDirectoryName($CatOutputPath)
47+
if (-not (Test-Path $catDir)) {
48+
New-Item -ItemType Directory -Path $catDir -Force | Out-Null
49+
}
50+
51+
# Find makecat.exe — it ships with the Windows SDK and may not be on PATH.
52+
$makecat = Get-Command makecat.exe -ErrorAction SilentlyContinue
53+
if (-not $makecat) {
54+
# Search common Windows SDK locations
55+
$sdkRoot = "${env:ProgramFiles(x86)}\Windows Kits\10\bin"
56+
if (Test-Path $sdkRoot) {
57+
$makecat = Get-ChildItem -Path $sdkRoot -Recurse -Filter 'makecat.exe' -File |
58+
Where-Object { $_.DirectoryName -match 'x64' } |
59+
Sort-Object DirectoryName -Descending |
60+
Select-Object -First 1
61+
}
62+
}
63+
64+
if (-not $makecat) {
65+
Write-Warning "makecat.exe not found — skipping catalog generation. Catalog signing requires the Windows SDK."
66+
exit 0
67+
}
68+
69+
$makecatPath = if ($makecat -is [System.Management.Automation.CommandInfo]) { $makecat.Source } else { $makecat.FullName }
70+
Write-Host "Using makecat.exe at: $makecatPath"
71+
72+
& $makecatPath $cdfPath
73+
if ($LASTEXITCODE -ne 0) {
74+
throw "makecat.exe failed with exit code $LASTEXITCODE"
75+
}
76+
77+
Write-Host "Generated catalog file: $CatOutputPath"

0 commit comments

Comments
 (0)