HP.Firmware.SureRecover.psm1
# # Copyright 2018-2022 HP Development Company, L.P. # All Rights Reserved. # # NOTICE: All information contained herein is, and remains the property of HP Development Company, L.P. # # The intellectual and technical concepts contained herein are proprietary to HP Development Company, L.P # 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 Development Company, L.P. 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 .PARAMETER All If specified, the output includes the OS Recovery Image and OS Recovery Agent configuration. .NOTES - Requires HP BIOS with HP Sure Recover support. - This command requires elevated privileges. .LINK [Blog post: HP Secure Platform Management with the HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/hp-secure-platform-management-hp-client-management-script-library) .LINK [Blog post: Provisioning and Configuring HP Sure Recover with HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/provisioning-and-configuring-hp-sure-recover-hp-client-management-script-library) .EXAMPLE Get-HPSureRecoverState #> function Get-HPSureRecoverState { [CmdletBinding(HelpUri = "https://developers.hp.com/hp-client-management/doc/Get-HPSureRecoverState")] 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 $mi_result -Category 0x05 -Verbose:$VerbosePreference $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" } $imageFailoverIsConfigured = [bool]$data.image_failover $obj = [ordered]@{ Version = $fixed_version Nonce = $data.Nonce BIOSFlags = ($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 ImageFailoverIsConfigured = $imageFailoverIsConfigured } 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) $osFailover = New-Object System.Collections.Generic.List[PSCustomObject] if ($imageFailoverIsConfigured) { try { $osFailoverIndex = Get-HPSureRecoverFailoverConfiguration -Image 'os' $osFailover.Add($osFailoverIndex) } catch { Write-Warning "Error reading OS Failover configuration $($Index): $($_.Exception.Message)" } $obj.Add("ImageFailover",$osFailover) } $obj.Add("Agent",$Agent) } return New-Object -TypeName PSCustomObject -Property $obj } <# .SYNOPSIS Read HP Sure Recover Failover configuration .DESCRIPTION This function returns the current configuration of the HP Sure Recover failover feature .PARAMETER Image This controls whether this command will create a configuration payload for a Recovery Agent image or a Recovery OS image. For now, only 'os' is supported. .NOTES - Requires HP BIOS with HP Sure Recover and Failover support. - This command requires elevated privileges. .EXAMPLE Get-HPSureRecoverFailoverConfiguration -Image os #> function Get-HPSureRecoverFailoverConfiguration { [CmdletBinding(HelpUri = "https://developers.hp.com/hp-client-management/doc/Get-HPSureRecoverFailoverConfiguration")] param( [ValidateSet("os")] [Parameter(Mandatory = $false,Position = 0)] [string]$Image = 'os' ) $mi_result = 0 $data = New-Object -TypeName surerecover_failover_configuration_t $index = 1 $c = '[DfmNativeSureRecover]::get_surerecover_failover_configuration' + (Test-OSBitness) + '([bool]$False,[int]$index,[ref]$data,[ref]$mi_result);' try { $result = Invoke-Expression -Command $c Test-HPPrivateCustomResult -result $result -mi_result $mi_result -Category 0x05 -Verbose:$VerbosePreference } catch { Write-Error "Failover is not configured properly. Error: $($_.Exception.Message)" } return [PSCustomObject]@{ Index = $Index Version = $data.version Url = $data.url Username = $data.username } } <# .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 - Requires HP BIOS with HP Sure Recover support - Requires Embedded Reimaging device hardware option - This command requires elevated privileges. .LINK [Blog post: HP Secure Platform Management with the HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/hp-secure-platform-management-hp-client-management-script-library) .LINK [Blog post: Provisioning and Configuring HP Sure Recover with HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/provisioning-and-configuring-hp-sure-recover-hp-client-management-script-library) .EXAMPLE Get-HPSureRecoverReimagingDeviceDetails #> function Get-HPSureRecoverReimagingDeviceDetails { [CmdletBinding(HelpUri = "https://developers.hp.com/hp-client-management/doc/Get-HPSureRecoverReimagingDeviceDetails")] 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 function. Security note: Payloads should only be created on secure servers. Once created, the payload may be transferred to a client and applied via the Set-HPSecurePlatformPayload. Creating the payload and passing it to the Set-HPSecurePlatformPayload function via the pipeline is not a recommended production pattern. .PARAMETER Image This controls whether this command will create a configuration payload for a Recovery Agent image or a Recovery OS image. The parameter value may be 'agent' or 'os'. .PARAMETER SigningKeyFile The path to the Secure Platform Management 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 Management signing key file password, if required. .PARAMETER SigningKeyCertificate The Secure Platform Management signing key certificate, as an X509Certificate object. .PARAMETER ImageCertificateFile The path to the image signing certificate, as a PFX file. If the PFX file is protected by a password (recommended), the ImageCertificatePassword 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. ImageCertificateFile and PublicKeyFile are mutually exclusive. .PARAMETER ImageCertificatePassword 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). ImageCertificateFile 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 Management 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. .PARAMETER RemoteSigningServiceKeyID The Signing Key ID to be used. .PARAMETER RemoteSigningServiceURL The KMS server URL (I.e.: https://<KMSAppName>.azurewebsites.net/). .PARAMETER CacheAccessToken This parameter should be specified for caching the access token when performing multiple operations on the KMS server, if not cached user have to re-enter credentials on each call of this function. If specified, the access token is cached in msalcache.dat file and user's credentials won't be asked again until it expires. .NOTES - Requires HP BIOS with HP Sure Recover support .LINK [Blog post: HP Secure Platform Management with the HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/hp-secure-platform-management-hp-client-management-script-library) .LINK [Blog post: Provisioning and Configuring HP Sure Recover with HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/provisioning-and-configuring-hp-sure-recover-hp-client-management-script-library) .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-HPSureRecoverImageConfigurationPayload")] 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)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $true,Position = 0)] [Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $true,Position = 0)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $true,Position = 0)] [Parameter(ParameterSetName = "RemoteSigning_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)] [Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $true,Position = 1)] [Alias("ImageKeyFile")] [System.IO.FileInfo]$ImageCertificateFile, [Parameter(ParameterSetName = "SKFileCert_OSFileCert",Mandatory = $false,Position = 5)] [Parameter(ParameterSetName = "SKBytesCert_OSFileCert",Mandatory = $false,Position = 5)] [Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $false,Position = 2)] [Alias("ImageKeyPassword")] [string]$ImageCertificatePassword, [Parameter(ParameterSetName = "SKFileCert_OSBytesCert",Mandatory = $true,Position = 6)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesCert",Mandatory = $true,Position = 6)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $true,Position = 1)] [System.Security.Cryptography.X509Certificates.X509Certificate2]$ImageCertificate, [Parameter(ParameterSetName = "SKFileCert_OSFilePem",Mandatory = $true,Position = 7)] [Parameter(ParameterSetName = "SKBytesCert_OSFilePem",Mandatory = $true,Position = 7)] [Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $true,Position = 1)] [System.IO.FileInfo]$PublicKeyFile, [Parameter(ParameterSetName = "SKFileCert_OSBytesPem",Mandatory = $true,Position = 8)] [Parameter(ParameterSetName = "SKBytesCert_OSBytesPem",Mandatory = $true,Position = 8)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $true,Position = 1)] [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)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $false,Position = 2)] [Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $false,Position = 3)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $false,Position = 2)] [Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $false,Position = 2)] [uint32]$Nonce = [math]::Floor([decimal](Get-Date (Get-Date).ToUniversalTime() -UFormat "%s").Replace(',','.')), [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)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $false,Position = 3)] [Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $false,Position = 4)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $false,Position = 3)] [Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $false,Position = 3)] [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)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $false,Position = 4)] [Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $false,Position = 5)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $false,Position = 4)] [Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $false,Position = 4)] [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)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $false,Position = 5)] [Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $false,Position = 6)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $false,Position = 5)] [Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $false,Position = 5)] [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)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $false,Position = 6)] [Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $false,Position = 7)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $false,Position = 6)] [Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $false,Position = 6)] [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)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $false,Position = 7)] [Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $false,Position = 8)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $false,Position = 7)] [Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $false,Position = 7)] [System.IO.FileInfo]$OutputFile, [Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $true,Position = 8)] [Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $true,Position = 9)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $true,Position = 8)] [Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $true,Position = 8)] [string]$RemoteSigningServiceKeyID, [Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $true,Position = 9)] [Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $true,Position = 10)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $true,Position = 9)] [Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $true,Position = 9)] [string]$RemoteSigningServiceURL, [Parameter(ParameterSetName = "RemoteSigning_OSBytesCert",Mandatory = $false,Position = 10)] [Parameter(ParameterSetName = "RemoteSigning_OSFileCert",Mandatory = $false,Position = 11)] [Parameter(ParameterSetName = "RemoteSigning_OSBytesPem",Mandatory = $false,Position = 10)] [Parameter(ParameterSetName = "RemoteSigning_OSFilePem",Mandatory = $false,Position = 10)] [switch]$CacheAccessToken ) Write-Verbose "Creating SureRecover Image provisioning payload" if ($PublicKeyFile -or $PublicKey) { $osk = Get-HPPrivatePublicKeyCoalesce -File $PublicKeyFile -key $PublicKey -Verbose:$VerbosePreference } else { $osk = Get-HPPrivateX509CertCoalesce -File $ImageCertificateFile -password $ImageCertificatePassword -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 0x05 $payload = $opaque.raw[0..($opaqueLength - 1)] if ($PSCmdlet.ParameterSetName -eq "RemoteSigning_OSBytesCert" -or $PSCmdlet.ParameterSetName -eq "RemoteSigning_OSFileCert" -or $PSCmdlet.ParameterSetName -eq "RemoteSigning_OSBytesPem" -or $PSCmdlet.ParameterSetName -eq "RemoteSigning_OSFilePem") { $sig = Invoke-HPPrivateRemoteSignData -Data $payload -CertificateId $RemoteSigningServiceKeyID -KMSUri $RemoteSigningServiceURL -CacheAccessToken:$CacheAccessToken -Verbose:$VerbosePreference } else { $sk = Get-HPPrivateX509CertCoalesce -File $SigningKeyFile -password $SigningKeyPassword -cert $SigningKeycertificate -Verbose:$VerbosePreference $sig = Invoke-HPPrivateSignData -Data $payload -Certificate $sk.Full -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 function. Security note: Payloads should only be created on secure servers. Once created, the payload may be transferred to a client and applied via the Set-HPSecurePlatformPayload. Creating the payload and passing it to the Set-HPSecurePlatformPayload function via the pipeline is not a recommended production pattern. .PARAMETER SigningKeyFile The path to the Secure Platform Management 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 Management signing key file password, if required. .PARAMETER SigningKeyCertificate The Secure Platform Management signing key certificate, as an X509Certificate object. .PARAMETER Nonce The operation nonce. In order to prevent replay attacks, the Secure Platform Management 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. .PARAMETER RemoteSigningServiceKeyID The Signing Key ID to be used. .PARAMETER RemoteSigningServiceURL The KMS server URL (I.e.: https://<KMSAppName>.azurewebsites.net/). .PARAMETER CacheAccessToken This parameter should be specified for caching the access token when performing multiple operations on the KMS server, if not cached user have to re-enter credentials on each call of this function. If specified, the access token is cached in msalcache.dat file and user's credentials won't be asked again until it expires. .LINK [Blog post: HP Secure Platform Management with the HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/hp-secure-platform-management-hp-client-management-script-library) .LINK [Blog post: Provisioning and Configuring HP Sure Recover with HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/provisioning-and-configuring-hp-sure-recover-hp-client-management-script-library) .NOTES - Requires HP BIOS with HP Sure Recover support .EXAMPLE New-HPSureRecoverDeprovisionPayload -SigningKeyFile sk.pfx #> function New-HPSureRecoverDeprovisionPayload { [CmdletBinding(DefaultParameterSetName = "SF",HelpUri = "https://developers.hp.com/hp-client-management/doc/New-HPSureRecoverDeprovisionPayload")] param( [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 0)] [System.IO.FileInfo]$SigningKeyFile, [Parameter(ParameterSetName = "SF",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)] [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 0)] [uint32]$Nonce = [math]::Floor([decimal](Get-Date (Get-Date).ToUniversalTime() -UFormat "%s").Replace(',','.')), [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 4)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 4)] [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 1)] [DeprovisioningTarget[]]$RemoveOnly, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 5)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 5)] [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 2)] [System.IO.FileInfo]$OutputFile, [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 3)] [string]$RemoteSigningServiceKeyID, [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 4)] [string]$RemoteSigningServiceURL, [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 5)] [switch]$CacheAccessToken ) 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 if ($PSCmdlet.ParameterSetName -eq "RemoteSigning") { $sig = Invoke-HPPrivateRemoteSignData -Data $payload -CertificateId $RemoteSigningServiceKeyID -KMSUri $RemoteSigningServiceURL -CacheAccessToken:$CacheAccessToken -Verbose:$VerbosePreference } else { $sk = Get-HPPrivateX509CertCoalesce -File $SigningKeyFile -password $SigningKeyPassword -cert $SigningKeycertificate -Verbose:$VerbosePreference $sig = Invoke-HPPrivateSignData -Data $payload -Certificate $sk.Full -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 function. Security note: Payloads should only be created on secure servers. Once created, the payload may be transferred to a client and applied via the Set-HPSecurePlatformPayload. Creating the payload and passing it to the Set-HPSecurePlatformPayload function via the pipeline is not a recommended production pattern. .PARAMETER SigningKeyFile The path to the Secure Platform Management 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 Management signing key file password, if required. .PARAMETER SigningKeyCertificate The Secure Platform Management signing key certificate, as an X509Certificate object. .PARAMETER Nonce The operation nonce. In order to prevent replay attacks, the Secure Platform Management 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. .PARAMETER RemoteSigningServiceKeyID The Signing Key ID to be used. .PARAMETER RemoteSigningServiceURL The KMS server URL (I.e.: https://<KMSAppName>.azurewebsites.net/). .PARAMETER CacheAccessToken This parameter should be specified for caching the access token when performing multiple operations on the KMS server, if not cached user have to re-enter credentials on each call of this function. If specified, the access token is cached in msalcache.dat file and user's credentials won't be asked again until it expires. .LINK [Blog post: HP Secure Platform Management with the HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/hp-secure-platform-management-hp-client-management-script-library) .LINK [Blog post: Provisioning and Configuring HP Sure Recover with HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/provisioning-and-configuring-hp-sure-recover-hp-client-management-script-library) .NOTES - Requires HP BIOS with HP Sure Recover support .EXAMPLE New-HPSureRecoverSchedulePayload -SigningKeyFile sk.pfx -DayOfWeek Sunday -Hour 2 #> function New-HPSureRecoverSchedulePayload { [CmdletBinding(DefaultParameterSetName = "SF",HelpUri = "https://developers.hp.com/hp-client-management/doc/New-HPSureRecoverSchedulePayload")] param( [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 0)] [System.IO.FileInfo]$SigningKeyFile, [Parameter(ValueFromPipeline,ParameterSetName = "SB",Mandatory = $true,Position = 0)] [System.Security.Cryptography.X509Certificates.X509Certificate2]$SigningKeyCertificate, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 1)] [string]$SigningKeyPassword, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 2)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 2)] [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 0)] [uint32]$Nonce = [math]::Floor([decimal](Get-Date (Get-Date).ToUniversalTime() -UFormat "%s").Replace(',','.')), [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 3)] [Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 3)] [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 1)] [surerecover_day_of_week]$DayOfWeek, [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 4)] [Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 4)] [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 2)] [ValidateRange(0,23)] [uint32]$Hour, [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 5)] [Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 5)] [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 3)] [ValidateRange(0,59)] [uint32]$Minute, [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 6)] [Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 6)] [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 4)] [ValidateRange(1,240)] [uint32]$WindowSize, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 7)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 7)] [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 5)] [System.IO.FileInfo]$OutputFile, [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 6)] [string]$RemoteSigningServiceKeyID, [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 7)] [string]$RemoteSigningServiceURL, [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 8)] [switch]$CacheAccessToken ) 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] if ($PSCmdlet.ParameterSetName -eq "RemoteSigning") { $cmd.sig = Invoke-HPPrivateRemoteSignData -Data $payload -CertificateId $RemoteSigningServiceKeyID -KMSUri $RemoteSigningServiceURL -CacheAccessToken:$CacheAccessToken -Verbose:$VerbosePreference } else { $sk = Get-HPPrivateX509CertCoalesce -File $SigningKeyFile -password $SigningKeyPassword -cert $SigningKeycertificate -Verbose:$VerbosePreference $cmd.sig = Invoke-HPPrivateSignData -Data $payload -Certificate $sk.Full -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 function. Security note: Payloads should only be created on secure servers. Once created, the payload may be transferred to a client and applied via the Set-HPSecurePlatformPayload. Creating the payload and passing it to the Set-HPSecurePlatformPayload function via the pipeline is not a recommended production pattern. .PARAMETER SigningKeyFile The path to the Secure Platform Management 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 Management signing key file password, if required. .PARAMETER SigningKeyCertificate The Secure Platform Management signing key certificate, as an X509Certificate object. .PARAMETER SigningKeyModulus The Secure Platform Management signing key modulus .PARAMETER Nonce The operation nonce. In order to prevent replay attacks, the Secure Platform Management 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 BIOSFlags Defines the imaging flags to set. This parameter was previously named OSImageFlags, .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. .PARAMETER RemoteSigningServiceKeyID The Signing Key ID to be used. .PARAMETER RemoteSigningServiceURL The KMS server URL (I.e.: https://<KMSAppName>.azurewebsites.net/). .PARAMETER CacheAccessToken This parameter should be specified for caching the access token when performing multiple operations on the KMS server, if not cached user have to re-enter credentials on each call of this function. If specified, the access token is cached in msalcache.dat file and user's credentials won't be asked again until it expires. .LINK [Blog post: HP Secure Platform Management with the HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/hp-secure-platform-management-hp-client-management-script-library) .LINK [Blog post: Provisioning and Configuring HP Sure Recover with HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/provisioning-and-configuring-hp-sure-recover-hp-client-management-script-library) .NOTES - Requires HP BIOS with HP Sure Recover support .EXAMPLE New-HPSureRecoverConfigurationPayload -SigningKeyFile sk.pfx -BIOSFlags WiFi -AgentFlags DRDVD .EXAMPLE New-HPSureRecoverConfigurationPayload -SigningKeyFile sk.pfx -BIOSFlags WiFi,SecureStorage -AgentFlags DRDVD,HPWolfSecurityForBusiness #> function New-HPSureRecoverConfigurationPayload { [CmdletBinding(DefaultParameterSetName = "SF",HelpUri = "https://developers.hp.com/hp-client-management/doc/New-HPSureRecoverConfigurationPayload")] param( [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 0)] [System.IO.FileInfo]$SigningKeyFile, [Parameter(ValueFromPipeline,ParameterSetName = "SB",Mandatory = $true,Position = 0)] [System.Security.Cryptography.X509Certificates.X509Certificate2]$SigningKeyCertificate, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 1)] [string]$SigningKeyPassword, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 3)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 3)] [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 0)] [uint32]$Nonce = [math]::Floor([decimal](Get-Date (Get-Date).ToUniversalTime() -UFormat "%s").Replace(',','.')), [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 4)] [Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 4)] [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 1)] [Alias("OSImageFlags")] [surerecover_os_flags]$BIOSFlags, [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 5)] [Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 5)] [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 2)] [surerecover_re_flags]$AgentFlags, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 6)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 6)] [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 3)] [System.IO.FileInfo]$OutputFile, [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 4)] [string]$RemoteSigningServiceKeyID, [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 5)] [string]$RemoteSigningServiceURL, [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 6)] [switch]$CacheAccessToken ) $data = New-Object -TypeName surerecover_configuration_payload_t $data.os_flags = [uint32]$BIOSFlags $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] if ($PSCmdlet.ParameterSetName -eq "RemoteSigning") { $cmd.sig = Invoke-HPPrivateRemoteSignData -Data $payload -CertificateId $RemoteSigningServiceKeyID -KMSUri $RemoteSigningServiceURL -CacheAccessToken:$CacheAccessToken -Verbose:$VerbosePreference } else { $sk = Get-HPPrivateX509CertCoalesce -File $SigningKeyFile -password $SigningKeyPassword -cert $SigningKeycertificate $cmd.sig = Invoke-HPPrivateSignData -Data $payload -Certificate $sk.Full -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 Configure HP Sure Recover Failover .DESCRIPTION This function creates a payload to configure HP Sure Recover OS or Recovery image failover. 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 function. Security note: Payloads should only be created on secure servers. Once created, the payload may be transferred to a client and applied via the Set-HPSecurePlatformPayload. Creating the payload and passing it to the Set-HPSecurePlatformPayload function via the pipeline is not a recommended production pattern. .PARAMETER Image This controls whether this command will create a configuration payload for a Recovery Agent image or a Recovery OS image. For now, only 'os' is supported. .PARAMETER SigningKeyFile The path to the Secure Platform Management 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 Management signing key file password, if required. .PARAMETER SigningKeyCertificate The Secure Platform Management signing key certificate, as an X509Certificate object. .PARAMETER Version The operation version. Each new configuration payload must increment the last operation payload version, as available in the Get-HPSureRecoverFailoverConfiguration. .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. An empty URL can be specified to deprovision Failover. .PARAMETER Nonce The operation nonce. In order to prevent replay attacks, the Secure Platform Management 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 OutputFile Write the resulting output to the specified file, instead of writing it to the pipeline. .PARAMETER RemoteSigningServiceKeyID The Signing Key ID to be used. .PARAMETER RemoteSigningServiceURL The KMS server URL (I.e.: https://<KMSAppName>.azurewebsites.net/). .PARAMETER CacheAccessToken This parameter should be specified for caching the access token when performing multiple operations on the KMS server, if not cached user have to re-enter credentials on each call of this function. If specified, the access token is cached in msalcache.dat file and user's credentials won't be asked again until it expires. .LINK [Blog post: HP Secure Platform Management with the HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/hp-secure-platform-management-hp-client-management-script-library) .NOTES - Requires HP BIOS with HP Sure Recover support .EXAMPLE New-HPSureRecoverFailoverConfigurationPayload -SigningKeyFile sk.pfx -Version 1 -Url '' .EXAMPLE New-HPSureRecoverFailoverConfigurationPayload -SigningKeyFile sk.pfx -Image os -Version 1 -Nonce 2 -Url 'http://url.com/' -Username 'user' -Password 123 #> function New-HPSureRecoverFailoverConfigurationPayload { [CmdletBinding(DefaultParameterSetName = "SF",HelpUri = "https://developers.hp.com/hp-client-management/doc/New-HPSureRecoverConfigurationPayload")] param( [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 0)] [System.IO.FileInfo]$SigningKeyFile, [Parameter(ValueFromPipeline,ParameterSetName = "SB",Mandatory = $true,Position = 0)] [System.Security.Cryptography.X509Certificates.X509Certificate2]$SigningKeyCertificate, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 1)] [string]$SigningKeyPassword, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 2)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 1)] [ValidateSet("os")] [string]$Image = "os", [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 3)] [Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 2)] [uint16]$Version, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 3)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 2)] [string]$Username, [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 3)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 2)] [string]$Password, [Parameter(ParameterSetName = "SF",Mandatory = $true,Position = 3)] [Parameter(ParameterSetName = "SB",Mandatory = $true,Position = 2)] [uri]$Url = "", [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 3)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 3)] [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 0)] [uint32]$Nonce = [math]::Floor([decimal](Get-Date (Get-Date).ToUniversalTime() -UFormat "%s").Replace(',','.')), [Parameter(ParameterSetName = "SF",Mandatory = $false,Position = 6)] [Parameter(ParameterSetName = "SB",Mandatory = $false,Position = 6)] [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 3)] [System.IO.FileInfo]$OutputFile, [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 4)] [string]$RemoteSigningServiceKeyID, [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $true,Position = 5)] [string]$RemoteSigningServiceURL, [Parameter(ParameterSetName = "RemoteSigning",Mandatory = $false,Position = 6)] [switch]$CacheAccessToken ) $opaque = New-Object opaque4096_t $opaqueLength = 4096 $mi_result = 0 [byte]$index = 1 $cmd = '[DfmNativeSureRecover]::get_surerecover_failover_opaque' + (Test-OSBitness) + '($Nonce, $Version, $index, $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 0x05 [byte[]]$payload = $opaque.raw[0..($opaqueLength - 1)] if ($PSCmdlet.ParameterSetName -eq "RemoteSigning") { $sig = Invoke-HPPrivateRemoteSignData -Data $payload -CertificateId $RemoteSigningServiceKeyID -KMSUri $RemoteSigningServiceURL -CacheAccessToken:$CacheAccessToken -Verbose:$VerbosePreference } else { $sk = Get-HPPrivateX509CertCoalesce -File $SigningKeyFile -password $SigningKeyPassword -cert $SigningKeycertificate $sig = Invoke-HPPrivateSignData -Data $payload -Certificate $sk.Full -Verbose:$VerbosePreference } [byte[]]$out = $sig + $payload Write-Verbose "Building output document" $output = New-Object -TypeName PortableFileFormat $output.Data = $out $output.purpose = "hp:surerecover:failover:os_image" $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 function. Security note: Payloads should only be created on secure servers. Once created, the payload may be transferred to a client and applied via the Set-HPSecurePlatformPayload. Creating the payload and passing it to the Set-HPSecurePlatformPayload function via the pipeline is not a recommended production pattern. .PARAMETER SigningKeyFile The path to the Secure Platform Management 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 Management signing key file password, if required. .PARAMETER SigningKeyCertificate The Secure Platform Management signing key certificate, as an X509Certificate object. .PARAMETER Nonce The operation nonce. In order to prevent replay attacks, the Secure Platform Management 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. .PARAMETER RemoteSigningServiceKeyID The Signing Key ID to be used. .PARAMETER RemoteSigningServiceURL The KMS server URL (I.e.: https://<KMSAppName>.azurewebsites.net/). .PARAMETER CacheAccessToken This parameter should be specified for caching the access token when performing multiple operations on the KMS server, if not cached user have to re-enter credentials on each call of this function. If specified, the access token is cached in msalcache.dat file and user's credentials won't be asked again until it expires. .LINK [Blog post: HP Secure Platform Management with the HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/hp-secure-platform-management-hp-client-management-script-library) .LINK [Blog post: Provisioning and Configuring HP Sure Recover with HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/provisioning-and-configuring-hp-sure-recover-hp-client-management-script-library) .NOTES - Requires HP BIOS with HP Sure Recover support .EXAMPLE New-HPSureRecoverTriggerRecoveryPayload -SigningKeyFile sk.pfx #> function New-HPSureRecoverTriggerRecoveryPayload { [CmdletBinding(DefaultParameterSetName = "SF_Schedule",HelpUri = "https://developers.hp.com/hp-client-management/doc/New-HPSureRecoverTriggerRecoveryPayload")] 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)] [Parameter(ParameterSetName = "RemoteSigning_Schedule",Mandatory = $false,Position = 0)] [Parameter(ParameterSetName = "RemoteSigning_Cancel",Mandatory = $false,Position = 0)] [uint32]$Nonce = [math]::Floor([decimal](Get-Date (Get-Date).ToUniversalTime() -UFormat "%s").Replace(',','.')), [Parameter(ParameterSetName = "SF_Schedule",Mandatory = $false,Position = 4)] [Parameter(ParameterSetName = "SB_Schedule",Mandatory = $false,Position = 4)] [Parameter(ParameterSetName = "RemoteSigning_Schedule",Mandatory = $false,Position = 1)] [switch]$Set, [Parameter(ParameterSetName = "SF_Cancel",Mandatory = $true,Position = 4)] [Parameter(ParameterSetName = "SB_Cancel",Mandatory = $true,Position = 4)] [Parameter(ParameterSetName = "RemoteSigning_Cancel",Mandatory = $true,Position = 1)] [switch]$Cancel, [Parameter(ParameterSetName = "SF_Schedule",Mandatory = $false,Position = 6)] [Parameter(ParameterSetName = "SB_Schedule",Mandatory = $false,Position = 6)] [Parameter(ParameterSetName = "RemoteSigning_Schedule",Mandatory = $false,Position = 2)] [ValidateRange(1,7)] [byte]$ForceAfterReboot = 1, [Parameter(ParameterSetName = "SF_Schedule",Mandatory = $false,Position = 7)] [Parameter(ParameterSetName = "SB_Schedule",Mandatory = $false,Position = 7)] [Parameter(ParameterSetName = "RemoteSigning_Schedule",Mandatory = $false,Position = 3)] [surerecover_prompt_policy]$PromptPolicy = "PromptBeforeRecovery,PromptOnError", [Parameter(ParameterSetName = "SF_Schedule",Mandatory = $false,Position = 8)] [Parameter(ParameterSetName = "SB_Schedule",Mandatory = $false,Position = 8)] [Parameter(ParameterSetName = "RemoteSigning_Schedule",Mandatory = $false,Position = 4)] [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)] [Parameter(ParameterSetName = "RemoteSigning_Schedule",Mandatory = $false,Position = 5)] [Parameter(ParameterSetName = "RemoteSigning_Cancel",Mandatory = $false,Position = 2)] [System.IO.FileInfo]$OutputFile, [Parameter(ParameterSetName = "RemoteSigning_Schedule",Mandatory = $true,Position = 6)] [Parameter(ParameterSetName = "RemoteSigning_Cancel",Mandatory = $true,Position = 3)] [string]$RemoteSigningServiceKeyID, [Parameter(ParameterSetName = "RemoteSigning_Schedule",Mandatory = $true,Position = 7)] [Parameter(ParameterSetName = "RemoteSigning_Cancel",Mandatory = $true,Position = 4)] [string]$RemoteSigningServiceURL, [Parameter(ParameterSetName = "RemoteSigning_Schedule",Mandatory = $false,Position = 8)] [Parameter(ParameterSetName = "RemoteSigning_Cancel",Mandatory = $false,Position = 5)] [switch]$CacheAccessToken ) $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] if ($PSCmdlet.ParameterSetName -eq "RemoteSigning_Schedule" -or $PSCmdlet.ParameterSetName -eq "RemoteSigning_Cancel") { $cmd.sig = Invoke-HPPrivateRemoteSignData -Data $payload -CertificateId $RemoteSigningServiceKeyID -KMSUri $RemoteSigningServiceURL -CacheAccessToken:$CacheAccessToken -Verbose:$VerbosePreference } else { $sk = Get-HPPrivateX509CertCoalesce -File $SigningKeyFile -password $SIgningKeyPassword -cert $SigningKeycertificate -Verbose:$VerbosePreference $cmd.sig = Invoke-HPPrivateSignData -Data $payload -Certificate $sk.Full -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. .LINK [Blog post: HP Secure Platform Management with the HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/hp-secure-platform-management-hp-client-management-script-library) .LINK [Blog post: Provisioning and Configuring HP Sure Recover with HP Client Management Script Library](https://developers.hp.com/hp-client-management/blog/provisioning-and-configuring-hp-sure-recover-hp-client-management-script-library) .NOTES - Requires HP BIOS with HP Sure Recover support - Requires Embedded Reimaging device hardware option .EXAMPLE Invoke-HPSureRecoverTriggerUpdate #> function Invoke-HPSureRecoverTriggerUpdate { [CmdletBinding(HelpUri = "https://developers.hp.com/hp-client-management/doc/Invoke-HPSureRecoverTriggerUpdate")] 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 0x05 } # SIG # Begin signature block # MIIuAwYJKoZIhvcNAQcCoIIt9DCCLfACAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCKQh7InUNVB2f9 # jS+Y2Safx6rft8ZM2jW6lWQmEq0Qf6CCE2wwggXAMIIEqKADAgECAhAP0bvKeWvX # +N1MguEKmpYxMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xKzApBgNV # BAMTIkRpZ2lDZXJ0IEhpZ2ggQXNzdXJhbmNlIEVWIFJvb3QgQ0EwHhcNMjIwMTEz # MDAwMDAwWhcNMzExMTA5MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMM # RGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQD # ExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqGSIb3DQEBAQUAA4IC # DwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEppz1Yq3aa # za57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllV # cq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT # +CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd # 463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+ # EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/CNdaSaTC5qmgZ92k # J7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtmmnTK3kse5w5j # rubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7 # f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJU # KSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+wh # X8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQAB # o4IBZjCCAWIwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5n # P+e6mK4cD08wHwYDVR0jBBgwFoAUsT7DaQP4v0cB1JgmGggC72NkK8MwDgYDVR0P # AQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMDMH8GCCsGAQUFBwEBBHMwcTAk # BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEkGCCsGAQUFBzAC # hj1odHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRIaWdoQXNzdXJh # bmNlRVZSb290Q0EuY3J0MEsGA1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwzLmRp # Z2ljZXJ0LmNvbS9EaWdpQ2VydEhpZ2hBc3N1cmFuY2VFVlJvb3RDQS5jcmwwHAYD # VR0gBBUwEzAHBgVngQwBAzAIBgZngQwBBAEwDQYJKoZIhvcNAQELBQADggEBAEHx # qRH0DxNHecllao3A7pgEpMbjDPKisedfYk/ak1k2zfIe4R7sD+EbP5HU5A/C5pg0 # /xkPZigfT2IxpCrhKhO61z7H0ZL+q93fqpgzRh9Onr3g7QdG64AupP2uU7SkwaT1 # IY1rzAGt9Rnu15ClMlIr28xzDxj4+87eg3Gn77tRWwR2L62t0+od/P1Tk+WMieNg # GbngLyOOLFxJy34riDkruQZhiPOuAnZ2dMFkkbiJUZflhX0901emWG4f7vtpYeJa # 3Cgh6GO6Ps9W7Zrk9wXqyvPsEt84zdp7PiuTUy9cUQBY3pBIowrHC/Q7bVUx8ALM # R3eWUaNetbxcyEMRoacwggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0G # CSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ # bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 # IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTla # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C # 0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce # 2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0da # E6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6T # SXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoA # FdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7Oh # D26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM # 1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z # 8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05 # huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNY # mtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP # /2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0T # AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYD # VR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMG # A1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYY # aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2Fj # ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNV # HR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU # cnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAN # BgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95Ry # sQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HL # IvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5Btf # Q/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnh # OE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIh # dXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV # 9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/j # wVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYH # Ki8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmC # XBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l # /aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZW # eE4wggbwMIIE2KADAgECAhAI+qTPsJ3byDJ7SsgX0LBUMA0GCSqGSIb3DQEBCwUA # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwHhcNMjIwMzA5MDAwMDAwWhcNMjMwMzA5MjM1OTU5WjB1MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTESMBAGA1UEBxMJUGFsbyBB # bHRvMRAwDgYDVQQKEwdIUCBJbmMuMRkwFwYDVQQLExBIUCBDeWJlcnNlY3VyaXR5 # MRAwDgYDVQQDEwdIUCBJbmMuMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKC # AYEA2KwFARbsSL8FnMdZ++xo7iVdqg+ZOY0S2KkvYQdNNcvrcfHTdNpNgf65RuIt # VQxdJXzmZcAOXJUPjRQRduvFf/I8jqR4UwBLsNoy/sEuQIDCfezNSQz8TPredjUG # Lr6Y9ie1vYryqJ110Mj6NtXZQidlytEneq3z73Ec7TRFKp8iiiwNpTcbhAq93pq6 # bjnc98ajFUBHJu9Gfk1Or3haR6m7YH0LRLVWm18I2OKrcPLk67hWRj6Aa7/heBkk # F8TfGCUwGBHhblrprBVECR3M4zTnMygBfxVEzYsdyAytPy0DgqzZ7+rHY0yvgDUx # Fi/d1SyqNDCf6FBBudNjzw7TULEBHlJjk96xhd1z4X5ctL1kW4duC7Mba6H8A1lI # qM5qa+8Fr88IJhnl21PlkBp+XAk3lBaeJ/DVpORIv3bhUV8OLae6ElQBGvqQoEY/ # AaNerghhFjiqAhaUG3z3Y7ruhVaCmuw/SMVS79dxESj/J1qHWVnF1tn2a4liq/RY # VeFTAgMBAAGjggIGMIICAjAfBgNVHSMEGDAWgBRoN+Drtjv4XxGG+/5hewiIZfRO # QjAdBgNVHQ4EFgQUAjIiVx974XGZre7F5HqNCJiWZbowDgYDVR0PAQH/BAQDAgeA # MBMGA1UdJQQMMAoGCCsGAQUFBwMDMIG1BgNVHR8Ega0wgaowU6BRoE+GTWh0dHA6 # Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5n # UlNBNDA5NlNIQTM4NDIwMjFDQTEuY3JsMFOgUaBPhk1odHRwOi8vY3JsNC5kaWdp # Y2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEz # ODQyMDIxQ0ExLmNybDA+BgNVHSAENzA1MDMGBmeBDAEEATApMCcGCCsGAQUFBwIB # FhtodHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgZQGCCsGAQUFBwEBBIGHMIGE # MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXAYIKwYBBQUH # MAKGUGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRH # NENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3J0MAwGA1UdEwEB/wQC # MAAwDQYJKoZIhvcNAQELBQADggIBAFrOPeL4ph8SmHwwcUQO7nPnapyOS0I50w70 # nVZ9CtrgyA7hiZmVm/CsC1JU8zg1dNyfH7wCDaoMAnqtybcdmhIXc4STwfcpiKOH # nL3fRQcZ2zCCXmX5lkWYWni9Nqx603JQ8yiUSl1sMyv0Cd4RasOBHnjQuekDDKNT # QvOiEA3NCZDGEjtIjE+TGqLW2kUEtjxzyr0mnhmidRaHry5C1GKu0mlKExwabOLW # xGrXj4FPtKmWXZh00lMbbdeHm1Zqn9CTsO6xt8CQXSemcpb7lXY80um71wQO23ub # tQGDe4QpShomqPmEIVxM5/B6Yih/0Lb8mt60SLfT5EOVS/Dhd86lSHcncL9JLxaq # WwbQhIwpEa4b3MiZqyemqb0+YIBn5yG43M4oLzRPTo2mPwG19OtnMVZsrcjGEzLz # EiBb9/YXsf8G5LAh86x2kRKDad35NNNojUJYVBtD7MGEsL37XF+6kWXsp92on2b2 # QLEL/5ZzJHmfrJ8m0TXMb4sMSI2KnHtCvEjG2MIAnjFEvNZ1ZFsKS78mwylDyHL0 # yTuv08JqDuommKgjmyvtLEeb6OYsOnSVQIcyV4XCY1kFA8mDuIsIlbWE3Nyv94Of # N+4jNKcDzniYb5LmKlXraIM8PjPpYb34DlNpzCDN7/tJuMFsy/NwArj1SiL630mg # Dm0fS5OgMYIZ7TCCGekCAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGln # aUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBT # aWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhAI+qTPsJ3byDJ7SsgX0LBU # MA0GCWCGSAFlAwQCAQUAoHwwEAYKKwYBBAGCNwIBDDECMAAwGQYJKoZIhvcNAQkD # MQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJ # KoZIhvcNAQkEMSIEIE/3Jm8HL5FcUDNtXsY2GP607TG8wVPgFBOLEC/EQICYMA0G # CSqGSIb3DQEBAQUABIIBgL0T2UVhi61OCdphLOoB6fHdPbYxOdSG+o9X6h1zdNV+ # 2qHZValsPUafik+Wh0chFb4b/HcdwM/Pgf6Iz2lzcIv9WR8nmUE2QErxK8GMlY/x # 1qKZj9nK8n+RD8EszOylJkZQiNZrjExqUKud3MtuczNgCkp4E84Y4hUuDBdOaRGb # 56Uqxw9woBUoDsvEHS4enFVML81m/UajOOZ99I7gJ1i/zKwxFLZPWJOn/QL43Yig # PE/HcY8ooGf+F4PjdaKAf7o25jKUTKTpauZmZ+7V1OmR44yOswjXL/PWu+Mx7QJW # yT+3/7XqZzCAcq9OKNvjkgcYgjC6bPzQmXBz4W2cFptYWHZXtk8uWG12EW0lWQnn # 051cB9zN4sldqhrvBS17g+vKSXX0dOsbqlfi77C7DwX5U6JQsI2l/HfOuHQKtQzQ # HnWW/30WbJ9zKlI8cTFffUEg5rZkQFRWAlZq49HAqeUkuKxGJiOBSDsNjWHJo3ra # dKGsPwZ4NRJfky5Kj5oGZKGCF0Mwghc/BgorBgEEAYI3AwMBMYIXLzCCFysGCSqG # SIb3DQEHAqCCFxwwghcYAgEDMQ8wDQYJYIZIAWUDBAIBBQAwdwYLKoZIhvcNAQkQ # AQSgaARmMGQCAQEGCWCGSAGG/WwHATAxMA0GCWCGSAFlAwQCAQUABCAGPqd+IeQb # RfcwhJ17iWtgRuq7op7aAtQet2xLe5t0IwIQM4WxQRIXFxWgw2Hm3mzu4BgPMjAy # MjA5MDcxNzM1MTZaoIITDTCCBsYwggSuoAMCAQICEAp6SoieyZlCkAZjOE2Gl50w # DQYJKoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0 # LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hB # MjU2IFRpbWVTdGFtcGluZyBDQTAeFw0yMjAzMjkwMDAwMDBaFw0zMzAzMTQyMzU5 # NTlaMEwxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjEkMCIG # A1UEAxMbRGlnaUNlcnQgVGltZXN0YW1wIDIwMjIgLSAyMIICIjANBgkqhkiG9w0B # AQEFAAOCAg8AMIICCgKCAgEAuSqWI6ZcvF/WSfAVghj0M+7MXGzj4CUu0jHkPECu # +6vE43hdflw26vUljUOjges4Y/k8iGnePNIwUQ0xB7pGbumjS0joiUF/DbLW+YTx # mD4LvwqEEnFsoWImAdPOw2z9rDt+3Cocqb0wxhbY2rzrsvGD0Z/NCcW5QWpFQiNB # Wvhg02UsPn5evZan8Pyx9PQoz0J5HzvHkwdoaOVENFJfD1De1FksRHTAMkcZW+KY # Lo/Qyj//xmfPPJOVToTpdhiYmREUxSsMoDPbTSSF6IKU4S8D7n+FAsmG4dUYFLcE # RfPgOL2ivXpxmOwV5/0u7NKbAIqsHY07gGj+0FmYJs7g7a5/KC7CnuALS8gI0TK7 # g/ojPNn/0oy790Mj3+fDWgVifnAs5SuyPWPqyK6BIGtDich+X7Aa3Rm9n3RBCq+5 # jgnTdKEvsFR2wZBPlOyGYf/bES+SAzDOMLeLD11Es0MdI1DNkdcvnfv8zbHBp8QO # xO9APhk6AtQxqWmgSfl14ZvoaORqDI/r5LEhe4ZnWH5/H+gr5BSyFtaBocraMJBr # 7m91wLA2JrIIO/+9vn9sExjfxm2keUmti39hhwVo99Rw40KV6J67m0uy4rZBPeev # pxooya1hsKBBGBlO7UebYZXtPgthWuo+epiSUc0/yUTngIspQnL3ebLdhOon7v59 # emsCAwEAAaOCAYswggGHMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBYG # A1UdJQEB/wQMMAoGCCsGAQUFBwMIMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCG # SAGG/WwHATAfBgNVHSMEGDAWgBS6FtltTYUvcyl2mi91jGogj57IbzAdBgNVHQ4E # FgQUjWS3iSH+VlhEhGGn6m8cNo/drw0wWgYDVR0fBFMwUTBPoE2gS4ZJaHR0cDov # L2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0UlNBNDA5NlNIQTI1 # NlRpbWVTdGFtcGluZ0NBLmNybDCBkAYIKwYBBQUHAQEEgYMwgYAwJAYIKwYBBQUH # MAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBYBggrBgEFBQcwAoZMaHR0cDov # L2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0UlNBNDA5NlNI # QTI1NlRpbWVTdGFtcGluZ0NBLmNydDANBgkqhkiG9w0BAQsFAAOCAgEADS0jdKbR # 9fjqS5k/AeT2DOSvFp3Zs4yXgimcQ28BLas4tXARv4QZiz9d5YZPvpM63io5WjlO # 2IRZpbwbmKrobO/RSGkZOFvPiTkdcHDZTt8jImzV3/ZZy6HC6kx2yqHcoSuWuJtV # qRprfdH1AglPgtalc4jEmIDf7kmVt7PMxafuDuHvHjiKn+8RyTFKWLbfOHzL+lz3 # 5FO/bgp8ftfemNUpZYkPopzAZfQBImXH6l50pls1klB89Bemh2RPPkaJFmMga8vy # e9A140pwSKm25x1gvQQiFSVwBnKpRDtpRxHT7unHoD5PELkwNuTzqmkJqIt+ZKJl # lBH7bjLx9bs4rc3AkxHVMnhKSzcqTPNc3LaFwLtwMFV41pj+VG1/calIGnjdRncu # G3rAM4r4SiiMEqhzzy350yPynhngDZQooOvbGlGglYKOKGukzp123qlzqkhqWUOu # X+r4DwZCnd8GaJb+KqB0W2Nm3mssuHiqTXBt8CzxBxV+NbTmtQyimaXXFWs1DoXW # 4CzM4AwkuHxSCx6ZfO/IyMWMWGmvqz3hz8x9Fa4Uv4px38qXsdhH6hyF4EVOEhwU # KVjMb9N/y77BDkpvIJyu2XMyWQjnLZKhGhH+MpimXSuX4IvTnMxttQ2uR2M4Rxdb # bxPaahBuH0m3RFu0CAqHWlkEdhGhp3cCExwwggauMIIElqADAgECAhAHNje3JFR8 # 2Ees/ShmKl5bMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV # BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yMjAzMjMwMDAwMDBaFw0z # NzAzMjIyMzU5NTlaMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg # SW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1 # NiBUaW1lU3RhbXBpbmcgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC # AQDGhjUGSbPBPXJJUVXHJQPE8pE3qZdRodbSg9GeTKJtoLDMg/la9hGhRBVCX6SI # 82j6ffOciQt/nR+eDzMfUBMLJnOWbfhXqAJ9/UO0hNoR8XOxs+4rgISKIhjf69o9 # xBd/qxkrPkLcZ47qUT3w1lbU5ygt69OxtXXnHwZljZQp09nsad/ZkIdGAHvbREGJ # 3HxqV3rwN3mfXazL6IRktFLydkf3YYMZ3V+0VAshaG43IbtArF+y3kp9zvU5Emfv # DqVjbOSmxR3NNg1c1eYbqMFkdECnwHLFuk4fsbVYTXn+149zk6wsOeKlSNbwsDET # qVcplicu9Yemj052FVUmcJgmf6AaRyBD40NjgHt1biclkJg6OBGz9vae5jtb7IHe # IhTZgirHkr+g3uM+onP65x9abJTyUpURK1h0QCirc0PO30qhHGs4xSnzyqqWc0Jo # n7ZGs506o9UD4L/wojzKQtwYSH8UNM/STKvvmz3+DrhkKvp1KCRB7UK/BZxmSVJQ # 9FHzNklNiyDSLFc1eSuo80VgvCONWPfcYd6T/jnA+bIwpUzX6ZhKWD7TA4j+s4/T # Xkt2ElGTyYwMO1uKIqjBJgj5FBASA31fI7tk42PgpuE+9sJ0sj8eCXbsq11GdeJg # o1gJASgADoRU7s7pXcheMBK9Rp6103a50g5rmQzSM7TNsQIDAQABo4IBXTCCAVkw # EgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUuhbZbU2FL3MpdpovdYxqII+e # yG8wHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQD # AgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEF # BQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRw # Oi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNy # dDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGln # aUNlcnRUcnVzdGVkUm9vdEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglg # hkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIBAH1ZjsCTtm+YqUQiAX5m1tghQuGw # GC4QTRPPMFPOvxj7x1Bd4ksp+3CKDaopafxpwc8dB+k+YMjYC+VcW9dth/qEICU0 # MWfNthKWb8RQTGIdDAiCqBa9qVbPFXONASIlzpVpP0d3+3J0FNf/q0+KLHqrhc1D # X+1gtqpPkWaeLJ7giqzl/Yy8ZCaHbJK9nXzQcAp876i8dU+6WvepELJd6f8oVInw # 1YpxdmXazPByoyP6wCeCRK6ZJxurJB4mwbfeKuv2nrF5mYGjVoarCkXJ38SNoOeY # +/umnXKvxMfBwWpx2cYTgAnEtp/Nh4cku0+jSbl3ZpHxcpzpSwJSpzd+k1OsOx0I # SQ+UzTl63f8lY5knLD0/a6fxZsNBzU+2QJshIUDQtxMkzdwdeDrknq3lNHGS1yZr # 5Dhzq6YBT70/O3itTK37xJV77QpfMzmHQXh6OOmc4d0j/R0o08f56PGYX/sr2H7y # Rp11LB4nLCbbbxV7HhmLNriT1ObyF5lZynDwN7+YAN8gFk8n+2BnFqFmut1VwDop # hrCYoCvtlUG3OtUVmDG0YgkPCr2B2RP+v6TR81fZvAT6gt4y3wSJ8ADNXcL50CN/ # AAvkdgIm2fBldkKmKYcJRyvmfxqkhQ/8mJb2VVQrH4D6wPIOK+XW+6kvRBVK5xMO # Hds3OBqhK/bt1nz8MIIFjTCCBHWgAwIBAgIQDpsYjvnQLefv21DiCEAYWjANBgkq # hkiG9w0BAQwFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5j # MRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBB # c3N1cmVkIElEIFJvb3QgQ0EwHhcNMjIwODAxMDAwMDAwWhcNMzExMTA5MjM1OTU5 # WjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL # ExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJv # b3QgRzQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1K # PDAiMGkz7MKnJS7JIT3yithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2r # snnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C # 8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBf # sXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY # QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8 # rhsDdV14Ztk6MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaY # dj1ZXUJ2h4mXaXpI8OCiEhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+ # wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw # ++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+N # P8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7F # wI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo4IBOjCCATYwDwYDVR0TAQH/BAUw # AwEB/zAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wHwYDVR0jBBgwFoAU # Reuir/SSy4IxLVGLp6chnfNtyA8wDgYDVR0PAQH/BAQDAgGGMHkGCCsGAQUFBwEB # BG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsG # AQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1 # cmVkSURSb290Q0EuY3J0MEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRp # Z2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwEQYDVR0gBAow # CDAGBgRVHSAAMA0GCSqGSIb3DQEBDAUAA4IBAQBwoL9DXFXnOF+go3QbPbYW1/e/ # Vwe9mqyhhyzshV6pGrsi+IcaaVQi7aSId229GhT0E0p6Ly23OO/0/4C5+KH38nLe # JLxSA8hO0Cre+i1Wz/n096wwepqLsl7Uz9FDRJtDIeuWcqFItJnLnU+nBgMTdydE # 1Od/6Fmo8L8vC6bp8jQ87PcDx4eo0kxAGTVGamlUsLihVo7spNU96LHc/RzY9Hda # XFSMb++hUD38dglohJ9vytsgjTVgHAIDyyCwrFigDkBjxZgiwbJZ9VVrzyerbHbO # byMt9H5xaiNrIv8SuFQtJ37YOtnwtoeW/VvRXKwYw02fc7cBqZ9Xql4o4rmUMYID # djCCA3ICAQEwdzBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu # Yy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYg # VGltZVN0YW1waW5nIENBAhAKekqInsmZQpAGYzhNhpedMA0GCWCGSAFlAwQCAQUA # oIHRMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0BCQUxDxcN # MjIwOTA3MTczNTE2WjArBgsqhkiG9w0BCRACDDEcMBowGDAWBBSFCPOGUVyz0wd9 # trS3wH8bSl5B3jAvBgkqhkiG9w0BCQQxIgQglX+38HulWr6p1bAq4hHC2lHmc1jU # LrqWcK5ugTkKjK0wNwYLKoZIhvcNAQkQAi8xKDAmMCQwIgQgnaaQFcNJxsGJeEW6 # NYKtcMiPpCk722q+nCvSU5J55jswDQYJKoZIhvcNAQEBBQAEggIASSTxVfMMh2AV # P+Ow02B+x0dTyZ6yfRqeNCFNK20BZA0P33ddqUL2R9pX0d94d7Q4jfB5R6HoRtX6 # Kles+bRnnc/o8xhM7wLcrbrGxO5gPI7Bwgodfc6QQl/cKsyHpYmRw2RYRakjPjN9 # hl1bhde8aLeViZc21KHd51vFpoXyQlpNVUuEPD2ocYOotvhQ1UqSChQYFCodRWzI # C+e83kcRFNTzvyWXcrYM+B7cVXAQFmcNwczYRmtQFefRR57ePVyR2VjlXDapw6ko # Vz5dF5N79Vd4x/oluzvEWZn0arxbc5FCvkYb7Bjx6kBw9Dj6Y8vJeft3Mt1J15Av # cpzABZNkMOo3JDeEZcUGjo1/2cwzCPh1QmxH2jln4JzGL13A99m9cST+6pvXuPkw # 17xdfU45ia/ts3HpiXkf6uDQb9xHl+/gObkouBijgp6kNuI8wyawPTqOwY1WXkAk # eG4XSmc13qtF+SWJlnwkY6uz8PpQMBFwdAD/3BJethWb42BQPiVCOrjiaAeVDTpW # p1v+myVIZBYs0NWeNxoF4MSqUPdy2n2JTVclmYxuC1SmfMJOGN23fhHyvatW4Pr9 # namcgtkCWFCMxeBBw/Q1ur7Z+jA4RAiUJoPfEWNDnio39s7ui/PbpVXIEot33Ds7 # B9yA1v7832N/uXqOnLIkK20LOOXvVwg= # SIG # End signature block |