AzureLocalNetworkInfraConnection/AzureLocal.NetworkInfraConnection.TlsInspection.Helpers.psm1
|
<#############################################################
# # # Copyright (C) Microsoft Corporation. All rights reserved. # # # #############################################################> function InfraIpTlsInspectionCheck { <# .SYNOPSIS Checks endpoint certificate chains from an infrastructure IP. .DESCRIPTION Connects to each configured TLS inspection target from the specified infrastructure IP and physical adapter. It compares the served signing chain with the target's Tags.ExpectedSubject values. HTTPS endpoints use their configured port, including non-standard ports. HTTP endpoints are logged and skipped. Returns lightweight endpoint results for New-AggregatedTestResult. Connection failures are logged and skipped because endpoint reachability is validated separately. .PARAMETER SourceIp Infrastructure IP address used as the local source address for each TLS connection. .PARAMETER PhysicalAdapterUsed Physical adapter carrying traffic from the temporary infrastructure-IP vNIC. .PARAMETER SslInspectionTargets Service definitions containing EndPoint, Severity, and Tags.ExpectedSubject values. .PARAMETER LanguageText Localized strings used to build endpoint result details. .PARAMETER ProxyHost Optional HTTP proxy host. When specified, the probe establishes an HTTP CONNECT tunnel. .PARAMETER ProxyPort HTTP proxy port used with ProxyHost. .PARAMETER TimeoutInSeconds Connection and socket timeout for each endpoint probe. The default is 15 seconds. .PARAMETER ProbeAttemptCount Maximum number of attempts for each endpoint probe. The default is three attempts. .PARAMETER ProbeRetryDelaySeconds Delay between failed endpoint probe attempts. The default is three seconds. .PARAMETER UseConfiguredSeverity Uses each service definition's Severity when true. Uses INFORMATIONAL during SDP phase one when false. .PARAMETER ProbeSkipReason Optional reason that prevents probing every target. When supplied, the function emits successful informational skip observations without opening network connections. .OUTPUTS Hashtable objects created by New-LightweightResult. One object is returned for each configured endpoint. .EXAMPLE InfraIpTlsInspectionCheck -SourceIp '192.168.1.220' ` -PhysicalAdapterUsed 'Ethernet' ` -SslInspectionTargets $targets ` -LanguageText $lnTxt Checks the configured endpoints directly and returns informational lightweight results. .EXAMPLE InfraIpTlsInspectionCheck -SourceIp '192.168.1.220' ` -PhysicalAdapterUsed 'Ethernet' ` -SslInspectionTargets $targets ` -LanguageText $lnTxt ` -ProxyHost 'proxy.contoso.com' ` -ProxyPort 8080 ` -UseConfiguredSeverity $true Checks the endpoints through an HTTP proxy and applies their configured severities. #> param ( [Parameter(Mandatory = $true)] [System.String] $SourceIp, [Parameter(Mandatory = $true)] [System.String] $PhysicalAdapterUsed, [Parameter(Mandatory = $true)] [PSObject[]] $SslInspectionTargets, [Parameter(Mandatory = $true)] $LanguageText, [Parameter(Mandatory = $false)] [System.String] $ProxyHost, [Parameter(Mandatory = $false)] [System.Int32] $ProxyPort = 0, [Parameter(Mandatory = $false)] [System.UInt16] $TimeoutInSeconds = 15, [Parameter(Mandatory = $false)] [ValidateRange(1, 10)] [System.UInt16] $ProbeAttemptCount = 3, [Parameter(Mandatory = $false)] [ValidateRange(0, 300)] [System.UInt16] $ProbeRetryDelaySeconds = 3, [Parameter(Mandatory = $false)] [System.Boolean] $UseConfiguredSeverity = $false, [Parameter(Mandatory = $false)] [System.String] $ProbeSkipReason ) [System.Collections.Hashtable[]] $detailResults = @() foreach ($service in $SslInspectionTargets) { $expectedSubject = @( $service.Tags.ExpectedSubject | Where-Object { -not [System.String]::IsNullOrWhiteSpace([System.String]$_) } | ForEach-Object { ([System.String]$_).Trim() } ) $configuredSeverity = if ([System.String]::IsNullOrWhiteSpace($service.Severity)) { 'CRITICAL' } else { $service.Severity.ToUpperInvariant() } foreach ($endpointInService in $service.EndPoint) { if (-not [System.String]::IsNullOrWhiteSpace($ProbeSkipReason)) { $detailResults += New-InfraIpTlsInspectionSkippedResult -SourceIp $SourceIp ` -PhysicalAdapterUsed $PhysicalAdapterUsed ` -Endpoint ([System.String]$endpointInService) ` -Reason $ProbeSkipReason ` -LanguageText $LanguageText continue } $endpointUriText = [System.String]$endpointInService if ($endpointUriText -notmatch '^[a-z][a-z0-9+.-]*://') { $httpsProtocol = @($service.Protocol | Where-Object { $_ -ieq 'https' } | Select-Object -First 1) if ($httpsProtocol.Count -eq 0) { Log-Info " >> Skipping TLS inspection check for $($endpointInService): the service does not define HTTPS." -Type Warning $detailResults += New-InfraIpTlsInspectionSkippedResult -SourceIp $SourceIp -PhysicalAdapterUsed $PhysicalAdapterUsed -Endpoint $endpointInService -Reason 'The service does not define HTTPS.' -LanguageText $LanguageText continue } $endpointUriText = "https://$($endpointUriText)" } [System.Uri] $endpointUri = $null if (-not [System.Uri]::TryCreate($endpointUriText, [System.UriKind]::Absolute, [ref]$endpointUri)) { Log-Info " >> Skipping TLS inspection check for $($endpointInService): the endpoint is not a valid absolute URI." -Type Warning $detailResults += New-InfraIpTlsInspectionSkippedResult -SourceIp $SourceIp -PhysicalAdapterUsed $PhysicalAdapterUsed -Endpoint $endpointInService -Reason 'The endpoint is not a valid absolute URI.' -LanguageText $LanguageText continue } if ($endpointUri.Scheme -ine 'https') { Log-Info " >> Skipping TLS inspection check for $($endpointInService): TLS certificate inspection requires HTTPS." -Type Warning $detailResults += New-InfraIpTlsInspectionSkippedResult -SourceIp $SourceIp -PhysicalAdapterUsed $PhysicalAdapterUsed -Endpoint $endpointUri.Authority -Reason 'TLS certificate inspection requires HTTPS.' -LanguageText $LanguageText continue } $targetHost = $endpointUri.DnsSafeHost $targetPort = $endpointUri.Port $targetResource = $endpointUri.Authority if ($expectedSubject.Count -eq 0) { Log-Info " >> Skipping TLS inspection check for $($service.Name): Tags.ExpectedSubject is not configured." -Type Warning $detailResults += New-InfraIpTlsInspectionSkippedResult -SourceIp $SourceIp -PhysicalAdapterUsed $PhysicalAdapterUsed -Endpoint $targetResource -Reason 'Tags.ExpectedSubject is not configured.' -LanguageText $LanguageText continue } $probeParams = @{ SourceIp = $SourceIp TargetHost = $targetHost TargetPort = $targetPort TimeoutMs = [System.Int32]($TimeoutInSeconds * 1000) } if (-not [System.String]::IsNullOrWhiteSpace($ProxyHost)) { $probeParams.ProxyHost = $ProxyHost $probeParams.ProxyPort = $ProxyPort } $chain = $null $lastProbeFailure = $null for ($probeAttempt = 1; $probeAttempt -le $ProbeAttemptCount; $probeAttempt++) { try { $chain = Get-SslCertificateChainFromSource @probeParams if ($chain -and $chain.Count -gt 0) { break } $lastProbeFailure = 'No certificate chain was returned.' } catch { $lastProbeFailure = $_.Exception.Message } if ($probeAttempt -lt $ProbeAttemptCount) { Log-Info " >> TLS inspection probe attempt $probeAttempt of $ProbeAttemptCount failed for $($targetHost) from infra IP $($SourceIp): $lastProbeFailure. Retrying in $ProbeRetryDelaySeconds seconds." -Type Warning Start-Sleep -Seconds $ProbeRetryDelaySeconds } } if (-not $chain -or $chain.Count -eq 0) { Log-Info " >> Skipping TLS inspection check for $($targetHost) from infra IP $($SourceIp) after $ProbeAttemptCount attempts: $lastProbeFailure" -Type Warning $detailResults += New-InfraIpTlsInspectionSkippedResult -SourceIp $SourceIp -PhysicalAdapterUsed $PhysicalAdapterUsed -Endpoint $targetResource -Reason $lastProbeFailure -LanguageText $LanguageText continue } try { # Exclude the leaf because an inspection proxy can preserve its expected organization. $signingSubjects = @($chain[0].Issuer) if ($chain.Count -ge 2) { $signingSubjects += $chain[1..($chain.Count - 1)].Subject } $matchCount = Test-SigningSubjectMatchesExpected -SigningSubject $signingSubjects -ExpectedSubject $expectedSubject $status = if ($matchCount -ge 1) { 'SUCCESS' } else { 'FAILURE' } $severity = if ($UseConfiguredSeverity) { $configuredSeverity } else { 'INFORMATIONAL' } $detail = if ($status -eq 'SUCCESS') { $LanguageText.InfraConnectionInfraPoolIPTlsInspectionEndpointPASSED -f $SourceIp, $PhysicalAdapterUsed, $targetResource, ($expectedSubject -join '; ') } else { $LanguageText.InfraConnectionInfraPoolIPTlsInspectionEndpointFAILED -f $SourceIp, $PhysicalAdapterUsed, $targetResource, ($signingSubjects -join '; '), ($expectedSubject -join '; ') } if ($status -eq 'SUCCESS') { Log-Info " >> [PASS] No TLS inspection from infra IP $($SourceIp) to $($targetResource)." } else { Log-Info " >> [FAIL] TLS inspection detected from infra IP $($SourceIp) to $($targetResource). Signed by: $($signingSubjects -join '; ')" -Type Error } $detailResults += New-LightweightResult ` -Name 'AzureLocal_NetworkInfraConnection_Test_Infra_IP_TLS_Inspection' ` -Status $status ` -Severity $severity ` -TargetResourceName $SourceIp ` -Source "$SourceIp ($PhysicalAdapterUsed)" ` -Resource $targetResource ` -Detail $detail } finally { foreach ($certificate in @($chain)) { if ($certificate -is [System.IDisposable]) { $certificate.Dispose() } } } } } return $detailResults } function New-InfraIpTlsInspectionSkippedResult { <# .SYNOPSIS Creates a lightweight result for a skipped TLS inspection probe. .DESCRIPTION Records a successful informational endpoint observation when a TLS inspection probe cannot run. The skip reason remains visible in the per-IP aggregate result and telemetry. .PARAMETER SourceIp Infrastructure IP that would have sourced the TLS probe. .PARAMETER PhysicalAdapterUsed Physical adapter that would have carried the TLS probe. .PARAMETER Endpoint Endpoint definition or authority that was not probed. .PARAMETER Reason Diagnostic reason the TLS probe was skipped. .PARAMETER LanguageText Localized strings used to build the result detail. .OUTPUTS Hashtable created by New-LightweightResult with SUCCESS status and INFORMATIONAL severity. .EXAMPLE New-InfraIpTlsInspectionSkippedResult ` -SourceIp '192.168.1.220' ` -PhysicalAdapterUsed 'Ethernet' ` -Endpoint 'mcr.microsoft.com' ` -Reason 'The enabled proxy configuration could not be resolved.' ` -LanguageText $lnTxt #> param ( [Parameter(Mandatory = $true)] [System.String] $SourceIp, [Parameter(Mandatory = $true)] [System.String] $PhysicalAdapterUsed, [Parameter(Mandatory = $true)] [System.String] $Endpoint, [Parameter(Mandatory = $true)] [System.String] $Reason, [Parameter(Mandatory = $true)] $LanguageText ) Log-Info " >> TLS inspection check skipped for $Endpoint from infra IP $SourceIp via $PhysicalAdapterUsed. Reason: $Reason" -Type Warning $result = New-LightweightResult ` -Name 'AzureLocal_NetworkInfraConnection_Test_Infra_IP_TLS_Inspection' ` -Status 'SUCCESS' ` -Severity 'INFORMATIONAL' ` -TargetResourceName $SourceIp ` -Source "$SourceIp ($PhysicalAdapterUsed)" ` -Resource $Endpoint ` -Detail ($LanguageText.InfraConnectionInfraPoolIPTlsInspectionEndpointSKIPPED -f $SourceIp, $PhysicalAdapterUsed, $Endpoint, $Reason) $result.AdditionalData.Outcome = 'SKIPPED' return $result } function New-InfraIpTlsInspectionResult { <# .SYNOPSIS Aggregates TLS endpoint checks for an infrastructure IP. .DESCRIPTION Uses New-AggregatedTestResult to combine lightweight endpoint results, then retargets each aggregate from AllNodes to the infrastructure IP. During SDP phase one, endpoint details use INFORMATIONAL severity and produce one result per IP. After promotion, configured endpoint severities produce one result per IP and severity. .PARAMETER SourceIp Infrastructure IP represented by the aggregate result. .PARAMETER DetailResults Lightweight endpoint results returned by InfraIpTlsInspectionCheck. .PARAMETER LanguageText Localized strings used for the aggregate description and remediation. .PARAMETER UseConfiguredSeverity Marks the aggregate as promoted when true and adds its severity to the target identity. .OUTPUTS PSCustomObject instances returned by New-AggregatedTestResult and retargeted to SourceIp. Returns no objects when DetailResults is empty. .EXAMPLE New-InfraIpTlsInspectionResult ` -SourceIp '192.168.1.220' ` -DetailResults $endpointResults ` -LanguageText $lnTxt Returns one informational SDP-phase result for the infrastructure IP. .EXAMPLE New-InfraIpTlsInspectionResult ` -SourceIp '192.168.1.220' ` -DetailResults $endpointResults ` -LanguageText $lnTxt ` -UseConfiguredSeverity $true Returns one aggregate per configured endpoint severity for the infrastructure IP. #> param ( [Parameter(Mandatory = $true)] [System.String] $SourceIp, [Parameter(Mandatory = $true)] [AllowEmptyCollection()] [PSObject[]] $DetailResults, [Parameter(Mandatory = $true)] $LanguageText, [Parameter(Mandatory = $false)] [System.Boolean] $UseConfiguredSeverity = $false ) if (@($DetailResults).Count -eq 0) { return @() } $results = @(New-AggregatedTestResult ` -TestName 'Test-InfraIpTlsInspection' ` -DisplayName ($LanguageText.InfraConnectionInfraPoolIPTlsInspectionAggregate -f $SourceIp) ` -Description ($LanguageText.InfraConnectionInfraPoolIPTlsInspectionAggregate -f $SourceIp) ` -DetailResults $DetailResults ` -ValidatorName 'NetworkInfraConnection' ` -ResourceType 'Infrastructure IP' ` -Remediation ($LanguageText.InfraConnectionInfraPoolIPTlsInspectionAggregateRemediation -f $SourceIp)) foreach ($result in $results) { $targetSuffix = if ($UseConfiguredSeverity) { "_$($result.Severity)" } else { '' } $targetName = "Infra_IP_TLS_Inspection_$($SourceIp)$($targetSuffix)" $result.TargetResourceID = $targetName $result.TargetResourceName = $targetName $result.TargetResourceType = 'Infrastructure IP' $result.Description = $LanguageText.InfraConnectionInfraPoolIPTlsInspectionAggregate -f $SourceIp $result.AdditionalData.Source = $env:COMPUTERNAME $result.AdditionalData.Resource = $SourceIp $result.AdditionalData.Remove('NodeCount') $result.AdditionalData.Remove('TotalNodes') $result.AdditionalData.InfrastructureIpCount = 1 $result.Tags.Remove('NodeCount') $result.Tags.InfrastructureIpCount = 1 $result.Tags.SdpPhaseOne = -not $UseConfiguredSeverity if ($UseConfiguredSeverity) { $result.Tags.ConfiguredSeverity = [string]$result.Severity } $severityResults = @($DetailResults | Where-Object { [string]$_.Severity -eq [string]$result.Severity }) $skippedResults = @($severityResults | Where-Object { $_.AdditionalData.Outcome -eq 'SKIPPED' }) if ($skippedResults.Count -gt 0) { $successfulChecks = @($severityResults | Where-Object { $_.Status -eq 'SUCCESS' -and $_.AdditionalData.Outcome -ne 'SKIPPED' }).Count $skipSummary = $LanguageText.InfraConnectionInfraPoolIPTlsInspectionAggregateWithSkipped -f ` $SourceIp, $successfulChecks, $severityResults.Count, $skippedResults.Count $skipDetails = @($skippedResults | ForEach-Object { $_.AdditionalData.Detail }) if ($result.Status -eq 'SUCCESS') { $result.AdditionalData.Detail = (@($skipSummary) + $skipDetails) -join "`n" } else { $result.AdditionalData.Detail = (@($result.AdditionalData.Detail, $skipSummary) + $skipDetails) -join "`n" } $result.AdditionalData.TotalChecks = $severityResults.Count $result.AdditionalData.SuccessfulChecks = $successfulChecks $result.AdditionalData.SkippedChecks = $skippedResults.Count $result.AdditionalData.HasSkippedChecks = $true $result.Tags.SkippedChecks = $skippedResults.Count $result.Tags.HasSkippedChecks = $true } Log-Info " >> TLS inspection summary for infra IP $($SourceIp), severity $($result.Severity): $($result.Status), $($result.AdditionalData.TotalChecks) checks." } return $results } function Get-InfraIpTlsInspectionProxyConfiguration { <# .SYNOPSIS Resolves proxy settings for infrastructure IP TLS inspection. .DESCRIPTION Returns the proxy host and port required by the source-bound TLS probe. When proxy use is disabled, the returned configuration is ready for direct probing. An enabled proxy that cannot be resolved returns a skip reason so the probe cannot bypass the proxy. .PARAMETER ProxyEnabled Indicates whether the host is configured to use a proxy. .OUTPUTS PSCustomObject containing Host, Port, Ready, and SkipReason properties. .EXAMPLE Get-InfraIpTlsInspectionProxyConfiguration -ProxyEnabled $true Resolves the WinHTTP proxy used by infrastructure IP TLS inspection. #> param ( [Parameter(Mandatory = $true)] [System.Boolean] $ProxyEnabled ) $configuration = [PSCustomObject]@{ Host = $null Port = 0 Ready = -not $ProxyEnabled SkipReason = $null } if (-not $ProxyEnabled) { return $configuration } try { $winProxy = EnvValidatorNwkLibGetWinProxyConfiguration -ProxyType WinHttp $proxyEndpoint = if (-not [System.String]::IsNullOrWhiteSpace($winProxy.HttpsProxy)) { $winProxy.HttpsProxy } else { $winProxy.HttpProxy } if ([System.String]::IsNullOrWhiteSpace($proxyEndpoint)) { $configuration.SkipReason = 'The enabled proxy configuration could not be resolved.' Log-Info 'Proxy is enabled, but no HTTP or HTTPS proxy endpoint was found. Infra IP TLS inspection checks will be skipped.' -Type Warning return $configuration } $proxyEndpoint = $proxyEndpoint -replace '^https?://', '' -replace '/.*$', '' $proxyParts = $proxyEndpoint -split ':' $configuration.Host = $proxyParts[0] $configuration.Port = if ($proxyParts.Count -ge 2) { [System.Int32] $proxyParts[1] } else { 8080 } $configuration.Ready = $true Log-Info "Resolved proxy $($configuration.Host):$($configuration.Port) for infra IP TLS inspection probe." } catch { $configuration.SkipReason = 'The enabled proxy configuration could not be resolved.' Log-Info "Could not resolve proxy for infra IP TLS inspection probe: $($_.Exception.Message)" -Type Warning } return $configuration } function Invoke-InfraIpTlsInspectionCheckForAdapter { <# .SYNOPSIS Runs infrastructure IP TLS inspection checks through one physical adapter. .DESCRIPTION Runs the configured endpoint checks from an infrastructure IP and adapter. The function applies resolved proxy settings or emits successful skip observations when an enabled proxy cannot be resolved. .PARAMETER SourceIp Infrastructure IP used as the local source address. .PARAMETER PhysicalAdapterUsed Physical adapter carrying traffic from the temporary infrastructure-IP vNIC. .PARAMETER SslInspectionTargets Service definitions selected for TLS inspection. .PARAMETER LanguageText Localized strings used to build result details. .PARAMETER ProxyConfiguration Configuration returned by Get-InfraIpTlsInspectionProxyConfiguration. .PARAMETER UseConfiguredSeverity Uses endpoint severities after SDP promotion when true. .PARAMETER TimeoutInSeconds Connection and socket timeout for each endpoint probe. The default is 15 seconds. .PARAMETER ProbeAttemptCount Maximum number of attempts for each endpoint probe. The default is three attempts. .PARAMETER ProbeRetryDelaySeconds Delay between failed endpoint probe attempts. The default is three seconds. .OUTPUTS Hashtable objects returned by InfraIpTlsInspectionCheck. .EXAMPLE Invoke-InfraIpTlsInspectionCheckForAdapter ` -SourceIp '192.168.1.220' ` -PhysicalAdapterUsed 'Ethernet' ` -SslInspectionTargets $targets ` -LanguageText $lnTxt ` -ProxyConfiguration $proxyConfiguration #> param ( [Parameter(Mandatory = $true)] [System.String] $SourceIp, [Parameter(Mandatory = $true)] [System.String] $PhysicalAdapterUsed, [Parameter(Mandatory = $true)] [AllowNull()] [AllowEmptyCollection()] [PSObject[]] $SslInspectionTargets, [Parameter(Mandatory = $true)] $LanguageText, [Parameter(Mandatory = $true)] [PSObject] $ProxyConfiguration, [Parameter(Mandatory = $false)] [System.Boolean] $UseConfiguredSeverity = $false, [Parameter(Mandatory = $false)] [System.UInt16] $TimeoutInSeconds = 15, [Parameter(Mandatory = $false)] [ValidateRange(1, 10)] [System.UInt16] $ProbeAttemptCount = 3, [Parameter(Mandatory = $false)] [ValidateRange(0, 300)] [System.UInt16] $ProbeRetryDelaySeconds = 3 ) if (-not $SslInspectionTargets -or $SslInspectionTargets.Count -eq 0) { Log-Info "TLS inspection targets are null or empty. No TLS inspection checks will run for infra IP $SourceIp via physical adapter $PhysicalAdapterUsed." return @() } if (-not $ProxyConfiguration.Ready) { Log-Info "TLS inspection checks are skipped because the enabled proxy configuration could not be resolved." return InfraIpTlsInspectionCheck -SourceIp $SourceIp ` -PhysicalAdapterUsed $PhysicalAdapterUsed ` -SslInspectionTargets $SslInspectionTargets ` -LanguageText $LanguageText ` -UseConfiguredSeverity:$UseConfiguredSeverity ` -ProbeSkipReason $ProxyConfiguration.SkipReason } Log-Info "TLS inspection targets found ($($SslInspectionTargets.Count)). Starting checks for infra IP $SourceIp via physical adapter $PhysicalAdapterUsed." return InfraIpTlsInspectionCheck -SourceIp $SourceIp ` -PhysicalAdapterUsed $PhysicalAdapterUsed ` -SslInspectionTargets $SslInspectionTargets ` -LanguageText $LanguageText ` -ProxyHost $ProxyConfiguration.Host ` -ProxyPort $ProxyConfiguration.Port ` -TimeoutInSeconds $TimeoutInSeconds ` -ProbeAttemptCount $ProbeAttemptCount ` -ProbeRetryDelaySeconds $ProbeRetryDelaySeconds ` -UseConfiguredSeverity:$UseConfiguredSeverity } function New-InfraIpTlsInspectionAggregateResults { <# .SYNOPSIS Creates TLS inspection aggregate results for all tested infrastructure IPs. .DESCRIPTION Converts the endpoint observations grouped by infrastructure IP into validator results. SDP phase one produces one informational result per IP; promoted checks may produce one result per IP and configured severity. .PARAMETER DetailResultsByIp Hashtable whose keys are infrastructure IPs and values are lightweight endpoint results. .PARAMETER LanguageText Localized strings used to build aggregate results. .PARAMETER UseConfiguredSeverity Uses endpoint severities after SDP promotion when true. .OUTPUTS PSCustomObject instances returned by New-InfraIpTlsInspectionResult. .EXAMPLE New-InfraIpTlsInspectionAggregateResults ` -DetailResultsByIp $tlsDetailsByIp ` -LanguageText $lnTxt #> param ( [Parameter(Mandatory = $true)] [System.Collections.Hashtable] $DetailResultsByIp, [Parameter(Mandatory = $true)] $LanguageText, [Parameter(Mandatory = $false)] [System.Boolean] $UseConfiguredSeverity = $false ) $results = @() foreach ($sourceIp in @($DetailResultsByIp.Keys | Sort-Object)) { $results += @(New-InfraIpTlsInspectionResult -SourceIp $sourceIp ` -DetailResults $DetailResultsByIp[$sourceIp] ` -LanguageText $LanguageText ` -UseConfiguredSeverity:$UseConfiguredSeverity) } return $results } Export-ModuleMember -Function InfraIpTlsInspectionCheck, New-InfraIpTlsInspectionSkippedResult, New-InfraIpTlsInspectionResult, Get-InfraIpTlsInspectionProxyConfiguration, Invoke-InfraIpTlsInspectionCheckForAdapter, New-InfraIpTlsInspectionAggregateResults # SIG # Begin signature block # MIInUAYJKoZIhvcNAQcCoIInQTCCJz0CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBZeNm0okWpHip4 # e3yhlFFuzBFASyY628le5V9iKquXvaCCDMkwggYEMIID7KADAgECAhMzAAACHPrN # xZvoL37EAAAAAAIcMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNVBAYTAlVTMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBD # b2RlIFNpZ25pbmcgUENBIDIwMjQwHhcNMjYwNDE2MTg1OTQxWhcNMjcwNDE1MTg1 # OTQxWjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYD # VQQDExVNaWNyb3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IB # DwAwggEKAoIBAQDVsZfgOKmM31HPfoWOoNEiw0SlCiIxUMC0I9NMWbucKOw/e9lP # oAoehQVu6SG65V4EPzrYsnBnFPNoi4/HoOdjhz1qkrEt4I6tEcxXU6oOeY9zGveC # /3iBeuhLYxM3M/PkcUoebF+Nednm8OkdSPoDu8imViHPQq/8CQUu0WRR4rE+dMRf # rpVqfmNi2qWCX94T4MsepijGVkwE//tJg0ryAiYdHT34LSnlG/RSBZmQRGWZ5g8j # qnKjRParSqMft1gvjuUTVgtWNZfgcLFSK5Wa0myrq8OPcgTGGsRgun+tnSS+IxDT # xVsAPH1OzvPjwomguByhUe/OcvUN0D5Wmp7xAgMBAAGjggGqMIIBpjAOBgNVHQ8B # Af8EBAMCB4AwHwYDVR0lBBgwFgYKKwYBBAGCN0wIAQYIKwYBBQUHAwMwHQYDVR0O # BBYEFNoH7a2YDjOSwpkp6DHcmUS7J+0yMFQGA1UdEQRNMEukSTBHMS0wKwYDVQQL # EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxFjAUBgNVBAUT # DTIzMDAxMis1MDc1NjkwHwYDVR0jBBgwFoAUf1k/VCHarU/vBeXmo9ctBpQSCDEw # YAYDVR0fBFkwVzBVoFOgUYZPaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w # cy9jcmwvTWljcm9zb2Z0JTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAyMDI0LmNy # bDBtBggrBgEFBQcBAQRhMF8wXQYIKwYBBQUHMAKGUWh0dHA6Ly93d3cubWljcm9z # b2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwQ29kZSUyMFNpZ25pbmcl # MjBQQ0ElMjAyMDI0LmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IC # AQAUnEqhaRXe0T3hIJjvdQErEkrA/7bByjn6t5IArODkkRjzkYwtKMc2yYj2quaN # rLutWw2YZcngKPy1b71YyDJQTy4NDRwaSh9Tw5thrk3NmcPrAHia5vtcBJ1CgtKK # 7mQbIcQ22d/N3813ayCDDFewu1+jsZmX+r/aTEqaOM4TVxVtRSkuCy8nAXKuChOK # Li/zA4XuH8iEYqIsj2YoNaeSxVmeGiERXpKdo3dDmYi0kO5w2D8VS4c3+9h6gElY # BaAAg/dYErBg27qT3vv0zRDJhJufvCNylA8S7/+8H5E/PV5cng6na9VV/w9OV3qu # uND6zdGa2EX38Glp50F9AIQk3p2xXmcvorDeM4XJ7UlWYBi6g80J1SSOQnInCYFE # msfUNn3+1AaTJKSJL83quKArTac2pKhu0Yzzzrzo6HrsRiQKzpnRBb1/dMa6P3hz # 75XbMRBctNsFhZC07WCmjExdLg2eHW5uV0TY8D5+6wozJf7vF3+WHkYPO85Z+BC6 # U4FkNbYNycZ9cE4j1tXRdyDCfml6c0HWPHjNVDObrv9lKt3qUqFpX38VCqVCyNOO # 1UcXfQiVjJw32U2WUKZjt/neJKHEBsm9kFsLuWzkQ53+qcaSaytmsCnk2gOglrlD # 5d3kKyvvAw+rzm0lT8K38P6PLxfZQHhu4W8dV7Av8N2ZmDCCBr0wggSloAMCAQIC # EzMAAAA5O7Y3Gb8GHWcAAAAAADkwDQYJKoZIhvcNAQEMBQAwgYgxCzAJBgNVBAYT # AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBS # b290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDExMB4XDTI0MDgwODIwNTQxOFoX # DTM2MDMyMjIyMTMwNFowVzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29m # dCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQ # Q0EgMjAyNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANgBnB7jOMeq # lRYHNa265v4IY9fH8TKhemHfPINe1gpLaV3dhg324WwH06LcHbpnsBukCDNitryo # 0dtS/EW6I/yEL/bLSY8hKpbfQuWusBPr9qazYcDxCW/qnjb5JsI1s8bNOg3bVATv # QVL4tcf03aTycsz8QeCdM0l/yHRObJ9QqazM1r6VPEOJ7LL+uEEb73w6QCuhs89a # 1uv1zerOYMnsneRRwCbpyW11IcggU0cRKDDq1pjVJzIbIF6+oiXXbReOsgeI8zu1 # FyQfK0fVkaya8SmVHQ/tOf23mZ4W9k0Ri22QW9p3UgSC5OUDktKxxcCmGL6tXLfO # GSWHIIV4YrTJTT6PNty5REojHJuZHArkF9VnHTERWoTjAzfI3kP+5b4alUdhgAZ7 # ttOu1bVnXfHaqPYl2rPs20ji03LOVWsh/radgE17es5hL+t6lV0eVHrVhsssROWJ # uz2MXMCt7iw7lFPG9LXKGjsmonn2gotGdHIuEg5JnJMJVmixd5LRlkmgYRZKzhxS # CwyoGIq0PhaA7Y+VPct5pCHkijcIIDm0nlkK+0KyepolcqGm0T/GYQRMhHJlGOOm # VQop36wUVUYklUy++vDWeEgEo4s7hxN6mIbf2MSIQ/iIfMZgJxC69oukMUXCrOC3 # SkE/xIkgpfl22MM1itkZ35nNXkMolU1lAgMBAAGjggFOMIIBSjAOBgNVHQ8BAf8E # BAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFH9ZP1Qh2q1P7wXl5qPX # LQaUEggxMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMA8GA1UdEwEB/wQFMAMB # Af8wHwYDVR0jBBgwFoAUci06AjGQQ7kUBU7h6qfHMdEjiTQwWgYDVR0fBFMwUTBP # oE2gS4ZJaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMv # TWljUm9vQ2VyQXV0MjAxMV8yMDExXzAzXzIyLmNybDBeBggrBgEFBQcBAQRSMFAw # TgYIKwYBBQUHMAKGQmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMv # TWljUm9vQ2VyQXV0MjAxMV8yMDExXzAzXzIyLmNydDANBgkqhkiG9w0BAQwFAAOC # AgEAFJQfOChP7onn6fLIMKrSlN1WYKwDFgAddymOUO3FrM8d7B/W/iQ6DxXsDn7D # 5W4wMwYeLystcEqfkjz4NURRgazyMu5yRzQh4LqjA4tStTcJh1opExo7nn5PuPBY # nbu0+THSuVHTe0VTTPVhily/piFrDo3axQ9P4C+Ol5yet+2gTfekICS5xS+cYfSI # vgn0JksVBVMYVI5QFu/qhnLhsEFEUzG8fvv0hjgkO+lkpV9ty6GkN4vdnd7ya6Q6 # aR9y34aiM1qmxaxBi6OUnyNl6fkuun/diTFnYDLTppOkr/mg5WSfCiDVMNCxtj4w # PKC5OmHm1DQIt/MNokbbH3UGsFP1QbzsLocuSqLCvH09Io3fDPTmscR9Y75G4qX7 # RTX8AdBPo0I6OEojf39zuFZt0qOHm65YWQE69cZM2ueE1MB05dNNgHK9gTE7zKvK # /fg8B2qjW88MT/WF5V5uvZGtqa9FSL2RazArA+rDPuf6JGYz4HpgMZHB4S6szWSK # YBv0VisCzfxgeU+dquXW9bd0auYlOB58DPcOYKdc3Se94g+xL4pcEhbB54JOgAkw # YTu/9dLeH2pDqeJZAABVDWRQCaXfO5LgyKwKCLYXpigrZYCjUSBcr+Ve8PFWMhVT # Ql0v4q8J/AUmQN5W4n101cY2L4A7GTQG1h32HHAvfQESWP0xghndMIIZ2QIBATBu # MFcxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x # KDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMjQCEzMAAAIc # +s3Fm+gvfsQAAAAAAhwwDQYJYIZIAWUDBAIBBQCggZAwGQYJKoZIhvcNAQkDMQwG # CisGAQQBgjcCAQQwLwYJKoZIhvcNAQkEMSIEIHmgCP9xwSes2QTYft6oiohL4AFK # 5Id+2PYY/FqXjbzxMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8AcwBv # AGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEBBQAE # ggEAOiL9ia4XN/gDWEi5ousfOOINdEVi8zj8d/7h6ipzTMMLLvSx6h6/Xyh5X6F5 # PVPlhTfMzigBKD7+Y4CNwFqDfRdaKEmKsvwbqGqZwdf1s46WK+Ubk3Gx4ERkKa/e # xbb58io4SdAlyKbGFqeCTXIhaLOk20qPBACCKz9JQXaiIJCeJUaQyWM5gvRobDlb # rIMR5xuhU/XuIR46b26733k9OTdKyx5ctgk+pZAuPzxmpiC6PoVqriyKIX5rV7/Y # GqvMVKKl4T0M7FJBe4qz6eGWZu8OKDlD+/+UPKAKnkJ0e+KPyCtlUM4A6L/X54bw # pQXavcn0ySQP4QK6L8r7/JsUGaGCF60wghepBgorBgEEAYI3AwMBMYIXmTCCF5UG # CSqGSIb3DQEHAqCCF4YwgheCAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFaBgsqhkiG # 9w0BCRABBKCCAUkEggFFMIIBQQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQC # AQUABCAKBF8ITgiYa5CiYoB8SpFWI6VfWRC7CeZXJrjpF8u7ggIGaoigikNaGBMy # MDI2MDgyNzE2MzgzOC45MThaMASAAgH0oIHZpIHWMIHTMQswCQYDVQQGEwJVUzET # MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV # TWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFu # ZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjoy # RDFBLTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy # dmljZaCCEfswggcoMIIFEKADAgECAhMzAAACEtEIBjzKGE+qAAEAAAISMA0GCSqG # SIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw # DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x # JjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTI1MDgx # NDE4NDgxNVoXDTI2MTExMzE4NDgxNVowgdMxCzAJBgNVBAYTAlVTMRMwEQYDVQQI # EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv # ZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh # dGlvbnMgTGltaXRlZDEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjJEMUEtMDVF # MC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIIC # IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAr0zToDkpWQtsZekS0cV0quDd # KSTGkovvBaZH0OAIEi0O3CcO77JiX8c4Epq9uibHVZZ1W/LoufE172vkRXO+QYNt # WWorECJ2AcZQ10bpAltkhZNiXlVJ8L3QzhKgrXrmMkm2J+/g81U23JPcO4wXHEft # onT3wpd//936rjmwxMm7NkbsygbJf+4AVBMNr4aMPQhBd76od0KMB6WrvyEGOOU0 # 893OFufS5EDey4n44WgaxJE0Vnv3/OOvuOw5Kp1KPqjjYJ+L9ywLuBMtcDfLpNQO # /h1eFEoMrbiEM67TOfNlXfxbDz4MlsYvLioxgd2Xzey1QxrV1+i+JyVDJMiSe9gK # OuzpiQQFE19DUPgsidyjLTzXEhSVLBlRor0eCVf7gC6Rfk8NY3rO2sggOL79vU5F # uDKTh/sIOtcUHeHC42jBGB+tfdKC1KOBR+UlN9aOzg8mpUNI2FgqQvirVP9ppbeM # Ufvp2wA9voyTiRWvDgzCxo8xlJ1nscYTHIQrmkF9j/Ca0IDmt8fvOn64nnlJOGUY # ZYHMC1l0xtgkYTE1ESUqqkawKk7iqbxdnLyycS+dR+zaxPudMDLrQFz8lgfy9obk # 0D8HC2dzhWpYNn5hdkoPEzgCqQUOp8v3Qj/sd4anyupe5KoCkjABOP3yhSQ4W9Z+ # DrJnhM/rbsXC7oTv26cCAwEAAaOCAUkwggFFMB0GA1UdDgQWBBRSBblSxb5cYKYO # wvd/VfoXOfu33jAfBgNVHSMEGDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBfBgNV # HR8EWDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2Ny # bC9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmwwbAYI # KwYBBQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAy # MDEwKDEpLmNydDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMI # MA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAgEAXnSAkmX79Rc7lxS1 # wOozXJ7V0ou5DntVcOJplIkDjvEN8BIQph4U+gSOLZuVReP/z9YdUiUkcPwL1PM2 # 45/kEX1EegpxNc8HDA6hKCHg0ALNEcuxnGOlgKLokXfUer1D5hiW8PABM9R+neit # eTgPaaRlJFvGTYvotc0uqGiES5hMQhL8RNFhpS9RcIWHtnQGEnrdOUvCAhs4FeVi # awcmLTKv+1870c/MeTHi0QDdeR+7/Wg4qhkJ2k1iEHJdmYf8rIV0NRBZcdRTTdHe # e35SXP5neNCfAkjDIuZycRud6jzPLCNLiNYzGXBswzJygj4EeSORT7wMvaFuKeRA # XoXC3wwYvgIsI1zn3DGY625Y+yZSi8UNSNHuri36Zv9a+Q4vJwDpYK36S0TB2pf7 # xLiiH32nk7YK73Rg98W6fZ2INuzYzZ7Ghgvfffkj4EUXg1E0EffY1pEqkbpDTP7h # /DBqtzoPXsyw2MUh+7yvWcq2BGZSuca6CY6X4ioMuc5PWpsmvOOli7ARNA7Ab8kK # dCc2gNDLacglsweZEc9/VQB6hls/b6Kk32nkwuHExKlaeoSVrKB5U9xlp1+c8J/7 # GJj4Rw7AiQ8tcp+WmfyD8KxX2QlKbDi4SUjnglv4617R8+a/cDWJyaMt8279Wn7f # 2yMedN7kfGIQ5SZj66RdhdlZOq8wggdxMIIFWaADAgECAhMzAAAAFcXna54Cm0mZ # AAAAAAAVMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 # IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0 # ZSBBdXRob3JpdHkgMjAxMDAeFw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMyMjVa # MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT # HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0BAQEF # AAOCAg8AMIICCgKCAgEA5OGmTOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51yMo1 # V/YBf2xK4OK9uT4XYDP/XE/HZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY6GB9 # alKDRLemjkZrBxTzxXb1hlDcwUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9cmmv # Haus9ja+NSZk2pg7uhp7M62AW36MEBydUv626GIl3GoPz130/o5Tz9bshVZN7928 # jaTjkY+yOSxRnOlwaQ3KNi1wjjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDuaRr3t # pK56KTesy+uDRedGbsoy1cCGMFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74kpEe # HT39IM9zfUGaRnXNxF803RKJ1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2K26o # ElHovwUDo9Fzpk03dJQcNIIP8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5TI4C # vEJoLhDqhFFG4tG9ahhaYQFzymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZki1ug # poMhXV8wdJGUlNi5UPkLiWHzNgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9QBXps # xREdcu+N+VLEhReTwDwV2xo3xwgVGD94q0W29R6HXtqPnhZyacaue7e3PmriLq0C # AwEAAaOCAd0wggHZMBIGCSsGAQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUCBBYE # FCqnUv5kxJq+gpE8RjUpzxD/LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJlpxtT # NRnpcjBcBgNVHSAEVTBTMFEGDCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIBFjNo # dHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5o # dG0wEwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBD # AEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZW # y4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5t # aWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAt # MDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3 # dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0y # My5jcnQwDQYJKoZIhvcNAQELBQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/ypb+pc # FLY+TkdkeLEGk5c9MTO1OdfCcTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulmZzpT # Td2YurYeeNg2LpypglYAA7AFvonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM9W0j # VOR4U3UkV7ndn/OOPcbzaN9l9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECWOKz3 # +SmJw7wXsFSFQrP8DJ6LGYnn8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4FOmR # sqlb30mjdAy87JGA0j3mSj5mO0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3UwxTSw # ethQ/gpY3UA8x1RtnWN0SCyxTkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPXfx5b # RAGOWhmRaw2fpCjcZxkoJLo4S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVXVAmx # aQFEfnyhYWxz/gq77EFmPWn9y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGConsX # HRWJjXD+57XQKBqJC4822rpM+Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU5nR0 # W2rRnj7tfqAxM328y+l7vzhwRNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEGahC0 # HVUzWLOhcGbyoYIDVjCCAj4CAQEwggEBoYHZpIHWMIHTMQswCQYDVQQGEwJVUzET # MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV # TWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFu # ZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjoy # RDFBLTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy # dmljZaIjCgEBMAcGBSsOAwIaAxUA5VHBr4h00EN7jUdQ33SE+qbk/8CggYMwgYCk # fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH # UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD # Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQsFAAIF # AO46XqswIhgPMjAyNjA4MjcwNjU4NTFaGA8yMDI2MDgyODA2NTg1MVowdDA6Bgor # BgEEAYRZCgQBMSwwKjAKAgUA7jpeqwIBADAHAgEAAgIXqDAHAgEAAgISEDAKAgUA # 7juwKwIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAID # B6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBCwUAA4IBAQBynmH3cLGKEeWqFf7N # wlkJYXm6QsKw2V1AtD1LKn1NR3vEcsQbWL3z8or9rzZj8cQL31BfqSe6BWZqRbcJ # jbMcAknNS84usfl8AqJ/uROVVYBrUtkHHZeDZm4C6doP0+SlaXUCL8Hgz2MCdbTc # dJL+O3511vZP0OrmCDDjfVYRDJFFnHYM4OMgSVCJ9+ZPEGLIaU0p6KJrmJqxaq7d # H0+VltNC5BnmZO7sWgCiZtbptUDreL5YIMZnkE/bnFPRPlmwCJPC5oRVx0kOs68K # jrw/fCaHKuOjCr1B0Px7bjpmiQZwytJztS82y9vW4osReTDWylvj6pCpv2pVFUKW # cf0AMYIEDTCCBAkCAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp # bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw # b3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAC # EzMAAAIS0QgGPMoYT6oAAQAAAhIwDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3 # DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgMWWr0gVX/WenEL0F # LQYNviheCris5m5DjafF1EBDvmswgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9 # BCBz+X5GvO7WngknH4BZeYU+BzBL1Jy5oJ8wVlTNIxfYgzCBmDCBgKR+MHwxCzAJ # BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k # MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jv # c29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAACEtEIBjzKGE+qAAEAAAISMCIE # IHGRAiSPTSkiYEvB0iYMI6k6CML5AKkdzI2PhaGR645QMA0GCSqGSIb3DQEBCwUA # BIICACI3ziSG9NSHtfBJCzBJ+hVzvrioxp0m5uvpAyDAGvgs93w5BsDqCVHxLIZx # OFlFgGHpDv1w46ez2H7gxn0Qxq2h0ylOBluTU2JnfB6TqG9vib7+9u+dEkefhTb/ # pn+vc94m28826RAEIXMTC/JdSM4gjpbiYGxl58llsfvWO9kTcPWLuDcEnc+oGz3F # cntepRFXs+KrXbtLJ6ahhN4dwW3qC+lbuStF4JVQRQ/QpTkqsf5wxIPyn8MHjlAi # SetE6BQbujNfPu5keUbShskPwWqwdGuXrX6Hup1AH48yYy/X/bwdfFxoJhRFyqjA # c7m5new/N+TMNEdC1tezkYen9aE5hbM6K1HXQHUV0gJwJ1yMCx9gKJbLtSzUiVTA # dSCRyHQW+Qx6dEFMz+FvA+ynNBDtQveOLfZ9oH3GsH7bHpQqlcY8wsx30pj5cYxH # MuctDD7DeMVVYC+awD0HykMz+djKxmRESE5X24BXWF0ADNW4E6JSxAJqJwP4ZFF1 # jueHb+nuNElq+GVt80zkbEeU4cBYg1PSqJMNA4l+IJFdEIVIVvZiZmrrDfxlC1GS # 2PYvu4CvUHwqnuy4+wa7u1RZ9esUSzaYumUv6nBGX5uzSogOlhMCFsBQIUzDFrJk # I7+iVFhx4/DF2hIm074SD+qIeLBDtxbolckbm9C190bd09cp # SIG # End signature block |