HP.Firmware.SureRecover.psm1
# Copyright (C)2018 HP Inc # All Rights Reserved. # # NOTICE: All information contained herein is, and remains the property of HP Inc. # # The intellectual and technical concepts contained herein are proprietary to HP Inc # and may be covered by U.S. and Foreign Patents, patents in process, and are protected by # trade secret or copyright law. Dissemination of this information or reproduction of this material # is strictly forbidden unless prior written permission is obtained from HP Inc. Set-StrictMode -Version 3.0 $ErrorActionPreference = 'Stop' #requires -Modules "HP.Private" [Flags()] enum DeprovisioningTarget{ AgentProvisioning = 1 OSImageProvisioning = 2 ConfigurationData = 4 TriggerRecoveryData = 8 ScheduleRecoveryData = 16 } # Convert a BIOS value to a boolean function ConvertValue { param($value) if ($value -eq "Enable" -or $value -eq "Yes") { return $true } $false } <# .SYNOPSIS Get the current state of the HP Sure Recover feature .DESCRIPTION This function returns the current state of the HP Sure Recover feature .NOTES - Supported on Windows 10. - Requires HP BIOS with HP Sure Recover support. - This command requires elevated privileges. #> function Get-HPSureRecoverState { [CmdletBinding(HelpUri = "https://developers.hp.com/hp-client-management/doc/Get%E2%80%90HPSureRecoverState")] param([switch]$All) $mi_result = 0 $data = New-Object -TypeName surerecover_state_t $c = '[DfmNativeSureRecover]::get_surerecover_state' + (Test-OSBitness) + '([ref]$data,[ref]$mi_result);' $result = Invoke-Expression -Command $c Test-HPPrivateCustomResult -result 0x80000711 -mi_result $result -Category 0x04 $fixed_version = "$($data.subsystem_version[0]).$($data.subsystem_version[1])" if ($fixed_version -eq "0.0") { Write-Verbose "Patched SURERECOVER version 0.0 to 1.0" $fixed_version = "1.0" } $SchedulerIsDisabled = ($data.schedule.window_size -eq 0) $RecoveryTimeBetweenRetries = ([uint32]$data.os_flags -shr 8) -band 0x0f $RecoveryNumberOfRetries = ([uint32]$data.os_flags -shr 12) -band 0x07 if ($RecoveryNumberOfRetries -eq 0) { $RecoveryNumberOfRetries = "Infinite" } $obj = [ordered]@{ Version = $fixed_version Nonce = $data.Nonce #OsImageIsProvisioned = $data.os_provisioned OsImageFlags = ($data.os_flags -band 0xff) ImageIsProvisioned = (($data.flags -band 2) -ne 0) AgentFlags = ($data.re_flags -band 0xff) AgentIsProvisioned = (($data.flags -band 1) -ne 0) RecoveryTimeBetweenRetries = $RecoveryTimeBetweenRetries RecoveryNumberOfRetries = $RecoveryNumberOfRetries Schedule = New-Object -TypeName PSObject -Property @{ DayOfWeek = $data.schedule.day_of_week Hour = [uint32]$data.schedule.Hour Minute = [uint32]$data.schedule.Minute WindowSize = [uint32]$data.schedule.window_size } ConfigurationDataIsProvisioned = (($data.flags -band 4) -ne 0) TriggerRecoveryDataIsProvisioned = (($data.flags -band 8) -ne 0) ScheduleRecoveryDataIsProvisioned = (($data.flags -band 16) -ne 0) SchedulerIsDisabled = $SchedulerIsDisabled } if ($all.IsPresent) { $ia = [ordered]@{ Url = (Get-HPBiosSettingValue -Name "OS Recovery Image URL") Username = (Get-HPBiosSettingValue -Name "OS Recovery Image Username") #PublicKey = (Get-HPBiosSettingValue -name "OS Recovery Image Public Key") ProvisioningVersion = (Get-HPBiosSettingValue -Name "OS Recovery Image Provisioning Version") } $aa = [ordered]@{ Url = (Get-HPBiosSettingValue -Name "OS Recovery Agent URL") Username = (Get-HPBiosSettingValue -Name "OS Recovery Agent Username") #PublicKey = (Get-HPBiosSettingValue -name "OS Recovery Agent Public Key") ProvisioningVersion = (Get-HPBiosSettingValue -Name "OS Recovery Agent Provisioning Version") } $Image = New-Object -TypeName PSObject -Property $ia $Agent = New-Object -TypeName PSObject -Property $aa $obj.Add("Image",$Image) $obj.Add("Agent",$Agent) } return New-Object -TypeName PSCustomObject -Property $obj } <# .SYNOPSIS Get information about the HP Sure Recover embedded reimaging device. .DESCRIPTION This function returns information about the embedded reimaging device for HP Sure Recover. .NOTES The embedded reimaging device is an optional hardware feature, and if not present, the field Embedded Reimaging Device will be false. .NOTES - Supported on Windows 10. - Requires HP BIOS with HP Sure Recover support - Requires Embedded Reimaging device hardware option - This command requires elevated privileges. #> function Get-HPSureRecoverReimagingDeviceDetails { [CmdletBinding(HelpUri = "https://developers.hp.com/hp-client-management/doc/Get%E2%80%90HPSureRecoverReimagingDeviceDetails")] param() $result = @{} try { [int]$ImageVersion = Get-HPBiosSettingValue -Name "OS Recovery Image Version" $result.Add("ImageVersion",$ImageVersion) } catch {} try { [int]$DriverVersion = Get-HPBiosSettingValue -Name "OS Recovery Driver Version" $result.Add("DriverVersion",$DriverVersion) } catch {} $result.Add("Embedded Reimaging Device",(Test-Path variable:ImageVersion) -and (Test-Path variable:DriverVersion)) $result } <# .SYNOPSIS Configure the HP Sure Recover OS or Recovery image .DESCRIPTION This function defines a custom HP Sure Recover OS or Recovery image. On return, the function writes the created payload to the pipeline, or to the file specified in the OutputFile parameter. This payload can then be passed to the [Set-HPSecurePlatformPayload](Set-HPSecurePlatformPayload) function. <div style="background-color: #ee8; padding:10px;"> <h4>Security note</h4> Payloads should only be created on secure servers. Once created, the payload may be transferred to a client and applied via the <b>Set-HPSecurePlatformPayload</b> . Creating the payload and passing it to the <b>Set-HPSecurePlatformPayload</b> function via the pipeline is not a recommended production pattern. </div> .PARAMETER Image This controls whether this command will create a configuration payload for a Recovery Agent image or a Recovery OS image. .PARAMETER SigningKeyFile The path to the secure platform signing key, as a PFX file. If the PFX file is protected by a password (recommended), the SigningKeyPassword parameter should also be provided. .PARAMETER SigningKeyPassword The secure platform signing key file password, if required. .PARAMETER SigningKeyCertificate The secure platform signing key certificate, as an X509Certificate object. .PARAMETER ImageKeyFile The path to the image signing key, as a PFX file. If the PFX file is protected by a password (recommended), the ImageKeyPassword parameter should also be provided. Depending on the Image switch, this will be either the signing key file for the Agent or the OS image. ImageKeyFile and PublicKeyFile are mutually exclusive. .PARAMETER ImageKeyPassword The image signing key file password, if required. .PARAMETER ImageCertificate The image signing key certificate, as an X509Certificate object. Depending on the Image switch, this will be either the signing key certificate for the Agent or the OS image. .PARAMETER PublicKeyFile The image signing key, as the path to a base64-encoded RSA key (a PEM file). ImageKeyFile and PublicKeyFile are mutually exclusive. .PARAMETER PublicKey The image signing key, as an array of bytes, including modulus and exponent. This option is currently reserved for internal use. .PARAMETER Nonce The operation nonce. In order to prevent replay attacks, the secure platform subsystem will only accept commands with a nonce greater or equal to the last nonce sent. If not specified, the nonce is inferred from the current local time. This works okay in most cases, however this approach has a resolution of seconds, so when doing high volume or parallel operations, it is possible to infer the same counter for two or more commands. In those cases, the caller should use its own nonce derivation and provide it through this parameter. .PARAMETER Version The operation version. Each new configuration payload must increment the last operation payload version, as available in the public WMI setting 'OS Recovery Image Provisioning Version'. If this switch is not provided, the function will read this public wmi setting and increment it, automatically. .PARAMETER Username The username for accessing the url specified in the Url parameter, if any. .PARAMETER Password The password for accessing the url specified in the Url parameter, if any. .PARAMETER Url The url from where to download the image. If not specified, the default HP.COM location will be used. .PARAMETER OutputFile Write the resulting output to the specified file, instead of writing it to the pipeline. .NOTES - Supported on Windows 10. - Requires HP BIOS with HP Sure Recover support .EXAMPLE $payload = New-HPSureRecoverImageConfigurationPayload -SigningKeyFile "$path\signing_key.pfx" -Image OS -ImageKeyFile ` "$path\os.pfx" -username my_http_user -password `s3cr3t` -url "http://my.company.com" ... $payload | Set-HPSecurePlatformPayload #> function New-HPSureRecoverImageConfigurationPayload { [CmdletBinding(DefaultParameterSetName = "SKFileCert_OSFilePem",HelpUri = "https://developers.hp.com/hp-client-management/doc/New%E2%80%90HPSureRecoverImageConfigurationPayload")] param( [Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $true,Position = 0)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $true,Position = 0)] [Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $true,Position = 0)] [Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $true,Position = 0)] [Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $true,Position = 0)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $true,Position = 0)] [Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $true,Position = 0)] [Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $true,Position = 0)] [ValidateSet("os","agent")] [string]$Image, [Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $true,Position = 1)] [Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $true,Position = 1)] [Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $true,Position = 1)] [Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $true,Position = 1)] [System.IO.FileInfo]$SigningKeyFile, [Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $false,Position = 2)] [Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $false,Position = 2)] [Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $false,Position = 2)] [Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $false,Position = 2)] [string]$SigningKeyPassword, [Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $true,Position = 3)] [Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $true,Position = 3)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $true,Position = 3)] [Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $true,Position = 3)] [System.Security.Cryptography.X509Certificates.X509Certificate2]$SigningKeyCertificate, [Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $true,Position = 4)] [Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $true,Position = 4)] [System.IO.FileInfo]$ImageKeyFile, [Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $false,Position = 5)] [Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $false,Position = 5)] [string]$ImageKeyPassword, [Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $true,Position = 6)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $true,Position = 6)] [System.Security.Cryptography.X509Certificates.X509Certificate2]$ImageCertificate, [Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $true,Position = 7)] [Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $true,Position = 7)] [System.IO.FileInfo]$PublicKeyFile, [Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $true,Position = 8)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $true,Position = 8)] [byte[]]$PublicKey, [Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $false,Position = 9)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $false,Position = 9)] [Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $false,Position = 9)] [Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $false,Position = 9)] [Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $false,Position = 9)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $false,Position = 9)] [Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $false,Position = 9)] [Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $false,Position = 9)] [uint32]$Nonce = [math]::Floor([decimal](Get-Date (Get-Date).ToUniversalTime() -UFormat "%s")), [Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $false,Position = 10)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $false,Position = 10)] [Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $false,Position = 10)] [Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $false,Position = 10)] [Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $false,Position = 10)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $false,Position = 10)] [Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $false,Position = 10)] [Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $false,Position = 10)] [uint16]$Version, [Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $false,Position = 11)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $false,Position = 11)] [Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $false,Position = 11)] [Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $false,Position = 11)] [Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $false,Position = 11)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $false,Position = 11)] [Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $false,Position = 11)] [Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $false,Position = 11)] [string]$Username, [Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $false,Position = 12)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $false,Position = 12)] [Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $false,Position = 12)] [Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $false,Position = 12)] [Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $false,Position = 12)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $false,Position = 12)] [Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $false,Position = 12)] [Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $false,Position = 12)] [string]$Password, [Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $false,Position = 13)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $false,Position = 13)] [Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $false,Position = 13)] [Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $false,Position = 13)] [Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $false,Position = 13)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $false,Position = 13)] [Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $false,Position = 13)] [Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $false,Position = 13)] [uri]$Url = "", [Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $false,Position = 14)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $false,Position = 14)] [Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $false,Position = 14)] [Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $false,Position = 14)] [Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $false,Position = 14)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $false,Position = 14)] [Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $false,Position = 14)] [Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $false,Position = 14)] [System.IO.FileInfo]$OutputFile ) Write-Verbose "Creating SureRecover Image provisioning payload" $sk = Get-HPPrivateX509CertCoalesce -File $SigningKeyFile -password $SIgningKeyPassword -cert $SigningKeycertificate -Verbose:$VerbosePreference if ($PublicKeyFile -or $PublicKey) { $osk = Get-HPPrivatePublicKeyCoalesce -file $PublicKeyFile -key $PublicKey -Verbose:$VerbosePreference } else { $osk = Get-HPPrivateX509CertCoalesce -File $ImageKeyFile -password $ImageKeyPassword -cert $ImageCertificate -Verbose:$VerbosePreference } $OKBytes = $osk.Modulus $opaque = New-Object opaque4096_t $opaqueLength = 4096 $mi_result = 0 if (-not $Version) { if ($image -eq "os") { $Version = [uint16](Get-HPBiosSettingValue "OS Recovery Image Provisioning Version") + 1 } else { $Version = [uint16](Get-HPBiosSettingValue "OS Recovery Agent Provisioning Version") + 1 } Write-Verbose "New version number is $version" } $cmd = '[DfmNativeSureRecover]::get_surerecover_provisioning_opaque' + (Test-OSBitness) + '($Nonce, $Version, $OKBytes,$($OKBytes.Count),$Username, $Password, $($Url.ToString()), [ref]$opaque, [ref]$opaqueLength, [ref]$mi_result);' $result = Invoke-Expression -Command $cmd Test-HPPrivateCustomResult -result $result -mi_result $mi_result -Category 0x04 $payload = $opaque.raw[0..($opaqueLength - 1)] $sig = Invoke-HPPrivateSignData -data $payload -Certificate $sk.Full -password $SigningKeyPassword -Verbose:$VerbosePreference [byte[]]$out = $sig + $payload Write-Verbose "Building output document" $output = New-Object -TypeName PortableFileFormat $output.data = $out if ($Image -eq "os") { $output.purpose = "hp:surerecover:provision:os_image" } else { $output.purpose = "hp:surerecover:provision:recovery_image" } Write-Verbose "Provisioning version will be $version" $output.timestamp = Get-Date if ($OutputFile) { Write-Verbose 'Will output to file $OutputFile' $f = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutputFile) $output | ConvertTo-Json -Compress | Out-File -FilePath $f -Encoding utf8 } else { $output | ConvertTo-Json -Compress } } <# .SYNOPSIS Deprovision HP Sure Recover .DESCRIPTION This function create a payload to deprovision the HP Sure Recover feature, or parts thereof. On return, the function writes the created payload to the pipeline, or to the file specified in the OutputFile parameter. This payload can then be passed to the [Set-HPSecurePlatformPayload](Set-HPSecurePlatformPayload) function. <div style="background-color: #ee8; padding:10px;"> <h4>Security note</h4> Payloads should only be created on secure servers. Once created, the payload may be transferred to a client and applied via the <b>Set-HPSecurePlatformPayload</b> . Creating the payload and passing it to the <b>Set-HPSecurePlatformPayload</b> function via the pipeline is not a recommended production pattern. </div> .PARAMETER SigningKeyFile The path to the secure platform signing key, as a PFX file. If the PFX file is protected by a password (recommended), the SigningKeyPassword parameter should also be provided. .PARAMETER SigningKeyPassword The secure platform signing key file password, if required. .PARAMETER SigningKeyCertificate The secure platform signing key certificate, as an X509Certificate object. .PARAMETER Nonce The operation nonce. In order to prevent replay attacks, the secure platform subsystem will only accept commands with a nonce greater or equal to the last nonce sent. If not specified, the nonce is inferred from the current local time. This works okay in most cases, however this approach has a resolution of seconds, so when doing high volume or parallel operations, it is possible to infer the same counter for two or more commands. In those cases, the caller should use its own nonce derivation and provide it through this parameter. .PARAMETER RemoveOnly This parameter allows deprovisioning only specific parts of the Sure Recover subsystem. If not specified, the entire SureRecover is deprovisoned. Possible values are one or more of the following: - AgentProvisioning - remove the Agent provisioning - OSImageProvisioning - remove the OS Image provisioning - ConfigurationData - remove HP SureRecover configuration data - TriggerRecoveryData - remove the HP Sure Recover trigger definition - ScheduleRecoveryData - remove the HP Sure Recover schedule definition .PARAMETER OutputFile Write the resulting output to the specified file, instead of writing it to the pipeline. .NOTES - Supported on Windows 10. - Requires HP BIOS with HP Sure Recover support #> function New-HPSureRecoverDeprovisionPayload { [CmdletBinding(DefaultParameterSetName = "SF",HelpUri = "https://developers.hp.com/hp-client-management/doc/New%E2%80%90HPSureRecoverDeprovisionPayload")] param( [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 0)] [string]$SigningKeyFile, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 1)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 1)] [string]$SigningKeyPassword, [Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 0)] [System.Security.Cryptography.X509Certificates.X509Certificate2]$SigningKeyCertificate, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 3)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 3)] [uint32]$Nonce = [math]::Floor([decimal](Get-Date (Get-Date).ToUniversalTime() -UFormat "%s")), [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 4)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 4)] [DeprovisioningTarget[]]$RemoveOnly, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 5)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 5)] [System.IO.FileInfo]$OutputFile ) Write-Verbose "Creating SureRecover deprovisioning payload" if ($RemoveOnly) { [byte]$target = 0 $RemoveOnly | ForEach-Object { $target = $target -bor $_ } Write-Verbose "Will deprovision only $([string]$RemoveOnly)" } else { [byte]$target = 31 # all five bits Write-Verbose "No deprovisioning filter specified, will deprovision all SureRecover" } $payload = [BitConverter]::GetBytes($nonce) + $target $sk = Get-HPPrivateX509CertCoalesce -File $SigningKeyFile -password $SIgningKeyPassword -cert $SigningKeycertificate -Verbose:$VerbosePreference $sig = Invoke-HPPrivateSignData -data $payload -Certificate $sk.Full -password $SigningKeyPassword -Verbose:$VerbosePreference Write-Verbose "Building output document" $output = New-Object -TypeName PortableFileFormat $output.data = $sig + $payload $output.purpose = "hp:surerecover:deprovision" $output.timestamp = Get-Date if ($OutputFile) { Write-Verbose 'Will output to file $OutputFile' $f = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutputFile) $output | ConvertTo-Json -Compress | Out-File -FilePath $f -Encoding utf8 } else { $output | ConvertTo-Json -Compress } } <# .SYNOPSIS Set HP Sure Recover schedule .DESCRIPTION This function create a payload to set a HP Sure Recover schedule. On return, the function writes the created payload to the pipeline, or to the file specified in the OutputFile parameter. This payload can then be passed to the [Set-HPSecurePlatformPayload](Set-HPSecurePlatformPayload) function. <div style="background-color: #ee8; padding:10px;"> <h4>Security note</h4> Payloads should only be created on secure servers. Once created, the payload may be transferred to a client and applied via the <b>Set-HPSecurePlatformPayload</b> . Creating the payload and passing it to the <b>Set-HPSecurePlatformPayload</b> function via the pipeline is not a recommended production pattern. </div> .PARAMETER SigningKeyFile The path to the secure platform signing key, as a PFX file. If the PFX file is protected by a password (recommended), the SigningKeyPassword parameter should also be provided. .PARAMETER SigningKeyPassword The secure platform signing key file password, if required. .PARAMETER SigningKeyCertificate The secure platform signing key certificate, as an X509Certificate object. .PARAMETER Nonce The operation nonce. In order to prevent replay attacks, the secure platform subsystem will only accept commands with a nonce greater or equal to the last nonce sent. If not specified, the nonce is inferred from the current local time. This works okay in most cases, however this approach has a resolution of seconds, so when doing high volume or parallel operations, it is possible to infer the same counter for two or more commands. In those cases, the caller should use its own nonce derivation and provide it through this parameter. .PARAMETER DayOfWeek Defines the day of the week for the schedule .PARAMETER Hour Defines the hour value for the schedule .PARAMETER Minute Defines the minute of the schedule .PARAMETER WindowSize Defines a windows size for the schedule activation (in minutes), in case the exact configured schedule is missed. By default, the window is zero. The value may not be larger than 4 hours (240 minutes). .PARAMETER OutputFile Write the resulting output to the specified file, instead of writing it to the pipeline. .NOTES - Supported on Windows 10. - Requires HP BIOS with HP Sure Recover support #> function New-HPSureRecoverSchedulePayload { [CmdletBinding(DefaultParameterSetName = "SF",HelpUri = "https://developers.hp.com/hp-client-management/doc/New%E2%80%90HPSureRecoverSchedulePayload")] param( [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 0)] [string]$SigningKeyFile, [Parameter(ValueFromPipeline,ParameterSetName = "SB",Mandatory = $true,Position = 0)] [System.Security.Cryptography.X509Certificates.X509Certificate2]$SigningKeyCertificate, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 1)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 1)] [string]$SigningKeyPassword, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 2)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 2)] [uint32]$Nonce = [math]::Floor([decimal](Get-Date (Get-Date).ToUniversalTime() -UFormat "%s")), [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 3)] [Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 3)] [surerecover_day_of_week]$DayOfWeek, [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 4)] [Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 4)] [ValidateRange(0,23)] [uint32]$Hour, [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 5)] [Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 5)] [ValidateRange(0,59)] [uint32]$Minute, [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 6)] [Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 6)] [ValidateRange(1,240)] [uint32]$WindowSize, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 7)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 7)] [System.IO.FileInfo]$OutputFile ) Write-Verbose "Creating SureRecover scheduling payload" $schedule_data = New-Object -TypeName surerecover_schedule_data_t Write-Verbose "Will set the SureRecover scheduler" $schedule_data.day_of_week = $DayOfWeek $schedule_data.Hour = $Hour $schedule_data.Minute = $Minute $schedule_data.window_size = $WindowSize $schedule = New-Object -TypeName surerecover_schedule_data_payload_t $schedule.schedule = $schedule_data $schedule.Nonce = $Nonce $cmd = New-Object -TypeName surerecover_schedule_payload_t $cmd.data = $schedule [byte[]]$payload = (Convert-HPPrivateObjectToBytes -obj $schedule -Verbose:$VerbosePreference)[0] $sk = Get-HPPrivateX509CertCoalesce -File $SigningKeyFile -password $SIgningKeyPassword -cert $SigningKeycertificate -Verbose:$VerbosePreference $cmd.sig = Invoke-HPPrivateSignData -data $payload -Certificate $sk.Full -password $SigningKeyPassword -Verbose:$VerbosePreference Write-Verbose "Building output document" $output = New-Object -TypeName PortableFileFormat $output.data = (Convert-HPPrivateObjectToBytes -obj $cmd -Verbose:$VerbosePreference)[0] $output.purpose = "hp:surerecover:scheduler" $output.timestamp = Get-Date if ($OutputFile) { Write-Verbose 'Will output to file $OutputFile' $f = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutputFile) $output | ConvertTo-Json -Compress | Out-File -FilePath $f -Encoding utf8 } else { $output | ConvertTo-Json -Compress } } <# .SYNOPSIS Configure HP Sure Recover .DESCRIPTION This function create a payload to configure HP Sure Recover On return, the function writes the created payload to the pipeline, or to the file specified in the OutputFile parameter. This payload can then be passed to the [Set-HPSecurePlatformPayload](Set-HPSecurePlatformPayload) function. <div style="background-color: #ee8; padding:10px;"> <h4>Security note</h4> Payloads should only be created on secure servers. Once created, the payload may be transferred to a client and applied via the <b>Set-HPSecurePlatformPayload</b> . Creating the payload and passing it to the <b>Set-HPSecurePlatformPayload</b> function via the pipeline is not a recommended production pattern. </div> .PARAMETER SigningKeyFile The path to the secure platform signing key, as a PFX file. If the PFX file is protected by a password (recommended), the SigningKeyPassword parameter should also be provided. .PARAMETER SigningKeyPassword The secure platform signing key file password, if required. .PARAMETER SigningKeyCertificate The secure platform signing key certificate, as an X509Certificate object. .PARAMETER Nonce The operation nonce. In order to prevent replay attacks, the secure platform subsystem will only accept commands with a nonce greater or equal to the last nonce sent. If not specified, the nonce is inferred from the current local time. This works okay in most cases, however this approach has a resolution of seconds, so when doing high volume or parallel operations, it is possible to infer the same counter for two or more commands. In those cases, the caller should use its own nonce derivation and provide it through this parameter. .PARAMETER OSImageFlags Defines the imaging flags to set .PARAMETER AgentFlags Defines the agent flags to set .PARAMETER OutputFile Write the resulting output to the specified file, instead of writing it to the pipeline. .NOTES - Supported on Windows 10. - Requires HP BIOS with HP Sure Recover support #> function New-HPSureRecoverConfigurationPayload { [CmdletBinding(DefaultParameterSetName = "SF",HelpUri = "https://developers.hp.com/hp-client-management/doc/New%E2%80%90HPSureRecoverConfigurationPayload")] param( [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 0)] [string]$SigningKeyFile, [Parameter(ValueFromPipeline,ParameterSetName = "SB",Mandatory = $true,Position = 0)] [System.Security.Cryptography.X509Certificates.X509Certificate2]$SigningKeyCertificate, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 1)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 1)] [string]$SigningKeyPassword, [Parameter(ValueFromPipeline,ParameterSetName = "SB",Mandatory = $true,Position = 2)] [byte[]]$SigningKeyModulus, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 3)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 3)] [uint32]$Nonce = [math]::Floor([decimal](Get-Date (Get-Date).ToUniversalTime() -UFormat "%s")), [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 4)] [Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 4)] [surerecover_os_flags]$OSImageFlags, [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 5)] [Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 5)] [ValidateRange(0,23)] [surerecover_re_flags]$AgentFlags, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 6)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 6)] [System.IO.FileInfo]$OutputFile ) $sk = Get-HPPrivateX509CertCoalesce -File $SigningKeyFile -password $SIgningKeyPassword -cert $SigningKeycertificate $data = New-Object -TypeName surerecover_configuration_payload_t $data.os_flags = [uint32]$OSImageFlags $data.re_flags = [uint32]$AgentFlags $data.arp_counter = $Nonce $cmd = New-Object -TypeName surerecover_configuration_t $cmd.data = $data [byte[]]$payload = (Convert-HPPrivateObjectToBytes -obj $data -Verbose:$VerbosePreference)[0] $cmd.sig = Invoke-HPPrivateSignData -data $payload -Certificate $sk.Full -password $SigningKeyPassword -Verbose:$VerbosePreference Write-Verbose "Building output document" $output = New-Object -TypeName PortableFileFormat $output.data = (Convert-HPPrivateObjectToBytes -obj $cmd -Verbose:$VerbosePreference)[0] $output.purpose = "hp:surerecover:configure" $output.timestamp = Get-Date if ($OutputFile) { Write-Verbose 'Will output to file $OutputFile' $f = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutputFile) $output | ConvertTo-Json -Compress | Out-File -FilePath $f -Encoding utf8 } else { $output | ConvertTo-Json -Compress } } <# .SYNOPSIS Trigger HP Sure Recover events .DESCRIPTION This function create a payload to trigger HP Sure Recover On return, the function writes the created payload to the pipeline, or to the file specified in the OutputFile parameter. This payload can then be passed to the [Set-HPSecurePlatformPayload](Set-HPSecurePlatformPayload) function. <div style="background-color: #ee8; padding:10px;"> <h4>Security note</h4> Payloads should only be created on secure servers. Once created, the payload may be transferred to a client and applied via the <b>Set-HPSecurePlatformPayload</b> . Creating the payload and passing it to the <b>Set-HPSecurePlatformPayload</b> function via the pipeline is not a recommended production pattern. </div> .PARAMETER SigningKeyFile The path to the secure platform signing key, as a PFX file. If the PFX file is protected by a password (recommended), the SigningKeyPassword parameter should also be provided. .PARAMETER SigningKeyPassword The secure platform signing key file password, if required. .PARAMETER SigningKeyCertificate The secure platform signing key certificate, as an X509Certificate object. .PARAMETER Nonce The operation nonce. In order to prevent replay attacks, the secure platform subsystem will only accept commands with a nonce greater or equal to the last nonce sent. If not specified, the nonce is inferred from the current local time. This works okay in most cases, however this approach has a resolution of seconds, so when doing high volume or parallel operations, it is possible to infer the same counter for two or more commands. In those cases, the caller should use its own nonce derivation and provide it through this parameter. .PARAMETER Set Indicates this is an operation to set the trigger information. This switch is default, and optional. .PARAMETER Cancel Indicates this is an operation to cancel any existing trigger definition. .PARAMETER ForceAfterReboot Defines how many reboots to count before applying the trigger. If not specified, defaults to 1 (next reboot). .PARAMETER PromptPolicy Defines the prompting policy. If not defined, it will default to prompt before recovery, and on error. .PARAMETER ErasePolicy Defines the erase policy for the imaging process. .PARAMETER OutputFile Write the resulting output to the specified file, instead of writing it to the pipeline. .NOTES - Supported on Windows 10. - Requires HP BIOS with HP Sure Recover support #> function New-HPSureRecoverTriggerRecoveryPayload { [CmdletBinding(DefaultParameterSetName = "SF_Schedule",HelpUri = "https://developers.hp.com/hp-client-management/doc/New%E2%80%90HPSureRecoverTriggerRecoveryPayload")] param( [Parameter(ParameterSetName = "SF_Schedule",Mandatory = $true,Position = 0)] [Parameter(ParameterSetName = "SF_Cancel",Mandatory = $true,Position = 0)] [string]$SigningKeyFile, [Parameter(ParameterSetName = "SF_Schedule",Mandatory = $false,Position = 1)] [Parameter(ParameterSetName = "SF_Cancel",Mandatory = $false,Position = 1)] [string]$SigningKeyPassword, [Parameter(ValueFromPipeline,ParameterSetName = "SB_Schedule",Mandatory = $true,Position = 0)] [Parameter(ValueFromPipeline,ParameterSetName = "SB_Cancel",Mandatory = $true,Position = 0)] [byte[]]$SigningKeyCertificate, [Parameter(ParameterSetName = "SF_Schedule",Mandatory = $false,Position = 3)] [Parameter(ParameterSetName = "SF_Cancel",Mandatory = $false,Position = 3)] [Parameter(ParameterSetName = "SB_Schedule",Mandatory = $false,Position = 3)] [Parameter(ParameterSetName = "SB_Cancel",Mandatory = $false,Position = 3)] [uint32]$Nonce = [math]::Floor([decimal](Get-Date (Get-Date).ToUniversalTime() -UFormat "%s")), [Parameter(ParameterSetName = "SF_Schedule",Mandatory = $false,Position = 4)] [Parameter(ParameterSetName = "SB_Schedule",Mandatory = $false,Position = 4)] [switch]$Set, [Parameter(ParameterSetName = "SF_Cancel",Mandatory = $true,Position = 4)] [Parameter(ParameterSetName = "SB_Cancel",Mandatory = $true,Position = 4)] [switch]$Cancel, [Parameter(ParameterSetName = "SF_Schedule",Mandatory = $false,Position = 6)] [Parameter(ParameterSetName = "SB_Schedule",Mandatory = $false,Position = 6)] [ValidateRange(1,7)] [byte]$ForceAfterReboot = 1, [Parameter(ParameterSetName = "SF_Schedule",Mandatory = $false,Position = 7)] [Parameter(ParameterSetName = "SB_Schedule",Mandatory = $false,Position = 7)] [surerecover_prompt_policy]$PromptPolicy = "PromptBeforeRecovery,PromptOnError", [Parameter(ParameterSetName = "SF_Schedule",Mandatory = $false,Position = 8)] [Parameter(ParameterSetName = "SB_Schedule",Mandatory = $false,Position = 8)] [surerecover_erase_policy]$ErasePolicy = "None", [Parameter(ParameterSetName = "SF_Schedule",Mandatory = $false,Position = 9)] [Parameter(ParameterSetName = "SB_Schedule",Mandatory = $false,Position = 9)] [Parameter(ParameterSetName = "SF_Cancel",Mandatory = $false,Position = 9)] [Parameter(ParameterSetName = "SB_Cancel",Mandatory = $false,Position = 9)] [System.IO.FileInfo]$OutputFile ) $sk = Get-HPPrivateX509CertCoalesce -File $SigningKeyFile -password $SIgningKeyPassword -cert $SigningKeycertificate -Verbose:$VerbosePreference $data = New-Object -TypeName surerecover_trigger_payload_t $data.arp_counter = $Nonce $data.bios_trigger_flags = 0 $output = New-Object -TypeName PortableFileFormat if ($Cancel.IsPresent) { Write-Verbose "Creating payload to cancel trigger" $output.purpose = "hp:surerecover:trigger" $data.bios_trigger_flags = 0 $data.re_trigger_flags = 0 } else { Write-Verbose ("Creating payload to set trigger") $output.purpose = "hp:surerecover:trigger" $data.bios_trigger_flags = [uint32]$ForceAfterReboot $data.re_trigger_flags = [uint32]$PromptPolicy $data.re_trigger_flags = ([uint32]$ErasePolicy -shl 4) -bor $data.re_trigger_flags } $cmd = New-Object -TypeName surerecover_trigger_t $cmd.data = $data [byte[]]$payload = (Convert-HPPrivateObjectToBytes -obj $data -Verbose:$VerbosePreference)[0] $cmd.sig = Invoke-HPPrivateSignData -data $payload -Certificate $sk.Full -password $SigningKeyPassword -Verbose:$VerbosePreference Write-Verbose "Building output document with nonce $([BitConverter]::GetBytes($nonce))" $output.data = (Convert-HPPrivateObjectToBytes -obj $cmd -Verbose:$VerbosePreference)[0] Write-Verbose "Sending document of size $($output.data.length)" $output.timestamp = Get-Date if ($OutputFile) { Write-Verbose 'Will output to file $OutputFile' $f = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutputFile) $output | ConvertTo-Json -Compress | Out-File -FilePath $f -Encoding utf8 } else { $output | ConvertTo-Json -Compress } } <# .SYNOPSIS Flag an embedded device for update, where available. .DESCRIPTION This triggers the embedded reimaging device for update. If the hardware option is not present, the function will throw a NotSupportedException. .NOTES - Supported on Windows 10. - Requires HP BIOS with HP Sure Recover support - Requires Embedded Reimaging device hardware option #> function Invoke-HPSureRecoverTriggerUpdate { [CmdletBinding(HelpUri = "https://developers.hp.com/hp-client-management/doc/New%E2%80%90HPSureRecoverTriggerUpdate")] param() $mi_result = 0 $cmd = '[DfmNativeSureRecover]::raise_surerecover_service_event_opaque' + (Test-OSBitness) + '($null, $null, [ref]$mi_result);' $result = Invoke-Expression -Command $cmd Test-HPPrivateCustomResult -result $result -mi_result $mi_result -Category 0x04 } # SIG # Begin signature block # MIIcNwYJKoZIhvcNAQcCoIIcKDCCHCQCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCN32BqI5miqZl3 # gKcPzsZdrLPkwAAtU7c60nVlGkvvgKCCCo0wggU2MIIEHqADAgECAhAM1s71mz4i # 3j/UnuaI4vzeMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xNTAzBgNV # BAMTLERpZ2lDZXJ0IFNIQTIgSGlnaCBBc3N1cmFuY2UgQ29kZSBTaWduaW5nIENB # MB4XDTE5MDQyMjAwMDAwMFoXDTIwMDQyOTEyMDAwMFowdTELMAkGA1UEBhMCVVMx # EzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVBhbG8gQWx0bzEQMA4GA1UE # ChMHSFAgSW5jLjEZMBcGA1UECxMQSFAgQ3liZXJzZWN1cml0eTEQMA4GA1UEAxMH # SFAgSW5jLjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANEwuTFpw7fQ # 3Ds5fvexal46Gg9TNMvdiJu7qMqDZnDJNl7ECdEPyLxsioGS7/yomOS9RXdXMJOm # tyV4/wIPbBaGC8E2tbLTbQQ4IJbgvC+Vc46vbo+sI8YTG6qBICOovFw9VhUNXXEy # SwHMoBNk8JS8R1slPpJKmNGB10HSatMGaHja0Lbqos0QuEx/tx2OXe+mzepIo66T # dtSv2MfPy2tcVcXIdiJGn7f4otxoj6T9X7hVIl78r5Y2XWHYtDK8KaV1E/qkiNXK # 1Xw5S53zv2VsZl6i1LZwt3d1Q9pUmm1AZe2YdhSGvwMP2LYBJGXIBbyLYnxS4HKB # R7MYZyz7H2kCAwEAAaOCAb8wggG7MB8GA1UdIwQYMBaAFGedDyAJDMyKOuWCRnJi # /PHMkOVAMB0GA1UdDgQWBBSnSAWgK15kcBLxsg4XNsT7ncH29zAOBgNVHQ8BAf8E # BAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwbQYDVR0fBGYwZDAwoC6gLIYqaHR0 # cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItaGEtY3MtZzEuY3JsMDCgLqAshipo # dHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1oYS1jcy1nMS5jcmwwTAYDVR0g # BEUwQzA3BglghkgBhv1sAwswKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGln # aWNlcnQuY29tL0NQUzAIBgZngQwBBAEwgYgGCCsGAQUFBwEBBHwwejAkBggrBgEF # BQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFIGCCsGAQUFBzAChkZodHRw # Oi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEySGlnaEFzc3VyYW5j # ZUNvZGVTaWduaW5nQ0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQAD # ggEBAJQblkFw+UYKYSY2M/CIEpJxZDnf+cDhodKAy+goI3XfExRHhyLu3Gc2ibFB # Y4wyz/sJSfHehtNPYckXxR9k/FB/GfYtEACug9xXxJ+iLxWUNQ4KPt3bXY/kmDxW # D1QXJFLbW5Dop3w/K0DL3fxnjOfYCcxsYodbeEiCJprCdNi3zd6x/J8Y35GDbLA5 # p7RfIAzKrmBLPHFGDWr/jWTfwPfUNz6jYJ51m0Ba9j81kzpxNUD0yBIZXBkVvSkx # A09KxzMSSvxvV9DSqSezQBVgWnl9TbElouYUQwk64i0GzL4lTsphK4rQJJ2uuKtH # wN4E0ibpm0uIqbLhgk+3ic8fHTIwggVPMIIEN6ADAgECAhALfhCQPDhJD/ovZ5qH # oae5MA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdp # Q2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xKzApBgNVBAMTIkRp # Z2lDZXJ0IEhpZ2ggQXNzdXJhbmNlIEVWIFJvb3QgQ0EwHhcNMTMxMDIyMTIwMDAw # WhcNMjgxMDIyMTIwMDAwWjB2MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNl # cnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTUwMwYDVQQDEyxEaWdp # Q2VydCBTSEEyIEhpZ2ggQXNzdXJhbmNlIENvZGUgU2lnbmluZyBDQTCCASIwDQYJ # KoZIhvcNAQEBBQADggEPADCCAQoCggEBALRKXn0HD0HexPV2Fja9cf/PP09zS5zR # Df5Ky1dYXoUW3QIVVJnwjzwvTQJ4EGjI2DVLP8H3Z86YHK4zuS0dpApUk8SFot81 # sfXxPKezNPtdSMlGyWJEvEiZ6yhJU8M9j8AO3jWY6WJR3z1rQGHuBEHaz6dcVpbR # +Uy3RISHmGnlgrkT5lW/yJJwkgoxb3+LMqvPa1qfYsQ+7r7tWaRTfwvxUoiKewpn # JMuQzezSTTRMsOG1n5zG9m8szebKU3QBn2c13jhJLc7tOUSCGXlOGrK1+7t48Elm # p8/6XJZ1kosactn/UJJTzD7CQzIJGoYTaTz7gTIzMmR1cygmHQgwOwcCAwEAAaOC # AeEwggHdMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMBMGA1Ud # JQQMMAoGCCsGAQUFBwMDMH8GCCsGAQUFBwEBBHMwcTAkBggrBgEFBQcwAYYYaHR0 # cDovL29jc3AuZGlnaWNlcnQuY29tMEkGCCsGAQUFBzAChj1odHRwOi8vY2FjZXJ0 # cy5kaWdpY2VydC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3J0 # MIGPBgNVHR8EgYcwgYQwQKA+oDyGOmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9E # aWdpQ2VydEhpZ2hBc3N1cmFuY2VFVlJvb3RDQS5jcmwwQKA+oDyGOmh0dHA6Ly9j # cmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEhpZ2hBc3N1cmFuY2VFVlJvb3RDQS5j # cmwwTwYDVR0gBEgwRjA4BgpghkgBhv1sAAIEMCowKAYIKwYBBQUHAgEWHGh0dHBz # Oi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCgYIYIZIAYb9bAMwHQYDVR0OBBYEFGed # DyAJDMyKOuWCRnJi/PHMkOVAMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSYJhoIAu9j # ZCvDMA0GCSqGSIb3DQEBCwUAA4IBAQBqDv9+E3wGpUvALoz5U2QJ4rpYkTBQ7Myf # 4dOoL0hGNhgp0HgoX5hWQA8eur2xO4dc3FvYIA3tGhZN1REkIUvxJ2mQE+sRoQHa # /bVOeVl1vTgqasP2jkEriqKL1yxRUdmcoMjjTrpsqEfSTtFoH4wCVzuzKWqOaiAq # ufIAYmS6yOkA+cyk1LqaNdivLGVsFnxYId5KMND66yRdBsmdFretSkXTJeIM8ECq # XE2sfs0Ggrl2RmkI2DK2gv7jqVg0QxuOZ2eXP2gxFjY4lT6H98fDr516dxnZ3pO1 # /W4r/JT5PbdMEjUsML7ojZ4FcJpIE/SM1ucerDjnqPOtDLd67GftMYIRADCCEPwC # AQEwgYowdjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcG # A1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTE1MDMGA1UEAxMsRGlnaUNlcnQgU0hBMiBI # aWdoIEFzc3VyYW5jZSBDb2RlIFNpZ25pbmcgQ0ECEAzWzvWbPiLeP9Se5oji/N4w # DQYJYIZIAWUDBAIBBQCgfDAQBgorBgEEAYI3AgEMMQIwADAZBgkqhkiG9w0BCQMx # DAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkq # hkiG9w0BCQQxIgQgqcSHg+eP0UU7GL4FeY4TI5aKNpm1uybHwOmizUVNc74wDQYJ # KoZIhvcNAQEBBQAEggEAYjpycwgnL/0bdit1VaMM+eMQNQU4hfyOoskTfLrQHTpZ # W+U7Yf4Hnq3FI++CU19k0EGRLyT59J+Vq6tFjiqcf3f7o0/8v4UP/JNM+yMnhQBT # M2bxLn5C9BTzpge5fXwdvklXkBxlrGtCz9oS6xq+qPVSB1/ZM8hQAwKUClbXfLSR # ciTQutNXS562mO/rSnv290GDqIgKUCKqiyBzIPJqldrIAJpVhUIDyKS5WXP9YUfa # qKlQ/e3E0sUXkH1Efvt/MTIV5oNildGdXsg0zfVkqg5B3q/iguJHI3CafgRMD1af # tXH4yERFj7xaULS9maWy7GIpR42y02OqRFdaPNvEq6GCDsgwgg7EBgorBgEEAYI3 # AwMBMYIOtDCCDrAGCSqGSIb3DQEHAqCCDqEwgg6dAgEDMQ8wDQYJYIZIAWUDBAIB # BQAwdwYLKoZIhvcNAQkQAQSgaARmMGQCAQEGCWCGSAGG/WwHATAxMA0GCWCGSAFl # AwQCAQUABCCOjwhP2butZUsYAK20tgnmRRkzXhbxQ9BMILoMz6dlIAIQF5lPI/0Z # sM0WuI5D8mpeABgPMjAyMDAyMTQyMjU3NDFaoIILuzCCBoIwggVqoAMCAQICEATN # P4VornbGG7D+cWDMp20wDQYJKoZIhvcNAQELBQAwcjELMAkGA1UEBhMCVVMxFTAT # BgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEx # MC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBD # QTAeFw0xOTEwMDEwMDAwMDBaFw0zMDEwMTcwMDAwMDBaMEwxCzAJBgNVBAYTAlVT # MRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjEkMCIGA1UEAxMbVElNRVNUQU1QLVNI # QTI1Ni0yMDE5LTEwLTE1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA # 6WQ1nPqpmGVkG+QX3LgpNsxnCViFTTDgyf/lOzwRKFCvBzHiXQkYwvaJjGkIBCPg # dy2dFeW46KFqjv/UrtJ6Fu/4QbUdOXXBzy+nrEV+lG2sAwGZPGI+fnr9RZcxtPq3 # 2UI+p1Wb31pPWAKoMmkiE76Lgi3GmKtrm7TJ8mURDHQNsvAIlnTE6LJIoqEUpfj6 # 4YlwRDuN7/uk9MO5vRQs6wwoJyWAqxBLFhJgC2kijE7NxtWyZVkh4HwsEo1wDo+K # yuDT17M5d1DQQiwues6cZ3o4d1RA/0+VBCDU68jOhxQI/h2A3dDnK3jqvx9wxu5C # FlM2RZtTGUlinXoCm5UUowIDAQABo4IDODCCAzQwDgYDVR0PAQH/BAQDAgeAMAwG # A1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwggG/BgNVHSAEggG2 # MIIBsjCCAaEGCWCGSAGG/WwHATCCAZIwKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3 # LmRpZ2ljZXJ0LmNvbS9DUFMwggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAA # dQBzAGUAIABvAGYAIAB0AGgAaQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAA # YwBvAG4AcwB0AGkAdAB1AHQAZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8A # ZgAgAHQAaABlACAARABpAGcAaQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4A # ZAAgAHQAaABlACAAUgBlAGwAeQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUA # ZQBtAGUAbgB0ACAAdwBoAGkAYwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwA # aQB0AHkAIABhAG4AZAAgAGEAcgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQA # IABoAGUAcgBlAGkAbgAgAGIAeQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZI # AYb9bAMVMB8GA1UdIwQYMBaAFPS24SAd/imu0uRhpbKiJbLIFzVuMB0GA1UdDgQW # BBRWUw/BxgenTdfYbldygFBM5OyewTBxBgNVHR8EajBoMDKgMKAuhixodHRwOi8v # Y3JsMy5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVkLXRzLmNybDAyoDCgLoYsaHR0 # cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC10cy5jcmwwgYUGCCsG # AQUFBwEBBHkwdzAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t # ME8GCCsGAQUFBzAChkNodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNl # cnRTSEEyQXNzdXJlZElEVGltZXN0YW1waW5nQ0EuY3J0MA0GCSqGSIb3DQEBCwUA # A4IBAQAug6FEBUoE47kyUvrZgfAau/gJjSO5PdiSoeZGHEovbno8Y243F6Mav1gj # skOclINOOQmwLOjH4eLM7ct5a87eIwFH7ZVUgeCAexKxrwKGqTpzav74n8GN0SGM # 5CmCw4oLYAACnR9HxJ+0CmhTf1oQpvgi5vhTkjFf2IKDLW0TQq6DwRBOpCT0R5ze # DyJyd1x/T+k5mCtXkkTX726T2UPHBDNjUTdWnkcEEcOjWFQh2OKOVtdJP1f8Cp8j # Xnv0lI3dnRq733oqptJFplUMj/ZMivKWz4lG3DGykZCjXzMwYFX1/GswrKHt5EdO # M55naii1TcLtW5eC+MupCGxTCbT3MIIFMTCCBBmgAwIBAgIQCqEl1tYyG35B5AXa # NpfCFTANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGln # aUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtE # aWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMTYwMTA3MTIwMDAwWhcNMzEw # MTA3MTIwMDAwWjByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5j # MRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBT # SEEyIEFzc3VyZWQgSUQgVGltZXN0YW1waW5nIENBMIIBIjANBgkqhkiG9w0BAQEF # AAOCAQ8AMIIBCgKCAQEAvdAy7kvNj3/dqbqCmcU5VChXtiNKxA4HRTNREH3Q+X1N # aH7ntqD0jbOI5Je/YyGQmL8TvFfTw+F+CNZqFAA49y4eO+7MpvYyWf5fZT/gm+vj # RkcGGlV+Cyd+wKL1oODeIj8O/36V+/OjuiI+GKwR5PCZA207hXwJ0+5dyJoLVOOo # CXFr4M8iEA91z3FyTgqt30A6XLdR4aF5FMZNJCMwXbzsPGBqrC8HzP3w6kfZiFBe # /WZuVmEnKYmEUeaC50ZQ/ZQqLKfkdT66mA+Ef58xFNat1fJky3seBdCEGXIX8RcG # 7z3N1k3vBkL9olMqT4UdxB08r8/arBD13ays6Vb/kwIDAQABo4IBzjCCAcowHQYD # VR0OBBYEFPS24SAd/imu0uRhpbKiJbLIFzVuMB8GA1UdIwQYMBaAFEXroq/0ksuC # MS1Ri6enIZ3zbcgPMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGG # MBMGA1UdJQQMMAoGCCsGAQUFBwMIMHkGCCsGAQUFBwEBBG0wazAkBggrBgEFBQcw # AYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRwOi8v # Y2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3J0 # MIGBBgNVHR8EejB4MDqgOKA2hjRodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGln # aUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMDqgOKA2hjRodHRwOi8vY3JsMy5kaWdp # Y2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMFAGA1UdIARJMEcw # OAYKYIZIAYb9bAACBDAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy # dC5jb20vQ1BTMAsGCWCGSAGG/WwHATANBgkqhkiG9w0BAQsFAAOCAQEAcZUS6VGH # VmnN793afKpjerN4zwY3QITvS4S/ys8DAv3Fp8MOIEIsr3fzKx8MIVoqtwU0HWqu # mfgnoma/Capg33akOpMP+LLR2HwZYuhegiUexLoceywh4tZbLBQ1QwRostt1AuBy # x5jWPGTlH0gQGF+JOGFNYkYkh2OMkVIsrymJ5Xgf1gsUpYDXEkdws3XVk4WTfraS # Z/tTYYmo9WuWwPRYaQ18yAGxuSh1t5ljhSKMYcp5lH5Z/IwP42+1ASa2bKXuh1Eh # 5Fhgm7oMLSttosR+u8QlK0cCCHxJrhO24XxCQijGGFbPQTS2Zl22dHv1VjMiLyI2 # skuiSpXY9aaOUjGCAk0wggJJAgEBMIGGMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNV # BAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBUaW1lc3RhbXBpbmcgQ0ECEATN # P4VornbGG7D+cWDMp20wDQYJYIZIAWUDBAIBBQCggZgwGgYJKoZIhvcNAQkDMQ0G # CyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yMDAyMTQyMjU3NDFaMCsGCyqG # SIb3DQEJEAIMMRwwGjAYMBYEFAMlvVBe2pYwLcIvT6AeTCi+KDTFMC8GCSqGSIb3 # DQEJBDEiBCCv7sodtsV5XTTlL1kHNzjb1fWy/NQe7R1NQFEMJ8bOHTANBgkqhkiG # 9w0BAQEFAASCAQCRRCO5FGtqA30EM+k5wUZ/x47CYB91XOJij1rh+RXojylhDLAM # QX/Qj8VtLJOdGH7dh+Z/kp2rfOQuji39ofIPHIIUeL6FZRbFcOq0HEI8xZIYxrUe # /XQmIL3jliF53gmaF9L64kN1fWdV74FDe2Jh+bP1xV0ddzwOcgB4Y5nWVaVZmrd4 # cL4SCPIV72Fqk3+eiziECXcq7xptYyMLOYS4VtfNe+0633JUJ6WlBiTaXm1MUycz # c5o4oOqQr0ely8F+w8bPRUnsPF9haKQ3q039V3lAfXNnW1UFd1/gICpI3Xzgm5NN # Ec+axCTCl04l8Ds/J8vps7U7c37uvDbpSvqB # SIG # End signature block |