mirror of
https://github.com/kiwix/kiwix-js-pwa.git
synced 2025-09-01 11:11:10 -04:00

Former-commit-id: ad9c9ac82aa9ca9def238b20bb56877fb5746d31 [formerly 252e6012d20658d3ed830b9395f33a4a4e686a7b [formerly e6cf52cd9d212002a665e6d3570fda45b6117d76]] Former-commit-id: 3ee24a6857f318b12aa6b0de34c442f157cb9784 Former-commit-id: cd14773001222e707d68c4fde761bf3ca3026383
777 lines
32 KiB
PowerShell
777 lines
32 KiB
PowerShell
#
|
|
# Add-AppxDevPackage.ps1 is a PowerShell script designed to install app
|
|
# packages created by Visual Studio for developers. To run this script from
|
|
# Explorer, right-click on its icon and choose "Run with PowerShell".
|
|
#
|
|
# Visual Studio supplies this script in the folder generated with its
|
|
# "Prepare Package" command. The same folder will also contain the app
|
|
# package (a .appx file), the signing certificate (a .cer file), and a
|
|
# "Dependencies" subfolder containing all the framework packages used by the
|
|
# app.
|
|
#
|
|
# This script simplifies installing these packages by automating the
|
|
# following functions:
|
|
# 1. Find the app package and signing certificate in the script directory
|
|
# 2. Prompt the user to acquire a developer license and to install the
|
|
# certificate if necessary
|
|
# 3. Find dependency packages that are applicable to the operating system's
|
|
# CPU architecture
|
|
# 4. Install the package along with all applicable dependencies
|
|
#
|
|
# All command line parameters are reserved for use internally by the script.
|
|
# Users should launch this script from Explorer.
|
|
#
|
|
|
|
# .Link
|
|
# http://go.microsoft.com/fwlink/?LinkId=243053
|
|
|
|
param(
|
|
[switch]$Force = $false,
|
|
[switch]$GetDeveloperLicense = $false,
|
|
[string]$CertificatePath = $null
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
# The language resources for this script are placed in the
|
|
# "Add-AppDevPackage.resources" subfolder alongside the script. Since the
|
|
# current working directory might not be the directory that contains the
|
|
# script, we need to create the full path of the resources directory to
|
|
# pass into Import-LocalizedData
|
|
$ScriptPath = $null
|
|
try
|
|
{
|
|
$ScriptPath = (Get-Variable MyInvocation).Value.MyCommand.Path
|
|
$ScriptDir = Split-Path -Parent $ScriptPath
|
|
}
|
|
catch {}
|
|
|
|
if (!$ScriptPath)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorNoScriptPath $ErrorCodes.NoScriptPath
|
|
}
|
|
|
|
$LocalizedResourcePath = Join-Path $ScriptDir "Add-AppDevPackage.resources"
|
|
Import-LocalizedData -BindingVariable UiStrings -BaseDirectory $LocalizedResourcePath
|
|
|
|
$ErrorCodes = Data {
|
|
ConvertFrom-StringData @'
|
|
Success = 0
|
|
NoScriptPath = 1
|
|
NoPackageFound = 2
|
|
ManyPackagesFound = 3
|
|
NoCertificateFound = 4
|
|
ManyCertificatesFound = 5
|
|
BadCertificate = 6
|
|
PackageUnsigned = 7
|
|
CertificateMismatch = 8
|
|
ForceElevate = 9
|
|
LaunchAdminFailed = 10
|
|
GetDeveloperLicenseFailed = 11
|
|
InstallCertificateFailed = 12
|
|
AddPackageFailed = 13
|
|
ForceDeveloperLicense = 14
|
|
CertUtilInstallFailed = 17
|
|
CertIsCA = 18
|
|
BannedEKU = 19
|
|
NoBasicConstraints = 20
|
|
NoCodeSigningEku = 21
|
|
InstallCertificateCancelled = 22
|
|
BannedKeyUsage = 23
|
|
ExpiredCertificate = 24
|
|
'@
|
|
}
|
|
|
|
function PrintMessageAndExit($ErrorMessage, $ReturnCode)
|
|
{
|
|
Write-Host $ErrorMessage
|
|
if (!$Force)
|
|
{
|
|
Pause
|
|
}
|
|
exit $ReturnCode
|
|
}
|
|
|
|
#
|
|
# Warns the user about installing certificates, and presents a Yes/No prompt
|
|
# to confirm the action. The default is set to No.
|
|
#
|
|
function ConfirmCertificateInstall
|
|
{
|
|
$Answer = $host.UI.PromptForChoice(
|
|
"",
|
|
$UiStrings.WarningInstallCert,
|
|
[System.Management.Automation.Host.ChoiceDescription[]]@($UiStrings.PromptYesString, $UiStrings.PromptNoString),
|
|
1)
|
|
|
|
return $Answer -eq 0
|
|
}
|
|
|
|
#
|
|
# Validates whether a file is a valid certificate using CertUtil.
|
|
# This needs to be done before calling Get-PfxCertificate on the file, otherwise
|
|
# the user will get a cryptic "Password: " prompt for invalid certs.
|
|
#
|
|
function ValidateCertificateFormat($FilePath)
|
|
{
|
|
# certutil -verify prints a lot of text that we don't need, so it's redirected to $null here
|
|
certutil.exe -verify $FilePath > $null
|
|
if ($LastExitCode -lt 0)
|
|
{
|
|
PrintMessageAndExit ($UiStrings.ErrorBadCertificate -f $FilePath, $LastExitCode) $ErrorCodes.BadCertificate
|
|
}
|
|
|
|
# Check if certificate is expired
|
|
$cert = Get-PfxCertificate $FilePath
|
|
if (($cert.NotBefore -gt (Get-Date)) -or ($cert.NotAfter -lt (Get-Date)))
|
|
{
|
|
PrintMessageAndExit ($UiStrings.ErrorExpiredCertificate -f $FilePath) $ErrorCodes.ExpiredCertificate
|
|
}
|
|
}
|
|
|
|
#
|
|
# Verify that the developer certificate meets the following restrictions:
|
|
# - The certificate must contain a Basic Constraints extension, and its
|
|
# Certificate Authority (CA) property must be false.
|
|
# - The certificate's Key Usage extension must be either absent, or set to
|
|
# only DigitalSignature.
|
|
# - The certificate must contain an Extended Key Usage (EKU) extension with
|
|
# Code Signing usage.
|
|
# - The certificate must NOT contain any other EKU except Code Signing and
|
|
# Lifetime Signing.
|
|
#
|
|
# These restrictions are enforced to decrease security risks that arise from
|
|
# trusting digital certificates.
|
|
#
|
|
function CheckCertificateRestrictions
|
|
{
|
|
Set-Variable -Name BasicConstraintsExtensionOid -Value "2.5.29.19" -Option Constant
|
|
Set-Variable -Name KeyUsageExtensionOid -Value "2.5.29.15" -Option Constant
|
|
Set-Variable -Name EkuExtensionOid -Value "2.5.29.37" -Option Constant
|
|
Set-Variable -Name CodeSigningEkuOid -Value "1.3.6.1.5.5.7.3.3" -Option Constant
|
|
Set-Variable -Name LifetimeSigningEkuOid -Value "1.3.6.1.4.1.311.10.3.13" -Option Constant
|
|
|
|
$CertificateExtensions = (Get-PfxCertificate $CertificatePath).Extensions
|
|
$HasBasicConstraints = $false
|
|
$HasCodeSigningEku = $false
|
|
|
|
foreach ($Extension in $CertificateExtensions)
|
|
{
|
|
# Certificate must contain the Basic Constraints extension
|
|
if ($Extension.oid.value -eq $BasicConstraintsExtensionOid)
|
|
{
|
|
# CA property must be false
|
|
if ($Extension.CertificateAuthority)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorCertIsCA $ErrorCodes.CertIsCA
|
|
}
|
|
$HasBasicConstraints = $true
|
|
}
|
|
|
|
# If key usage is present, it must be set to digital signature
|
|
elseif ($Extension.oid.value -eq $KeyUsageExtensionOid)
|
|
{
|
|
if ($Extension.KeyUsages -ne "DigitalSignature")
|
|
{
|
|
PrintMessageAndExit ($UiStrings.ErrorBannedKeyUsage -f $Extension.KeyUsages) $ErrorCodes.BannedKeyUsage
|
|
}
|
|
}
|
|
|
|
elseif ($Extension.oid.value -eq $EkuExtensionOid)
|
|
{
|
|
# Certificate must contain the Code Signing EKU
|
|
$EKUs = $Extension.EnhancedKeyUsages.Value
|
|
if ($EKUs -contains $CodeSigningEkuOid)
|
|
{
|
|
$HasCodeSigningEKU = $True
|
|
}
|
|
|
|
# EKUs other than code signing and lifetime signing are not allowed
|
|
foreach ($EKU in $EKUs)
|
|
{
|
|
if ($EKU -ne $CodeSigningEkuOid -and $EKU -ne $LifetimeSigningEkuOid)
|
|
{
|
|
PrintMessageAndExit ($UiStrings.ErrorBannedEKU -f $EKU) $ErrorCodes.BannedEKU
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$HasBasicConstraints)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorNoBasicConstraints $ErrorCodes.NoBasicConstraints
|
|
}
|
|
if (!$HasCodeSigningEKU)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorNoCodeSigningEku $ErrorCodes.NoCodeSigningEku
|
|
}
|
|
}
|
|
|
|
#
|
|
# Performs operations that require administrative privileges:
|
|
# - Prompt the user to obtain a developer license
|
|
# - Install the developer certificate (if -Force is not specified, also prompts the user to confirm)
|
|
#
|
|
function DoElevatedOperations
|
|
{
|
|
if ($GetDeveloperLicense)
|
|
{
|
|
Write-Host $UiStrings.GettingDeveloperLicense
|
|
|
|
if ($Force)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorForceDeveloperLicense $ErrorCodes.ForceDeveloperLicense
|
|
}
|
|
try
|
|
{
|
|
Show-WindowsDeveloperLicenseRegistration
|
|
}
|
|
catch
|
|
{
|
|
$Error[0] # Dump details about the last error
|
|
PrintMessageAndExit $UiStrings.ErrorGetDeveloperLicenseFailed $ErrorCodes.GetDeveloperLicenseFailed
|
|
}
|
|
}
|
|
|
|
if ($CertificatePath)
|
|
{
|
|
Write-Host $UiStrings.InstallingCertificate
|
|
|
|
# Make sure certificate format is valid and usage constraints are followed
|
|
ValidateCertificateFormat $CertificatePath
|
|
CheckCertificateRestrictions
|
|
|
|
# If -Force is not specified, warn the user and get consent
|
|
if ($Force -or (ConfirmCertificateInstall))
|
|
{
|
|
# Add cert to store
|
|
certutil.exe -addstore TrustedPeople $CertificatePath
|
|
if ($LastExitCode -lt 0)
|
|
{
|
|
PrintMessageAndExit ($UiStrings.ErrorCertUtilInstallFailed -f $LastExitCode) $ErrorCodes.CertUtilInstallFailed
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorInstallCertificateCancelled $ErrorCodes.InstallCertificateCancelled
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Checks whether the machine is missing a valid developer license.
|
|
#
|
|
function CheckIfNeedDeveloperLicense
|
|
{
|
|
$Result = $true
|
|
try
|
|
{
|
|
$Result = (Get-WindowsDeveloperLicense | Where-Object { $_.IsValid } | Measure-Object).Count -eq 0
|
|
}
|
|
catch {}
|
|
|
|
return $Result
|
|
}
|
|
|
|
#
|
|
# Launches an elevated process running the current script to perform tasks
|
|
# that require administrative privileges. This function waits until the
|
|
# elevated process terminates, and checks whether those tasks were successful.
|
|
#
|
|
function LaunchElevated
|
|
{
|
|
# Set up command line arguments to the elevated process
|
|
$RelaunchArgs = '-ExecutionPolicy Unrestricted -file "' + $ScriptPath + '"'
|
|
|
|
if ($Force)
|
|
{
|
|
$RelaunchArgs += ' -Force'
|
|
}
|
|
if ($NeedDeveloperLicense)
|
|
{
|
|
$RelaunchArgs += ' -GetDeveloperLicense'
|
|
}
|
|
if ($NeedInstallCertificate)
|
|
{
|
|
$RelaunchArgs += ' -CertificatePath "' + $DeveloperCertificatePath.FullName + '"'
|
|
}
|
|
|
|
# Launch the process and wait for it to finish
|
|
try
|
|
{
|
|
$AdminProcess = Start-Process "$PsHome\PowerShell.exe" -Verb RunAs -ArgumentList $RelaunchArgs -PassThru
|
|
}
|
|
catch
|
|
{
|
|
$Error[0] # Dump details about the last error
|
|
PrintMessageAndExit $UiStrings.ErrorLaunchAdminFailed $ErrorCodes.LaunchAdminFailed
|
|
}
|
|
|
|
while (!($AdminProcess.HasExited))
|
|
{
|
|
Start-Sleep -Seconds 2
|
|
}
|
|
|
|
# Check if all elevated operations were successful
|
|
if ($NeedDeveloperLicense)
|
|
{
|
|
if (CheckIfNeedDeveloperLicense)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorGetDeveloperLicenseFailed $ErrorCodes.GetDeveloperLicenseFailed
|
|
}
|
|
else
|
|
{
|
|
Write-Host $UiStrings.AcquireLicenseSuccessful
|
|
}
|
|
}
|
|
if ($NeedInstallCertificate)
|
|
{
|
|
$Signature = Get-AuthenticodeSignature $DeveloperPackagePath -Verbose
|
|
if ($Signature.Status -ne "Valid")
|
|
{
|
|
PrintMessageAndExit ($UiStrings.ErrorInstallCertificateFailed -f $Signature.Status) $ErrorCodes.InstallCertificateFailed
|
|
}
|
|
else
|
|
{
|
|
Write-Host $UiStrings.InstallCertificateSuccessful
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Finds all applicable dependency packages according to OS architecture, and
|
|
# installs the developer package with its dependencies. The expected layout
|
|
# of dependencies is:
|
|
#
|
|
# <current dir>
|
|
# \Dependencies
|
|
# <Architecture neutral dependencies>.appx\.msix
|
|
# \x86
|
|
# <x86 dependencies>.appx\.msix
|
|
# \x64
|
|
# <x64 dependencies>.appx\.msix
|
|
# \arm
|
|
# <arm dependencies>.appx\.msix
|
|
#
|
|
function InstallPackageWithDependencies
|
|
{
|
|
$DependencyPackagesDir = (Join-Path $ScriptDir "Dependencies")
|
|
$DependencyPackages = @()
|
|
if (Test-Path $DependencyPackagesDir)
|
|
{
|
|
# Get architecture-neutral dependencies
|
|
$DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "*.appx") | Where-Object { $_.Mode -NotMatch "d" }
|
|
$DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "*.msix") | Where-Object { $_.Mode -NotMatch "d" }
|
|
|
|
# Get architecture-specific dependencies
|
|
if (($Env:Processor_Architecture -eq "x86" -or $Env:Processor_Architecture -eq "amd64") -and (Test-Path (Join-Path $DependencyPackagesDir "x86")))
|
|
{
|
|
$DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "x86\*.appx") | Where-Object { $_.Mode -NotMatch "d" }
|
|
$DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "x86\*.msix") | Where-Object { $_.Mode -NotMatch "d" }
|
|
}
|
|
if (($Env:Processor_Architecture -eq "amd64") -and (Test-Path (Join-Path $DependencyPackagesDir "x64")))
|
|
{
|
|
$DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "x64\*.appx") | Where-Object { $_.Mode -NotMatch "d" }
|
|
$DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "x64\*.msix") | Where-Object { $_.Mode -NotMatch "d" }
|
|
}
|
|
if (($Env:Processor_Architecture -eq "arm") -and (Test-Path (Join-Path $DependencyPackagesDir "arm")))
|
|
{
|
|
$DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "arm\*.appx") | Where-Object { $_.Mode -NotMatch "d" }
|
|
$DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "arm\*.msix") | Where-Object { $_.Mode -NotMatch "d" }
|
|
}
|
|
}
|
|
Write-Host $UiStrings.InstallingPackage
|
|
|
|
$AddPackageSucceeded = $False
|
|
try
|
|
{
|
|
if ($DependencyPackages.FullName.Count -gt 0)
|
|
{
|
|
Write-Host $UiStrings.DependenciesFound
|
|
$DependencyPackages.FullName
|
|
Add-AppxPackage -Path $DeveloperPackagePath.FullName -DependencyPath $DependencyPackages.FullName -ForceApplicationShutdown
|
|
}
|
|
else
|
|
{
|
|
Add-AppxPackage -Path $DeveloperPackagePath.FullName -ForceApplicationShutdown
|
|
}
|
|
$AddPackageSucceeded = $?
|
|
}
|
|
catch
|
|
{
|
|
$Error[0] # Dump details about the last error
|
|
}
|
|
|
|
if (!$AddPackageSucceeded)
|
|
{
|
|
if ($NeedInstallCertificate)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorAddPackageFailedWithCert $ErrorCodes.AddPackageFailed
|
|
}
|
|
else
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorAddPackageFailed $ErrorCodes.AddPackageFailed
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Main script logic when the user launches the script without parameters.
|
|
#
|
|
function DoStandardOperations
|
|
{
|
|
# Check for an .appx or .msix file in the script directory
|
|
$PackagePath = Get-ChildItem (Join-Path $ScriptDir "*.appx") | Where-Object { $_.Mode -NotMatch "d" }
|
|
if ($PackagePath -eq $null)
|
|
{
|
|
$PackagePath = Get-ChildItem (Join-Path $ScriptDir "*.msix") | Where-Object { $_.Mode -NotMatch "d" }
|
|
}
|
|
$PackageCount = ($PackagePath | Measure-Object).Count
|
|
|
|
# Check for an .appxbundle or .msixbundle file in the script directory
|
|
$BundlePath = Get-ChildItem (Join-Path $ScriptDir "*.appxbundle") | Where-Object { $_.Mode -NotMatch "d" }
|
|
if ($BundlePath -eq $null)
|
|
{
|
|
$BundlePath = Get-ChildItem (Join-Path $ScriptDir "*.msixbundle") | Where-Object { $_.Mode -NotMatch "d" }
|
|
}
|
|
$BundleCount = ($BundlePath | Measure-Object).Count
|
|
|
|
# Check for an .eappx or .emsix file in the script directory
|
|
$EncryptedPackagePath = Get-ChildItem (Join-Path $ScriptDir "*.eappx") | Where-Object { $_.Mode -NotMatch "d" }
|
|
if ($EncryptedPackagePath -eq $null)
|
|
{
|
|
$EncryptedPackagePath = Get-ChildItem (Join-Path $ScriptDir "*.emsix") | Where-Object { $_.Mode -NotMatch "d" }
|
|
}
|
|
$EncryptedPackageCount = ($EncryptedPackagePath | Measure-Object).Count
|
|
|
|
# Check for an .eappxbundle or .emsixbundle file in the script directory
|
|
$EncryptedBundlePath = Get-ChildItem (Join-Path $ScriptDir "*.eappxbundle") | Where-Object { $_.Mode -NotMatch "d" }
|
|
if ($EncryptedBundlePath -eq $null)
|
|
{
|
|
$EncryptedBundlePath = Get-ChildItem (Join-Path $ScriptDir "*.emsixbundle") | Where-Object { $_.Mode -NotMatch "d" }
|
|
}
|
|
$EncryptedBundleCount = ($EncryptedBundlePath | Measure-Object).Count
|
|
|
|
$NumberOfPackages = $PackageCount + $EncryptedPackageCount
|
|
$NumberOfBundles = $BundleCount + $EncryptedBundleCount
|
|
|
|
# There must be at least one package or bundle
|
|
if ($NumberOfPackages + $NumberOfBundles -lt 1)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorNoPackageFound $ErrorCodes.NoPackageFound
|
|
}
|
|
# We must have exactly one bundle OR no bundle and exactly one package
|
|
elseif ($NumberOfBundles -gt 1 -or
|
|
($NumberOfBundles -eq 0 -and $NumberOfpackages -gt 1))
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorManyPackagesFound $ErrorCodes.ManyPackagesFound
|
|
}
|
|
|
|
# First attempt to install a bundle or encrypted bundle. If neither exists, fall back to packages and then encrypted packages
|
|
if ($BundleCount -eq 1)
|
|
{
|
|
$DeveloperPackagePath = $BundlePath
|
|
Write-Host ($UiStrings.BundleFound -f $DeveloperPackagePath.FullName)
|
|
}
|
|
elseif ($EncryptedBundleCount -eq 1)
|
|
{
|
|
$DeveloperPackagePath = $EncryptedBundlePath
|
|
Write-Host ($UiStrings.EncryptedBundleFound -f $DeveloperPackagePath.FullName)
|
|
}
|
|
elseif ($PackageCount -eq 1)
|
|
{
|
|
$DeveloperPackagePath = $PackagePath
|
|
Write-Host ($UiStrings.PackageFound -f $DeveloperPackagePath.FullName)
|
|
}
|
|
elseif ($EncryptedPackageCount -eq 1)
|
|
{
|
|
$DeveloperPackagePath = $EncryptedPackagePath
|
|
Write-Host ($UiStrings.EncryptedPackageFound -f $DeveloperPackagePath.FullName)
|
|
}
|
|
|
|
# The package must be signed
|
|
$PackageSignature = Get-AuthenticodeSignature $DeveloperPackagePath
|
|
$PackageCertificate = $PackageSignature.SignerCertificate
|
|
if (!$PackageCertificate)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorPackageUnsigned $ErrorCodes.PackageUnsigned
|
|
}
|
|
|
|
# Test if the package signature is trusted. If not, the corresponding certificate
|
|
# needs to be present in the current directory and needs to be installed.
|
|
$NeedInstallCertificate = ($PackageSignature.Status -ne "Valid")
|
|
|
|
if ($NeedInstallCertificate)
|
|
{
|
|
# List all .cer files in the script directory
|
|
$DeveloperCertificatePath = Get-ChildItem (Join-Path $ScriptDir "*.cer") | Where-Object { $_.Mode -NotMatch "d" }
|
|
$DeveloperCertificateCount = ($DeveloperCertificatePath | Measure-Object).Count
|
|
|
|
# There must be exactly 1 certificate
|
|
if ($DeveloperCertificateCount -lt 1)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorNoCertificateFound $ErrorCodes.NoCertificateFound
|
|
}
|
|
elseif ($DeveloperCertificateCount -gt 1)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorManyCertificatesFound $ErrorCodes.ManyCertificatesFound
|
|
}
|
|
|
|
Write-Host ($UiStrings.CertificateFound -f $DeveloperCertificatePath.FullName)
|
|
|
|
# The .cer file must have the format of a valid certificate
|
|
ValidateCertificateFormat $DeveloperCertificatePath
|
|
|
|
# The package signature must match the certificate file
|
|
if ($PackageCertificate -ne (Get-PfxCertificate $DeveloperCertificatePath))
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorCertificateMismatch $ErrorCodes.CertificateMismatch
|
|
}
|
|
}
|
|
|
|
$NeedDeveloperLicense = CheckIfNeedDeveloperLicense
|
|
|
|
# Relaunch the script elevated with the necessary parameters if needed
|
|
if ($NeedDeveloperLicense -or $NeedInstallCertificate)
|
|
{
|
|
Write-Host $UiStrings.ElevateActions
|
|
if ($NeedDeveloperLicense)
|
|
{
|
|
Write-Host $UiStrings.ElevateActionDevLicense
|
|
}
|
|
if ($NeedInstallCertificate)
|
|
{
|
|
Write-Host $UiStrings.ElevateActionCertificate
|
|
}
|
|
|
|
$IsAlreadyElevated = ([Security.Principal.WindowsIdentity]::GetCurrent().Groups.Value -contains "S-1-5-32-544")
|
|
if ($IsAlreadyElevated)
|
|
{
|
|
if ($Force -and $NeedDeveloperLicense)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorForceDeveloperLicense $ErrorCodes.ForceDeveloperLicense
|
|
}
|
|
if ($Force -and $NeedInstallCertificate)
|
|
{
|
|
Write-Warning $UiStrings.WarningInstallCert
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ($Force)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorForceElevate $ErrorCodes.ForceElevate
|
|
}
|
|
else
|
|
{
|
|
Write-Host $UiStrings.ElevateActionsContinue
|
|
Pause
|
|
}
|
|
}
|
|
|
|
LaunchElevated
|
|
}
|
|
|
|
InstallPackageWithDependencies
|
|
}
|
|
|
|
#
|
|
# Main script entry point
|
|
#
|
|
if ($GetDeveloperLicense -or $CertificatePath)
|
|
{
|
|
DoElevatedOperations
|
|
}
|
|
else
|
|
{
|
|
DoStandardOperations
|
|
PrintMessageAndExit $UiStrings.Success $ErrorCodes.Success
|
|
}
|
|
|
|
# SIG # Begin signature block
|
|
# MIIiTwYJKoZIhvcNAQcCoIIiQDCCIjwCAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
|
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
|
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCD5BdpRggDM/3NT
|
|
# wBDQFaER9aOD9SdM3CUzPDQe6F3dFqCCC3YwggT+MIID5qADAgECAhMzAAACz20s
|
|
# xXyqZabYAAAAAALPMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
|
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
|
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
|
|
# bmcgUENBIDIwMTAwHhcNMTkwNTAyMjEyNTQyWhcNMjAwNTAyMjEyNTQyWjB0MQsw
|
|
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
|
|
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
|
|
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
|
# AQC5WvO1XVj5Qw+VAXn6dOWwyrU48JLK7JuZQh066rWPdXWDqRs2/0CWjtd1CtGW
|
|
# rsezdxI5gtnuSHU9R61TOTxp0crY8D8hWkw66Chnw30gU0uci7yT+SBG8FCCym9q
|
|
# Tlbx1EOu2Onbvnx3fUZzAzpk6fYtyyVRDZDJFlkpDBUgY6i4T3AknQHlaZRJydZY
|
|
# qJuJuC/gbhunzJ11CKbIMWUPo+291saTjGYiv0hXHYyhweatkIEpK4pi9MKh28jB
|
|
# eSN0NwiSZeNXAeRPoQr1aJbWCYBKBdyuMNexWvsd+YTeksvywPjqJm7Tc37FZqUF
|
|
# rMTrENoMXHw2mZxZicaUR/a7AgMBAAGjggF9MIIBeTAfBgNVHSUEGDAWBgorBgEE
|
|
# AYI3PQYBBggrBgEFBQcDAzAdBgNVHQ4EFgQUN/NN7E2vLAQxqRCIC1jAbwO8VQgw
|
|
# VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh
|
|
# dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwODY1KzQ1NDI0NDAfBgNVHSMEGDAW
|
|
# gBTm/F97uyIAWORyTrX0IXQjMubvrDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8v
|
|
# Y3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNDb2RTaWdQQ0Ff
|
|
# MjAxMC0wNy0wNi5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRw
|
|
# Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY0NvZFNpZ1BDQV8yMDEw
|
|
# LTA3LTA2LmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQCqMI8I
|
|
# dLEoiAqBDMw46rHAR5p98xk1puiL6RYE5MMy4Sn3zLjwxsMC1bCNC0H+XKkDhiX1
|
|
# JJ+wBMRpCieUBLIJ3BmvuwGLkuTYcgQHcoHTicrXeZhB5aAp+5WR2fiMQCNwmrL2
|
|
# ywp1C70cctf/mCAB3sDN0NOl/2sMi/mFaSIVCddO8sHp1Hin0eNG9j2pBmYRo54v
|
|
# 7+bTxYApyPrTt5gN3KTOhGjrm/sUgyhtIleaRr43ccTs7TiPTW4TVDmHxvQeQd+6
|
|
# hyjawsACpYBSPL2a4mbAXsNW6GUdzNTs9U0FrvOblnvyqTuu4Ls7QpvsILrqHG30
|
|
# aiSPMQE8igpYYWdYMIIGcDCCBFigAwIBAgIKYQxSTAAAAAAAAzANBgkqhkiG9w0B
|
|
# AQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNV
|
|
# BAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAG
|
|
# A1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAw
|
|
# HhcNMTAwNzA2MjA0MDE3WhcNMjUwNzA2MjA1MDE3WjB+MQswCQYDVQQGEwJVUzET
|
|
# MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV
|
|
# TWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQgQ29kZSBT
|
|
# aWduaW5nIFBDQSAyMDEwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
|
|
# 6Q5kUHlntcTj/QkATJ6UrPdWaOpE2M/FWE+ppXZ8bUW60zmStKQe+fllguQX0o/9
|
|
# RJwI6GWTzixVhL99COMuK6hBKxi3oktuSUxrFQfe0dLCiR5xlM21f0u0rwjYzIjW
|
|
# axeUOpPOJj/s5v40mFfVHV1J9rIqLtWFu1k/+JC0K4N0yiuzO0bj8EZJwRdmVMkc
|
|
# vR3EVWJXcvhnuSUgNN5dpqWVXqsogM3Vsp7lA7Vj07IUyMHIiiYKWX8H7P8O7YAS
|
|
# NUwSpr5SW/Wm2uCLC0h31oVH1RC5xuiq7otqLQVcYMa0KlucIxxfReMaFB5vN8sZ
|
|
# M4BqiU2jamZjeJPVMM+VHwIDAQABo4IB4zCCAd8wEAYJKwYBBAGCNxUBBAMCAQAw
|
|
# HQYDVR0OBBYEFOb8X3u7IgBY5HJOtfQhdCMy5u+sMBkGCSsGAQQBgjcUAgQMHgoA
|
|
# UwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQY
|
|
# MBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6
|
|
# Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1
|
|
# dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0
|
|
# dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIw
|
|
# MTAtMDYtMjMuY3J0MIGdBgNVHSAEgZUwgZIwgY8GCSsGAQQBgjcuAzCBgTA9Bggr
|
|
# BgEFBQcCARYxaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL1BLSS9kb2NzL0NQUy9k
|
|
# ZWZhdWx0Lmh0bTBABggrBgEFBQcCAjA0HjIgHQBMAGUAZwBhAGwAXwBQAG8AbABp
|
|
# AGMAeQBfAFMAdABhAHQAZQBtAGUAbgB0AC4gHTANBgkqhkiG9w0BAQsFAAOCAgEA
|
|
# GnTvV08pe8QWhXi4UNMi/AmdrIKX+DT/KiyXlRLl5L/Pv5PI4zSp24G43B4AvtI1
|
|
# b6/lf3mVd+UC1PHr2M1OHhthosJaIxrwjKhiUUVnCOM/PB6T+DCFF8g5QKbXDrMh
|
|
# KeWloWmMIpPMdJjnoUdD8lOswA8waX/+0iUgbW9h098H1dlyACxphnY9UdumOUjJ
|
|
# N2FtB91TGcun1mHCv+KDqw/ga5uV1n0oUbCJSlGkmmzItx9KGg5pqdfcwX7RSXCq
|
|
# tq27ckdjF/qm1qKmhuyoEESbY7ayaYkGx0aGehg/6MUdIdV7+QIjLcVBy78dTMgW
|
|
# 77Gcf/wiS0mKbhXjpn92W9FTeZGFndXS2z1zNfM8rlSyUkdqwKoTldKOEdqZZ14y
|
|
# jPs3hdHcdYWch8ZaV4XCv90Nj4ybLeu07s8n07VeafqkFgQBpyRnc89NT7beBVaX
|
|
# evfpUk30dwVPhcbYC/GO7UIJ0Q124yNWeCImNr7KsYxuqh3khdpHM2KPpMmRM19x
|
|
# HkCvmGXJIuhCISWKHC1g2TeJQYkqFg/XYTyUaGBS79ZHmaCAQO4VgXc+nOBTGBpQ
|
|
# HTiVmx5mMxMnORd4hzbOTsNfsvU9R1O24OXbC2E9KteSLM43Wj5AQjGkHxAIwlac
|
|
# vyRdUQKdannSF9PawZSOB3slcUSrBmrm1MbfI5qWdcUxghYvMIIWKwIBATCBlTB+
|
|
# MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk
|
|
# bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9N
|
|
# aWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDEwAhMzAAACz20sxXyqZabYAAAA
|
|
# AALPMA0GCWCGSAFlAwQCAQUAoIGuMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEE
|
|
# MBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCBD
|
|
# AerId9KHdHY2YUo2JgxX4DBOYZn/OL23opQ4Y8smAjBCBgorBgEEAYI3AgEMMTQw
|
|
# MqAUgBIATQBpAGMAcgBvAHMAbwBmAHShGoAYaHR0cDovL3d3dy5taWNyb3NvZnQu
|
|
# Y29tMA0GCSqGSIb3DQEBAQUABIIBADGTPfGCerJY3hyXU9uXgMgXbhJWidsAnI4d
|
|
# MAwoI/yBxmlg+1Yq4gAFR0wFDqTPbXYTBvQ5OdKjqhxOmS9f0Qf3PY0NYrwdLaQP
|
|
# IjeSrAF3YFbhiyUokgLR78Iy1XQeJxhEquOuH5TA7rvSt4kFkZIlAdwSARSul7JN
|
|
# VXegfxt+PV/tV+P21pqbkYvvjNgBpbVJBO4WY74vPNc/GWI5juH807Lnb3/AGx5D
|
|
# Mg5AGXJnO0sgRrLDxAensCAEmPBDj+ej1mnhhqD86xPQtTvqaPQ/TkFkZfT4AtJR
|
|
# m5eMPwcbjSpCHr/XqKv3R5SyQYnCu4PiLaboMf7JzaYrulkqHAmhghO5MIITtQYK
|
|
# KwYBBAGCNwMDATGCE6UwghOhBgkqhkiG9w0BBwKgghOSMIITjgIBAzEPMA0GCWCG
|
|
# SAFlAwQCAQUAMIIBVwYLKoZIhvcNAQkQAQSgggFGBIIBQjCCAT4CAQEGCisGAQQB
|
|
# hFkKAwEwMTANBglghkgBZQMEAgEFAAQgwBrd2L0fVeiLCvS9/WD0rS16JiEiejGB
|
|
# agB4Lm83Q5oCBl56b8E7rhgSMjAyMDA0MDkyMDU4MDQuMzFaMAcCAQGAAgH0oIHU
|
|
# pIHRMIHOMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
|
|
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSkwJwYD
|
|
# VQQLEyBNaWNyb3NvZnQgT3BlcmF0aW9ucyBQdWVydG8gUmljbzEmMCQGA1UECxMd
|
|
# VGhhbGVzIFRTUyBFU046QkJFQy0zMENBLTJEQkUxJTAjBgNVBAMTHE1pY3Jvc29m
|
|
# dCBUaW1lLVN0YW1wIFNlcnZpY2Wggg8iMIIE9TCCA92gAwIBAgITMwAAAP8vnmsF
|
|
# EdNrlwAAAAAA/zANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UE
|
|
# CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z
|
|
# b2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQ
|
|
# Q0EgMjAxMDAeFw0xOTA5MDYyMDQxMDlaFw0yMDEyMDQyMDQxMDlaMIHOMQswCQYD
|
|
# VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe
|
|
# MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSkwJwYDVQQLEyBNaWNyb3Nv
|
|
# ZnQgT3BlcmF0aW9ucyBQdWVydG8gUmljbzEmMCQGA1UECxMdVGhhbGVzIFRTUyBF
|
|
# U046QkJFQy0zMENBLTJEQkUxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1w
|
|
# IFNlcnZpY2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCuCOuILcP+
|
|
# LfUEqGIrXGvCr+mEFRpy20gxNNMkZI+kViE/rsYH3eItmQfawIndfP1bKp+1J2b3
|
|
# mXXJ7qqwMYlflpc4qTc/HgOByIa3tFmUEWN/jDBKzE9FucFHKgPT8gtEnVGOg9h3
|
|
# ES3zIJj18d+sVVcbpgmutvJKopGl1u9vTNwLxdH3S4t+ov1SgOgsTF0CblJiu/zd
|
|
# iwsQzstk+3nQPjk+DlwfEC5kwOricPV0QMaC/q+Buj+4rBUAvDKb/NvBqRtJptmT
|
|
# 9S5HZOXidFMm2i2SJVK0sEamOw69Jaj1mB5bksyMP0PFttGYVxh02dTBDG6AbmTC
|
|
# Er9bKrgPBjWxAgMBAAGjggEbMIIBFzAdBgNVHQ4EFgQUzhnW8N+xfFZ8o+3bxTZy
|
|
# MEBX1gEwHwYDVR0jBBgwFoAU1WM6XIoxkPNDe3xGG8UzaFqFbVUwVgYDVR0fBE8w
|
|
# TTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVj
|
|
# dHMvTWljVGltU3RhUENBXzIwMTAtMDctMDEuY3JsMFoGCCsGAQUFBwEBBE4wTDBK
|
|
# BggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9N
|
|
# aWNUaW1TdGFQQ0FfMjAxMC0wNy0wMS5jcnQwDAYDVR0TAQH/BAIwADATBgNVHSUE
|
|
# DDAKBggrBgEFBQcDCDANBgkqhkiG9w0BAQsFAAOCAQEApAnaQljuFW4UjErMgHn4
|
|
# LWHVod53qtw/9FERINhT6tH/Ed6n6AzDcfeBdr4taaxo5dB+juWM6nDQwd99kInu
|
|
# Kk7fqRlxd7ZmJlkFQ6MAdLzdJDGXSkS7I3aR7E/pKnBV1Y6gbICuPeM1CTPYSO26
|
|
# ryfWM36/PGu1Iv1JGNkJOG82X2J3SiACPFIzCaexAK4P9bEPc8GhqdHdxc7x0fVe
|
|
# Ow+EvBanHFa82hmz2HC/JMaI4yR7JtRgKjZZTuOIWBqkXmDFcFaTgfFl4jJLdwQC
|
|
# dkMb4wfLgVdc/Jym4nJrqBZFTb0mkAYb6OkK1h6gNobk69mFO5yjDTiw8hPGZRor
|
|
# kjCCBnEwggRZoAMCAQICCmEJgSoAAAAAAAIwDQYJKoZIhvcNAQELBQAwgYgxCzAJ
|
|
# BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k
|
|
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jv
|
|
# c29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEwMB4XDTEwMDcwMTIx
|
|
# MzY1NVoXDTI1MDcwMTIxNDY1NVowfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh
|
|
# c2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBD
|
|
# b3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIw
|
|
# MTAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpHQ28dxGKOiDs/BOX
|
|
# 9fp/aZRrdFQQ1aUKAIKF++18aEssX8XD5WHCdrc+Zitb8BVTJwQxH0EbGpUdzgkT
|
|
# jnxhMFmxMEQP8WCIhFRDDNdNuDgIs0Ldk6zWczBXJoKjRQ3Q6vVHgc2/JGAyWGBG
|
|
# 8lhHhjKEHnRhZ5FfgVSxz5NMksHEpl3RYRNuKMYa+YaAu99h/EbBJx0kZxJyGiGK
|
|
# r0tkiVBisV39dx898Fd1rL2KQk1AUdEPnAY+Z3/1ZsADlkR+79BL/W7lmsqxqPJ6
|
|
# Kgox8NpOBpG2iAg16HgcsOmZzTznL0S6p/TcZL2kAcEgCZN4zfy8wMlEXV4WnAEF
|
|
# TyJNAgMBAAGjggHmMIIB4jAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQU1WM6
|
|
# XIoxkPNDe3xGG8UzaFqFbVUwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYD
|
|
# VR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/oolxi
|
|
# aNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3Nv
|
|
# ZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMu
|
|
# Y3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNy
|
|
# b3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcnQw
|
|
# gaAGA1UdIAEB/wSBlTCBkjCBjwYJKwYBBAGCNy4DMIGBMD0GCCsGAQUFBwIBFjFo
|
|
# dHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vUEtJL2RvY3MvQ1BTL2RlZmF1bHQuaHRt
|
|
# MEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAFAAbwBsAGkAYwB5AF8AUwB0
|
|
# AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQAH5ohRDeLG4Jg/
|
|
# gXEDPZ2joSFvs+umzPUxvs8F4qn++ldtGTCzwsVmyWrf9efweL3HqJ4l4/m87WtU
|
|
# VwgrUYJEEvu5U4zM9GASinbMQEBBm9xcF/9c+V4XNZgkVkt070IQyK+/f8Z/8jd9
|
|
# Wj8c8pl5SpFSAK84Dxf1L3mBZdmptWvkx872ynoAb0swRCQiPM/tA6WWj1kpvLb9
|
|
# BOFwnzJKJ/1Vry/+tuWOM7tiX5rbV0Dp8c6ZZpCM/2pif93FSguRJuI57BlKcWOd
|
|
# eyFtw5yjojz6f32WapB4pm3S4Zz5Hfw42JT0xqUKloakvZ4argRCg7i1gJsiOCC1
|
|
# JeVk7Pf0v35jWSUPei45V3aicaoGig+JFrphpxHLmtgOR5qAxdDNp9DvfYPw4Ttx
|
|
# Cd9ddJgiCGHasFAeb73x4QDf5zEHpJM692VHeOj4qEir995yfmFrb3epgcunCaw5
|
|
# u+zGy9iCtHLNHfS4hQEegPsbiSpUObJb2sgNVZl6h3M7COaYLeqN4DMuEin1wC9U
|
|
# JyH3yKxO2ii4sanblrKnQqLJzxlBTeCG+SqaoxFmMNO7dDJL32N79ZmKLxvHIa9Z
|
|
# ta7cRDyXUHHXodLFVeNp3lfB0d4wwP3M5k37Db9dT+mdHhk4L7zPWAUu7w2gUDXa
|
|
# 7wknHNWzfjUeCLraNtvTX4/edIhJEqGCA7AwggKYAgEBMIH+oYHUpIHRMIHOMQsw
|
|
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
|
|
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSkwJwYDVQQLEyBNaWNy
|
|
# b3NvZnQgT3BlcmF0aW9ucyBQdWVydG8gUmljbzEmMCQGA1UECxMdVGhhbGVzIFRT
|
|
# UyBFU046QkJFQy0zMENBLTJEQkUxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0
|
|
# YW1wIFNlcnZpY2WiJQoBATAJBgUrDgMCGgUAAxUAAjbENWjPNg9MFMx7uLG8Osg6
|
|
# dx2ggd4wgdukgdgwgdUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
|
|
# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
|
|
# b24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMScw
|
|
# JQYDVQQLEx5uQ2lwaGVyIE5UUyBFU046NERFOS0wQzVFLTNFMDkxKzApBgNVBAMT
|
|
# Ik1pY3Jvc29mdCBUaW1lIFNvdXJjZSBNYXN0ZXIgQ2xvY2swDQYJKoZIhvcNAQEF
|
|
# BQACBQDiORpNMCIYDzIwMjAwNDA5MTE1MTQxWhgPMjAyMDA0MTAxMTUxNDFaMHcw
|
|
# PQYKKwYBBAGEWQoEATEvMC0wCgIFAOI5Gk0CAQAwCgIBAAICGdwCAf8wBwIBAAIC
|
|
# GqwwCgIFAOI6a80CAQAwNgYKKwYBBAGEWQoEAjEoMCYwDAYKKwYBBAGEWQoDAaAK
|
|
# MAgCAQACAxbjYKEKMAgCAQACAwehIDANBgkqhkiG9w0BAQUFAAOCAQEABnBMppi9
|
|
# x3/eTqCHWKBAzZuCVn0vSxjDJ8mUsWB3mXddZ/TDcfA2MTqQnwW/xiDx6HNlTdRt
|
|
# Ii/tjOegAiYl1HfPViMQTadFFA3+v38/dWLFPtiZHv4tc9P1E2SQ9IxkDx/2T5zd
|
|
# bLQynB/5HvkGv3PoFp7uT6XmwnM+E7NXGaKPEieId69dlxmrujXD9PdyP4zVTD2A
|
|
# cS70aUYUVJb0yyePQnFP5nbWJLY9l0mZ/4ypxNnlx1GYO7D6z3YW8CBtHvncKEoF
|
|
# sMHdvZSa4uqxxixty1j5ckjPjzEmK94glEetxaRsxfSKYUDmGyM+dRgOhCzQgkjW
|
|
# EWoyoxk1SKmC5TGCAvUwggLxAgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQI
|
|
# EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv
|
|
# ZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBD
|
|
# QSAyMDEwAhMzAAAA/y+eawUR02uXAAAAAAD/MA0GCWCGSAFlAwQCAQUAoIIBMjAa
|
|
# BgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIEINF+cv0h
|
|
# z00XM+ToBhlb8dz+wZuCJW0KI9hnUR0ujeLXMIHiBgsqhkiG9w0BCRACDDGB0jCB
|
|
# zzCBzDCBsQQUAjbENWjPNg9MFMx7uLG8Osg6dx0wgZgwgYCkfjB8MQswCQYDVQQG
|
|
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
|
|
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg
|
|
# VGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAP8vnmsFEdNrlwAAAAAA/zAWBBQN4cP3
|
|
# Lty5AfjYZ0mpFsU2dlUhQTANBgkqhkiG9w0BAQsFAASCAQCOVuvdo4Ol6alhUPSP
|
|
# rhSzI2HiILRARtD8pv1hIaaZBTHhGGTMlqeqQJNsuWqBqFPrfkFSVGsFv0aWfO/S
|
|
# Z2c6hTKvj2JfxoxDpBgfbNBe53CDKI3zKBDqHX/jMs6H+wI1ebDzXROkmp4G7h2R
|
|
# ZyW/0yi9kj8m4mkL8sDNcS/KABoIUxUPyfC+wHN1Tgujpzu6ZeaMJ0vPptI3vX3w
|
|
# hLf6jmMleMS/iMG6iYDfdIEnbeM4OC1X9YC9+CrCnIAyHkjQxBW/NI94oV1e7YGF
|
|
# 4A1Qt3Q+A3kC1Asua6owY2oL/ecKYeGzwsbP2/kU6SWerMObKfbd++xalbf/eCyD
|
|
# xEZ+
|
|
# SIG # End signature block
|