Skip to content

Commit ed9b14c

Browse files
hoyosjsmmitche
authored andcommitted
[release/6.0] Add signing infrastructure for diagnostic binaries (#74330)
* Add DAC signature infrastructure * Add signature verification
1 parent 38e60d8 commit ed9b14c

File tree

5 files changed

+89
-71
lines changed

5 files changed

+89
-71
lines changed

eng/Signing.props

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project InitialTargets="SetupFilesToSign">
1+
<Project>
22

33
<PropertyGroup>
44
<!--
@@ -27,7 +27,12 @@
2727
<FileSignInfo Include="Mono.Cecil.Pdb.dll" CertificateName="3PartySHA2" />
2828
<FileSignInfo Include="Mono.Cecil.Rocks.dll" CertificateName="3PartySHA2" />
2929

30-
<FileSignInfo Include="mscordaccore.dll" CertificateName="MicrosoftSHA2" />
30+
<!--
31+
The DAC and the DBI must go through special signing provisioning using a system separate
32+
from MicroBuild.
33+
-->
34+
<FileSignInfo Include="mscordaccore.dll" CertificateName="None" />
35+
<FileSignInfo Include="mscordbi.dll" CertificateName="None" />
3136

3237
<!-- Exclude symbol packages from have a NuGet signature. These are never pushed to NuGet.org or
3338
other feeds (in fact, that have identical identity to their non-symbol variant) -->
@@ -56,33 +61,4 @@
5661
<ItemsToSignWithoutPaths Include="@(ItemsToSignWithPaths->'%(Filename)%(Extension)')" />
5762
<ItemsToSignPostBuild Include="@(ItemsToSignWithoutPaths->Distinct())" />
5863
</ItemGroup>
59-
60-
<Target Name="SetupFilesToSign">
61-
<!-- Ensure that we don't miss the DAC or DBI with the globbing below -->
62-
<PropertyGroup Condition="'$(SignDiagnostics)' == 'true' or '$(SignDiagnosticsPackages)' == 'true'">
63-
<AllowEmptySignList>false</AllowEmptySignList>
64-
</PropertyGroup>
65-
66-
<ItemGroup Condition="'$(SignDiagnostics)' == 'true'">
67-
<ItemsToSign Include="$(DiagnosticsFilesRoot)\**\mscordaccore*.dll" />
68-
<ItemsToSign Include="$(DiagnosticsFilesRoot)\**\mscordbi.dll" />
69-
<!--
70-
The DAC should be signed with the SHA2 cert (both long and short name).
71-
We already add the short-name DAC above, so add the long-name DAC here.
72-
-->
73-
<DacFileSignInfo Include="@(ItemsToSign->'%(FileName)%(Extension)')"
74-
Condition="$([System.String]::new('%(FileName)').StartsWith('mscordaccore'))" />
75-
<FileSignInfo Include="@(DacFileSignInfo->ClearMetadata()->Distinct())"
76-
Exclude="mscordaccore.dll"
77-
CertificateName="MicrosoftSHA2" />
78-
</ItemGroup>
79-
80-
<ItemGroup Condition="'$(SignDiagnosticsPackages)' == 'true'">
81-
<!-- The cross OS diagnostics symbol packages need to be signed as they are the only packages
82-
that have a specific version of assets that are only meant to be indexed in symbol servers.
83-
Since only *symbols.nupkg get indexed, and installer doesn't produce these, we need to glob them for signing. -->
84-
<ItemsToSign Include="$(PackagesFolder)\**\*CrossOsDiag*.nupkg" />
85-
</ItemGroup>
86-
</Target>
87-
8864
</Project>

eng/pipelines/coreclr/templates/build-job.yml

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -238,23 +238,11 @@ jobs:
238238

239239
# Sign diagnostic files on Windows
240240
- ${{ if and(eq(parameters.osGroup, 'windows'), eq(parameters.signBinaries, true)) }}:
241-
- powershell: >-
242-
eng\common\build.ps1 -ci -sign -restore -configuration:$(buildConfig) -warnaserror:0 $(officialBuildIdArg)
243-
/p:DiagnosticsFilesRoot="$(buildProductRootFolderPath)"
244-
/p:SignDiagnostics=true
245-
/p:DotNetSignType=$(SignType)
246-
-noBl
247-
/bl:$(Build.SourcesDirectory)/artifacts/log/$(buildConfig)/SignDiagnostics.binlog
248-
-projects $(Build.SourcesDirectory)\eng\empty.csproj
249-
displayName: Sign Diagnostic Binaries
250-
251-
- task: PublishPipelineArtifact@1
252-
displayName: Publish Signing Logs
253-
inputs:
254-
targetPath: '$(Build.SourcesDirectory)/artifacts/log/'
255-
artifactName: ${{ format('SignLogs_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }}
256-
continueOnError: true
257-
condition: always()
241+
- template: /eng/pipelines/coreclr/templates/sign-diagnostic-files.yml
242+
parameters:
243+
basePath: $(buildProductRootFolderPath)
244+
isOfficialBuild: ${{ parameters.isOfficialBuild }}
245+
timeoutInMinutes: 30
258246

259247
# Builds using gcc are not tested, and clrTools unitests do not publish the build artifacts
260248
- ${{ if and(ne(parameters.compilerName, 'gcc'), ne(parameters.testGroup, 'clrTools')) }}:
@@ -275,6 +263,7 @@ jobs:
275263
archType: ${{ parameters.archType }}
276264
osGroup: ${{ parameters.osGroup }}
277265
osSubgroup: ${{ parameters.osSubgroup }}
266+
isOfficialBuild: ${{ parameters.isOfficialBuild }}
278267

279268
- ${{ if and(ne(parameters.compilerName, 'gcc'), ne(parameters.testGroup, ''), ne(parameters.testGroup, 'clrTools')) }}:
280269
# Publish test native components for consumption by test execution.

eng/pipelines/coreclr/templates/crossdac-build.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ parameters:
22
archType: ''
33
osGroup: ''
44
osSubgroup: ''
5+
isOfficialBuild: false
56

67
steps:
78
# Always build the crossdac, that way we know in CI/PR if things break to build.
@@ -30,6 +31,12 @@ steps:
3031
!**/sharedFramework/**/*
3132
TargetFolder: '$(buildMuslDacStagingPath)'
3233

34+
- template: /eng/pipelines/coreclr/templates/sign-diagnostic-files.yml
35+
parameters:
36+
basePath: $(crossDacArtifactPath)
37+
isOfficialBuild: ${{ parameters.isOfficialBuild }}
38+
timeoutInMinutes: 30
39+
3340
- ${{ if eq(parameters.osGroup, 'Linux') }}:
3441
- task: CopyFiles@2
3542
displayName: Gather runtime for CrossDac

eng/pipelines/coreclr/templates/crossdac-pack.yml

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,6 @@ jobs:
5454
- ${{ parameters.runtimeFlavor }}_${{ parameters.runtimeVariant }}_product_build_${{ platform }}_${{ parameters.buildConfig }}
5555

5656
steps:
57-
# Install MicroBuild for signing the package
58-
- ${{ if eq(parameters.isOfficialBuild, true) }}:
59-
- template: /eng/pipelines/common/restore-internal-tools.yml
60-
61-
- task: MicroBuildSigningPlugin@2
62-
displayName: Install MicroBuild plugin for Signing
63-
inputs:
64-
signType: $(SignType)
65-
zipSources: false
66-
feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json
67-
continueOnError: false
68-
condition: and(succeeded(), in(variables['SignType'], 'real', 'test'))
69-
7057
- task: DownloadBuildArtifacts@0
7158
displayName: Download CrossDac artifacts
7259
inputs:
@@ -77,16 +64,6 @@ jobs:
7764
- script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset crossdacpack -arch $(archType) $(osArg) -c $(buildConfig) $(officialBuildIdArg) $(crossDacArgs) -ci
7865
displayName: Build crossdac packaging
7966

80-
# Sign diagnostic files
81-
- ${{ if eq(parameters.isOfficialBuild, true) }}:
82-
- powershell: >-
83-
eng\common\build.ps1 -ci -sign -restore -configuration:$(buildConfig) -warnaserror:0 $(officialBuildIdArg)
84-
/p:PackagesFolder="$(Build.SourcesDirectory)/artifacts/packages/$(buildConfig)"
85-
/p:SignDiagnosticsPackages=true
86-
/p:DotNetSignType=$(SignType)
87-
-projects $(Build.SourcesDirectory)\eng\empty.csproj
88-
displayName: Sign CrossDac package and contents
89-
9067
# Save packages using the prepare-signed-artifacts format.
9168
- template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml
9269
parameters:
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
parameters:
2+
basePath: ''
3+
isOfficialBuild: ''
4+
timeoutInMinutes: ''
5+
6+
steps:
7+
- ${{ if and(eq(parameters.isOfficialBuild, true), ne(variables['Build.Reason'], 'PullRequest'), or(startswith(variables['Build.SourceBranch'], 'refs/heads/release/'), startswith(variables['Build.SourceBranch'], 'refs/heads/internal/release/'))) }}:
8+
- task: EsrpCodeSigning@1
9+
displayName: Sign Diagnostic Binaries
10+
inputs:
11+
ConnectedServiceName: 'dotnetesrp-diagnostics-dnceng'
12+
FolderPath: ${{ parameters.basePath }}
13+
Pattern: |
14+
**/mscordaccore*.dll
15+
**/mscordbi*.dll
16+
UseMinimatch: true
17+
signConfigType: 'inlineSignParams'
18+
inlineOperation: >-
19+
[
20+
{
21+
"keyCode": "CP-471322",
22+
"operationCode": "SigntoolSign",
23+
"parameters": {
24+
"OpusName": "Microsoft",
25+
"OpusInfo": "http://www.microsoft.com",
26+
"PageHash": "/NPH",
27+
"FileDigest": "/fd sha256",
28+
"TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
29+
},
30+
"toolName": "sign",
31+
"toolVersion": "1.0"
32+
},
33+
{
34+
"KeyCode": "CP-471322",
35+
"OperationCode": "SigntoolVerify",
36+
"Parameters": {},
37+
"ToolName": "sign",
38+
"ToolVersion": "1.0"
39+
}
40+
]
41+
SessionTimeout: ${{ parameters.timeoutInMinutes }}
42+
MaxConcurrency: '50'
43+
MaxRetryAttempts: '5'
44+
45+
- powershell: |
46+
$filesToSign = $(Get-ChildItem -Recurse ${{ parameters.basePath }} -Include mscordaccore*.dll, mscordbi*.dll)
47+
foreach ($file in $filesToSign) {
48+
$signingCert = $(Get-AuthenticodeSignature $file).SignerCertificate
49+
if ($signingCert -eq $null)
50+
{
51+
throw "File $file does not contain a signature."
52+
}
53+
54+
if ($signingCert.Subject -ne "CN=.NET DAC, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" `
55+
-or $signingCert.Issuer -ne "CN=Microsoft Code Signing PCA 2010, O=Microsoft Corporation, L=Redmond, S=Washington, C=US")
56+
{
57+
throw "File $file not in expected trust chain."
58+
}
59+
60+
$certEKU = $signingCert.Extensions.Where({ $_.Oid.FriendlyName -eq "Enhanced Key Usage" }) | Select -First 1
61+
62+
if ($certEKU.EnhancedKeyUsages.Where({ $_.Value -eq "1.3.6.1.4.1.311.84.4.1" }).Count -ne 1)
63+
{
64+
throw "Signature for $file does not contain expected EKU."
65+
}
66+
67+
Write-Host "$file is correctly signed."
68+
}
69+
displayName: Validate diagnostic signatures

0 commit comments

Comments
 (0)