Skip to content

Commit e69c9d0

Browse files
[release/7.0-rc1] Change signature for diagnostic binaries (#74323)
* Add DAC signature infrastructure * Use a .NET 6 SDK to enable signing * Add signature verification Co-authored-by: Juan Sebastian Hoyos Ayala <juan.hoyos@microsoft.com>
1 parent d8e8436 commit e69c9d0

File tree

5 files changed

+101
-74
lines changed

5 files changed

+101
-74
lines changed

eng/Signing.props

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
<Project InitialTargets="SetupFilesToSign">
2-
1+
<Project>
32
<PropertyGroup>
43
<!--
54
Windows arm/arm64 jobs don't have MSIs to sign. Keep it simple: allow not finding any matches
@@ -20,6 +19,13 @@
2019
<!-- apphost and comhost template files are not signed, by design. -->
2120
<FileSignInfo Include="apphost.exe;singlefilehost.exe;comhost.dll" CertificateName="None" />
2221

22+
<!--
23+
The DAC and the DBI must go through special signing provisioning using a system separate
24+
from MicroBuild.
25+
-->
26+
<FileSignInfo Include="mscordaccore.dll" CertificateName="None" />
27+
<FileSignInfo Include="mscordbi.dll" CertificateName="None" />
28+
2329
<!-- We don't need to code sign .js files because they are not used in Windows Script Host. -->
2430
<!-- WARNING: Needs to happed outside of any target -->
2531
<FileExtensionSignInfo Update=".js" CertificateName="None" />
@@ -31,8 +37,6 @@
3137
<FileSignInfo Include="Mono.Cecil.Pdb.dll" CertificateName="3PartySHA2" />
3238
<FileSignInfo Include="Mono.Cecil.Rocks.dll" CertificateName="3PartySHA2" />
3339

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

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

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -261,25 +261,12 @@ jobs:
261261
targetFolder: $(buildProductRootFolderPath)/sharedFramework
262262
overWrite: true
263263

264-
# Sign diagnostic files on Windows
265264
- ${{ if and(eq(parameters.osGroup, 'windows'), eq(parameters.signBinaries, true)) }}:
266-
- powershell: >-
267-
eng\common\build.ps1 -ci -sign -restore -configuration:$(buildConfig) -warnaserror:0 $(officialBuildIdArg)
268-
/p:DiagnosticsFilesRoot="$(buildProductRootFolderPath)"
269-
/p:SignDiagnostics=true
270-
/p:DotNetSignType=$(SignType)
271-
-noBl
272-
/bl:$(Build.SourcesDirectory)/artifacts/log/$(buildConfig)/SignDiagnostics.binlog
273-
-projects $(Build.SourcesDirectory)\eng\empty.csproj
274-
displayName: Sign Diagnostic Binaries
275-
276-
- task: PublishPipelineArtifact@1
277-
displayName: Publish Signing Logs
278-
inputs:
279-
targetPath: '$(Build.SourcesDirectory)/artifacts/log/'
280-
artifactName: ${{ format('SignLogs_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }}
281-
continueOnError: true
282-
condition: always()
265+
- template: /eng/pipelines/coreclr/templates/sign-diagnostic-files.yml
266+
parameters:
267+
basePath: $(buildProductRootFolderPath)
268+
isOfficialBuild: ${{ parameters.signBinaries }}
269+
timeoutInMinutes: 30
283270

284271
# Builds using gcc are not tested, and clrTools unitests do not publish the build artifacts
285272
- ${{ if and(ne(parameters.compilerName, 'gcc'), ne(parameters.testGroup, 'clrTools'), ne(parameters.disableClrTest, true)) }}:
@@ -300,6 +287,7 @@ jobs:
300287
archType: ${{ parameters.archType }}
301288
osGroup: ${{ parameters.osGroup }}
302289
osSubgroup: ${{ parameters.osSubgroup }}
290+
isOfficialBuild: ${{ parameters.signBinaries }}
303291
${{ if eq(parameters.archType, 'arm') }}:
304292
hostArchType: x86
305293
${{ else }}:

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
parameters:
22
archType: ''
3+
isOfficialBuild: false
34
osGroup: ''
45
osSubgroup: ''
56
hostArchType: ''
@@ -52,6 +53,12 @@ steps:
5253
5354
displayName: Gather CrossDac Artifacts
5455
56+
- template: /eng/pipelines/coreclr/templates/sign-diagnostic-files.yml
57+
parameters:
58+
basePath: $(crossDacArtifactPath)
59+
isOfficialBuild: ${{ parameters.isOfficialBuild }}
60+
timeoutInMinutes: 30
61+
5562
- ${{ if eq(parameters.osGroup, 'Linux') }}:
5663
- task: CopyFiles@2
5764
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: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
parameters:
2+
basePath: ''
3+
isOfficialBuild: ''
4+
timeoutInMinutes: ''
5+
6+
steps:
7+
- ${{ if and(eq(parameters.isOfficialBuild, true), ne(variables['Build.Reason'], 'PullRequest')) }}:
8+
- task: UseDotNet@2
9+
displayName: Install .NET 6 SDK for signing.
10+
inputs:
11+
packageType: 'sdk'
12+
version: '6.0.x'
13+
installationPath: '$(Agent.TempDirectory)/dotnet'
14+
15+
- task: EsrpCodeSigning@1
16+
displayName: Sign Diagnostic Binaries
17+
inputs:
18+
ConnectedServiceName: 'dotnetesrp-diagnostics-dnceng'
19+
FolderPath: ${{ parameters.basePath }}
20+
Pattern: |
21+
**/mscordaccore*.dll
22+
**/mscordbi*.dll
23+
UseMinimatch: true
24+
signConfigType: 'inlineSignParams'
25+
inlineOperation: >-
26+
[
27+
{
28+
"keyCode": "CP-471322",
29+
"operationCode": "SigntoolSign",
30+
"parameters": {
31+
"OpusName": "Microsoft",
32+
"OpusInfo": "http://www.microsoft.com",
33+
"PageHash": "/NPH",
34+
"FileDigest": "/fd sha256",
35+
"TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
36+
},
37+
"toolName": "sign",
38+
"toolVersion": "1.0"
39+
},
40+
{
41+
"KeyCode": "CP-471322",
42+
"OperationCode": "SigntoolVerify",
43+
"Parameters": {},
44+
"ToolName": "sign",
45+
"ToolVersion": "1.0"
46+
}
47+
]
48+
SessionTimeout: ${{ parameters.timeoutInMinutes }}
49+
MaxConcurrency: '50'
50+
MaxRetryAttempts: '5'
51+
env:
52+
DOTNET_MULTILEVEL_LOOKUP: 0
53+
DOTNET_ROOT: '$(Agent.TempDirectory)/dotnet'
54+
DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR: '$(Agent.TempDirectory)/dotnet'
55+
56+
- powershell: |
57+
$filesToSign = $(Get-ChildItem -Recurse ${{ parameters.basePath }} -Include mscordaccore*.dll, mscordbi*.dll)
58+
foreach ($file in $filesToSign) {
59+
$signingCert = $(Get-AuthenticodeSignature $file).SignerCertificate
60+
if ($signingCert -eq $null)
61+
{
62+
throw "File $file does not contain a signature."
63+
}
64+
65+
if ($signingCert.Subject -ne "CN=.NET DAC, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" `
66+
-or $signingCert.Issuer -ne "CN=Microsoft Code Signing PCA 2010, O=Microsoft Corporation, L=Redmond, S=Washington, C=US")
67+
{
68+
throw "File $file not in expected trust chain."
69+
}
70+
71+
$certEKU = $signingCert.Extensions.Where({ $_.Oid.FriendlyName -eq "Enhanced Key Usage" }) | Select -First 1
72+
73+
if ($certEKU.EnhancedKeyUsages.Where({ $_.Value -eq "1.3.6.1.4.1.311.84.4.1" }).Count -ne 1)
74+
{
75+
throw "Signature for $file does not contain expected EKU."
76+
}
77+
78+
Write-Host "$file is correctly signed."
79+
}
80+
displayName: Validate diagnostic signatures

0 commit comments

Comments
 (0)