Skip to content

Commit 9965641

Browse files
authored
Merge pull request #4462 from cormacpayne/signature-script
Update signature script for strong name and authenticode
2 parents 7adf751 + 9f3ceb6 commit 9965641

File tree

3 files changed

+214
-19
lines changed

3 files changed

+214
-19
lines changed

build.proj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,8 @@
387387
<Output TaskParameter="AuthCodeSignTaskErrorsDetected" PropertyName="AuthTaskFailed" />
388388
</VerifyAuthenticodeSignatureTask>
389389

390-
<Exec Command="&quot;$(PowerShellCommand)&quot; -NonInteractive -NoLogo -NoProfile -Command &quot;. $(LibraryToolsFolder)\CheckStrongNameSignature.ps1 &quot;"/>
390+
<Exec Command="&quot;$(PowerShellCommand)&quot; -NonInteractive -NoLogo -NoProfile -Command &quot;. $(LibraryToolsFolder)\CheckSignature.ps1 -CustomPath $(LibrarySourceFolder)\Package\$(Configuration) &quot;"
391+
ContinueOnError="ErrorAndContinue" />
391392

392393
<!-- Copying signed shortcut back -->
393394
<Copy SourceFiles="$(LibrarySourceFolder)\Package\$(Configuration)\AzureRM.psd1"

tools/CheckSignature.ps1

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
<#
2+
Check (and recurse) current directory .\CheckSignature.ps1
3+
Find and check directory of Azure PowerShell modules .\CheckSignature.ps1 -AzurePowerShell
4+
Check directory of MSI-installed modules .\CheckSignature.ps1 -MsiInstall
5+
Check directory of gallery-installed modules .\CheckSignature.ps1 -GalleryInstall
6+
Check files in provided path .\CheckSignature.ps1 -CustomPath $Path
7+
#>
8+
[CmdletBinding(DefaultParameterSetName="CurrentDirectory")]
9+
Param
10+
(
11+
[Parameter(ParameterSetName="AzurePowerShell", Mandatory=$true)]
12+
[switch]$AzurePowerShell,
13+
[Parameter(ParameterSetName="MsiInstall", Mandatory=$true)]
14+
[switch]$MsiInstall,
15+
[Parameter(ParameterSetName="GalleryInstall", Mandatory=$true)]
16+
[switch]$GalleryInstall,
17+
[Parameter(ParameterSetName="CustomPath", Mandatory=$true)]
18+
[string]$CustomPath
19+
)
20+
21+
function Check-StrongName {
22+
[CmdletBinding()]
23+
param([Parameter(ValueFromPipeline=$true)][string]$path)
24+
$output = & "sn.exe" -vf $path
25+
$length = $output.Length - 1
26+
if (-not $output[$length].Contains("is valid")) {
27+
Write-Output "$path has an invalid strong name."
28+
}
29+
}
30+
31+
function Check-AuthenticodeSignature {
32+
[CmdletBinding()]
33+
param([Parameter(ValueFromPipeline=$true)][string]$path)
34+
$output = Get-AuthenticodeSignature $path
35+
if (-not ($output.Status -like "Valid")) {
36+
Write-Output "$path has an invalid authenticode signature. Status is $($output.Status)"
37+
}
38+
}
39+
40+
function Check-All {
41+
[CmdletBinding()]
42+
param([Parameter()][string]$path)
43+
44+
if (!(Get-Command "sn.exe" -ErrorAction SilentlyContinue))
45+
{
46+
Write-Error "Unable to find sn.exe; please ensure that the Windows SDK is installed and found in the PATH environment variable."
47+
return
48+
}
49+
50+
$invalidList = @()
51+
52+
$files = Get-ChildItem $path\* -Include *.dll -Recurse | Where-Object { $_.FullName -like "*Azure*" }
53+
Write-Host "Checking the strong name signature of $($files.Count) files (.dll)" -ForegroundColor Yellow
54+
55+
$invalidStrongNameList = @()
56+
57+
for ($idx = 0; $idx -lt $files.Length; $idx++) {
58+
$percent = (100 * $idx) / $files.Length
59+
Write-Progress -Activity "Validating strong name signature of $($files[$idx])" -Status "$percent% Complete" -PercentComplete $percent
60+
$invalidStrongNameList += Check-StrongName -path $files[$idx]
61+
}
62+
63+
if ($invalidStrongNameList.Length -gt 0) {
64+
$invalidList += $invalidStrongNameList
65+
Write-Host "Found $($invalidStrongNameList.Count) files with an invalid strong name signature." -ForegroundColor Red
66+
}
67+
else {
68+
Write-Host "All files (.dll) have a strong name signature." -ForegroundColor Green
69+
}
70+
71+
# -------------------------------------
72+
73+
$files = Get-ChildItem $path\* -Include *.dll, *.ps1, *.psm1 -Recurse | Where-Object { $_.FullName -like "*Azure*" }
74+
$files = $files | Where-Object { ($_.FullName -notlike "*Newtonsoft.Json*") -and `
75+
($_.FullName -notlike "*AutoMapper*") -and `
76+
($_.FullName -notlike "*Security.Cryptography*") -and `
77+
($_.FullName -notlike "*BouncyCastle.Crypto*")}
78+
Write-Host "Checking the authenticode signature of $($files.Count) files (.dll, .ps1, .psm1)" -ForegroundColor Yellow
79+
80+
$invalidAuthenticodeList = @()
81+
82+
for ($idx = 0; $idx -lt $files.Length; $idx++) {
83+
$percent = (100 * $idx) / $files.Length
84+
Write-Progress -Activity "Validating authenticode signature of $($files[$idx])" -Status "$percent% Complete" -PercentComplete $percent
85+
$invalidAuthenticodeList += Check-AuthenticodeSignature -path $files[$idx]
86+
}
87+
88+
if ($invalidAuthenticodeList.Length -gt 0) {
89+
$invalidList += $invalidAuthenticodeList
90+
Write-Host "Found $($invalidAuthenticodeList.Count) files with an invalid authenticode signature." -ForegroundColor Red
91+
}
92+
else {
93+
Write-Host "All files (.dll, .ps1, .psd1) have a valid authenticode signature." -ForegroundColor Green
94+
}
95+
96+
if ($invalidList.Length -gt 0) {
97+
Write-Output($invalidList)
98+
throw "Strong name signature check and/or authenticode signature check failed. Please see the above errors."
99+
}
100+
}
101+
102+
$path = ".\"
103+
104+
if ($PSCmdlet.ParameterSetName -eq "AzurePowerShell")
105+
{
106+
$ProfileModule = Get-Module -Name AzureRM.Profile -ListAvailable
107+
if (!($ProfileModule))
108+
{
109+
Write-Error "Unable to find the AzureRM.Profile module. Please ensure that Azure PowerShell has been installed and the appropriate path is found in the PSModulePath environment variable."
110+
return
111+
}
112+
113+
if ($ProfileModule.Count -gt 1)
114+
{
115+
Write-Error "Mulitple versions of Azure PowerShell were found. Please use the -MsiInstall and -GalleryInstall switches to select the installed version you want to check."
116+
return
117+
}
118+
119+
$ModulePath = $ProfileModule.Path
120+
if ($ModulePath -like "*Microsoft SDKs\Azure\PowerShell*")
121+
{
122+
$EndIdx = $ModulePath.IndexOf("PowerShell\ResourceManager", [System.StringComparison]::OrdinalIgnoreCase) + "PowerShell".Length
123+
}
124+
elseif ($ModulePath -like "*Modules\AzureRM.Profile*")
125+
{
126+
$EndIdx = $ModulePath.IndexOf("Modules\AzureRM.Profile", [System.StringComparison]::OrdinalIgnoreCase) + "Modules".Length
127+
}
128+
129+
$path = $ModulePath.Substring(0, $EndIdx)
130+
Write-Host "Found AzureRM module - checking all (Azure) files in $path" -ForegroundColor Yellow
131+
}
132+
elseif ($PSCmdlet.ParameterSetName -eq "MsiInstall")
133+
{
134+
$ProfileModule = Get-Module -Name AzureRM.Profile -ListAvailable
135+
if (!($ProfileModule))
136+
{
137+
Write-Error "Unable to find the AzureRM.Profile module. Please ensure that Azure PowerShell has been installed and the appropriate path is found in the PSModulePath environment variable."
138+
return
139+
}
140+
141+
$SearchString = "Microsoft SDKs\Azure\PowerShell"
142+
143+
$ModulePath = $ProfileModule.Path
144+
145+
if ($ProfileModule.Count -gt 1)
146+
{
147+
$ModulePath = $ProfileModule | Where-Object { $_.Path -like "*$($SearchString)*" }
148+
if (!($ModulePath))
149+
{
150+
Write-Error "Unable to find path of MSI-installed modules from multiple locations found in PSModulePath."
151+
return
152+
}
153+
}
154+
else
155+
{
156+
if ($ModulePath -notlike "*$($SearchString)*")
157+
{
158+
Write-Error "Modules installed on the current machine were not from MSI. Consider using the -GalleryInstall switch."
159+
return
160+
}
161+
}
162+
163+
$EndIdx = $ModulePath.IndexOf("PowerShell\ResourceManager", [System.StringComparison]::OrdinalIgnoreCase) + "PowerShell".Length
164+
$path = $ModulePath.Substring(0, $EndIdx)
165+
Write-Host "Installed Azure PowerShell from MSI - checking all (Azure) files in $path" -ForegroundColor Yellow
166+
}
167+
elseif ($PSCmdlet.ParameterSetName -eq "GalleryInstall")
168+
{
169+
$ProfileModule = Get-Module -Name AzureRM.Profile -ListAvailable
170+
if (!($ProfileModule))
171+
{
172+
Write-Error "Unable to find the AzureRM.Profile module. Please ensure that Azure PowerShell has been installed and the appropriate path is found in the PSModulePath environment variable."
173+
return
174+
}
175+
176+
$SearchString = "WindowsPowerShell\Modules"
177+
178+
$ModulePath = $ProfileModule.Path
179+
180+
if ($ProfileModule.Count -gt 1)
181+
{
182+
$ModulePath = $ProfileModule | Where-Object { $_.Path -like "*$($SearchString)*" }
183+
if (!($ModulePath))
184+
{
185+
Write-Error "Unable to find path of gallery-installed modules from multiple locations found in PSModulePath."
186+
return
187+
}
188+
}
189+
else
190+
{
191+
if ($ModulePath -notlike "*$($SearchString)*")
192+
{
193+
Write-Error "Modules installed on the current machine were not from the gallery. Consider using the -MsiInstall switch."
194+
return
195+
}
196+
}
197+
198+
$EndIdx = $ModulePath.IndexOf("Modules\AzureRM.Profile", [System.StringComparison]::OrdinalIgnoreCase) + "Modules".Length
199+
$path = $ModulePath.Substring(0, $EndIdx)
200+
Write-Host "Installed Azure PowerShell from the gallery - checking all (Azure) files in $path" -ForegroundColor Yellow
201+
}
202+
elseif ($PSCmdlet.ParameterSetName -eq "CustomPath")
203+
{
204+
$path = $CustomPath
205+
Write-Host "Custom path provided - checking all (Azure) files in $path" -ForegroundColor Yellow
206+
}
207+
else
208+
{
209+
Write-Host "No switch parameter set - checking all files in current directory" -ForegroundColor Yellow
210+
}
211+
212+
Check-All $path

tools/CheckStrongNameSignature.ps1

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)