ContinuousAssurance/ContinuousAssurance.ps1
Set-StrictMode -Version Latest function Install-AzSKADOContinuousAssurance { <# .SYNOPSIS This command would help in setting up Continuous Assurance feature of AzSK.ADO in your subscription .DESCRIPTION This command will create a resource group (Name: ADOScannerRG) which runs security scan on organization and projects which are specified during installation. Security scan results will be populated in Log Analytics workspace which is configured during installation. Also, detailed logs will be stored in storage account (Name: adoscannersayyMMddHHmmss format). .PARAMETER SubscriptionId Subscription id in which CA setup needs to be done. .PARAMETER Location Location in which all resources need to be setup. .PARAMETER ResourceGroupName Resource group name where CA setup need to be done. (Default : ADOScannerRG) .PARAMETER LAWSId Workspace ID of Log Analytics workspace where security scan results will be sent .PARAMETER LAWSSharedKey Shared key of Log Analytics workspace which is used to monitor security scan results. .PARAMETER OrganizationName Organization name for which scan will be performed. .PARAMETER PATToken PAT token secure string for organization to be scanned. .PARAMETER PATTokenURL KeyVault URL for PATToken. .PARAMETER IdentityResourceId Resource id of user assigned managed identity to be used to access KeyVault for PATToken. .PARAMETER ProjectName Project to be scanned within the organization. .PARAMETER ExtendedCommand Extended command to narrow down the scans. .PARAMETER ScanIntervalInHours Overrides the default scan interval (24hrs) with the custom provided value. .PARAMETER CreateLAWorkspace Switch to create and map new log analytics workspace with CA setup. .NOTES This command helps the application team to verify whether their ADO resources are compliant with the security guidance or not #> Param( [Parameter(Mandatory = $true, ParameterSetName = "Default", HelpMessage="Subscription id in which CA setup needs to be done.")] [Parameter(Mandatory = $true, ParameterSetName = "CentralCA")] [Parameter(Mandatory = $true, ParameterSetName = "OAuthBasedCA")] [string] [Alias("sid")] $SubscriptionId , [Parameter(Mandatory = $true, ParameterSetName = "Default", HelpMessage = "Organization name for which scan will be performed.")] [Parameter(Mandatory = $true, ParameterSetName = "CentralCA")] [Parameter(Mandatory = $true, ParameterSetName = "OAuthBasedCA")] [ValidateNotNullOrEmpty()] [Alias("oz")] [string] $OrganizationName, [Parameter(Mandatory = $true, ParameterSetName = "Default", HelpMessage = "Project to be scanned within the organization.")] [Parameter(Mandatory = $true, ParameterSetName = "CentralCA")] [Parameter(Mandatory = $true, ParameterSetName = "OAuthBasedCA")] [Alias("pns", "ProjectNames","pn")] [string] $ProjectName, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage = "PAT token secure string for organization to be scanned.")] [ValidateNotNullOrEmpty()] [Alias("pat","tkn")] [System.Security.SecureString] $PATToken, [Parameter(Mandatory = $true, ParameterSetName = "CentralCA", HelpMessage = "KeyVault URL for PATToken")] [ValidateNotNullOrEmpty()] [Alias("ptu")] [string] $PATTokenURL, [Parameter(Mandatory = $true, ParameterSetName = "CentralCA", HelpMessage = "Resource id of user assigned managed identity")] [ValidateNotNullOrEmpty()] [Alias("ici")] [string] $IdentityResourceId, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage="Resource group name where CA setup needs to be done")] [Parameter(Mandatory = $false, ParameterSetName = "CentralCA")] [Parameter(Mandatory = $false, ParameterSetName = "OAuthBasedCA")] [string] [ValidateNotNullOrEmpty()] [Alias("rgn")] $ResourceGroupName, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage="Location in which all resources need to be setup.")] [Parameter(Mandatory = $false, ParameterSetName = "CentralCA")] [Parameter(Mandatory = $false, ParameterSetName = "OAuthBasedCA")] [string] [ValidateNotNullOrEmpty()] [Alias("loc")] $Location, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage="Workspace ID of Log Analytics workspace which is used to monitor security scan results.")] [Parameter(Mandatory = $false, ParameterSetName = "CentralCA")] [Parameter(Mandatory = $false, ParameterSetName = "OAuthBasedCA")] [string] [ValidateNotNullOrEmpty()] [Alias("lwid","wid")] $LAWSId, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage="Shared key of Log Analytics workspace which is used to monitor security scan results.")] [Parameter(Mandatory = $false, ParameterSetName = "CentralCA")] [Parameter(Mandatory = $false, ParameterSetName = "OAuthBasedCA")] [string] [ValidateNotNullOrEmpty()] [Alias("lwkey","wkey")] $LAWSSharedKey, [switch] [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage = "Switch to create and map new Log Analytics workspace with CA setup.")] [Parameter(Mandatory = $false, ParameterSetName = "CentralCA")] [Parameter(Mandatory = $false, ParameterSetName = "OAuthBasedCA")] [Alias("cws")] $CreateLAWorkspace, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage = "Use extended command to narrow down the target scan.")] [Parameter(Mandatory = $false, ParameterSetName = "CentralCA")] [Parameter(Mandatory = $false, ParameterSetName = "OAuthBasedCA")] [Alias("ex")] [string] $ExtendedCommand, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage = "Overrides the default scan interval (24hrs) with the custom provided value.")] [Parameter(Mandatory = $false, ParameterSetName = "CentralCA")] [Parameter(Mandatory = $false, ParameterSetName = "OAuthBasedCA")] [Alias("si")] [int] $ScanIntervalInHours, [Parameter(Mandatory = $true, ParameterSetName = "OAuthBasedCA")] [Alias("oai")] [System.Security.SecureString] $OAuthAppId, [Parameter(Mandatory = $true, ParameterSetName = "OAuthBasedCA")] [ValidateNotNullOrEmpty()] [Alias("csec")] [System.Security.SecureString] $ClientSecret, [Parameter(Mandatory = $true, ParameterSetName = "OAuthBasedCA")] [Alias("ausc")] [string] $AuthorizedScopes, [switch] [Parameter(Mandatory = $false, HelpMessage = "Create a storage account to store common data(eg. bug logging etc.).")] [Alias("cdsa")] $CreateCommonDataStorageAccount ) Begin { [CommandHelper]::BeginCommand($PSCmdlet.MyInvocation); [ListenerHelper]::RegisterListeners(); } Process { try { if ([string]::IsNullOrWhiteSpace($PATToken) -and [string]::IsNullOrWhiteSpace($PATTokenURL) -and $PSCmdlet.ParameterSetName -ne 'OAuthBasedCA' ) { $PATToken = Read-Host "Provide PAT for [$OrganizationName] org:" -AsSecureString } $resolver = [Resolver]::new($OrganizationName) $caAccount = [CAAutomation]::new($SubscriptionId, $Location,` $OrganizationName, $PATToken, $PATTokenURL, $ResourceGroupName, $LAWSId,` $LAWSSharedKey, $ProjectName, $IdentityResourceId,` $ExtendedCommand, $ScanIntervalInHours, $PSCmdlet.MyInvocation, $CreateLAWorkspace,` $OAuthAppId, $ClientSecret, $AuthorizedScopes, $CreateCommonDataStorageAccount); if ($PSCmdlet.ParameterSetName -eq 'Default') { $caAccount.InvokeFunction($caAccount.InstallAzSKADOContinuousAssurance) } elseif ($PSCmdlet.ParameterSetName -eq 'CentralCA') { $caAccount.InvokeFunction($caAccount.InstallAzSKADOCentralContinuousAssurance) } else { $caAccount.InvokeFunction($caAccount.InstallAzSKADOOAuthBasedContinuousAssurance) } } catch { [EventBase]::PublishGenericException($_); } } End { [ListenerHelper]::UnregisterListeners(); } } function Update-AzSKADOContinuousAssurance { <# .SYNOPSIS This command would help in updating user configurable properties of Continuous Assurance in your subscription .DESCRIPTION This command will update configurations of existing AzSK.ADO CA setup in your subscription. Security scan results will be populated in Log Analytics workspace which is configured during installation. Also, detailed logs will be stored in storage account (Name: adoscannersayyMMddHHmmss format). .PARAMETER SubscriptionId Subscription id in which CA setup is present. .PARAMETER ResourceGroupName Resource group name where CA setup is available (Default : ADOScannerRG). .PARAMETER LAWSId Workspace ID of Log Analytics workspace which is used to monitor security scan results. .PARAMETER LAWSSharedKey Shared key of Log Analytics workspace which is used to monitor security scan results. .PARAMETER AltLAWSId Alternate workspace ID of Log Analytics workspace where security scan results will be sent .PARAMETER AltLAWSSharedKey Alternate shared key of Log Analytics workspace which is used to monitor security scan results. .PARAMETER OrganizationName Organization name for which scan will be performed. .PARAMETER PATToken PAT token secure string for organization to be scanned. .PARAMETER PATTokenURL KeyVault URL for PATToken. .PARAMETER ProjectName Project to be scanned within the organization. .PARAMETER ExtendedCommand Extended command to narrow down the target scan. .PARAMETER ScanIntervalInHours Overrides the default scan interval (24hrs) with the custom provided value. .PARAMETER ClearExtendedCommand Use to clear extended command. .PARAMETER WebhookUrl Provide webhook url to enable it in CA setup. .PARAMETER WebhookAuthZHeaderName Provide webhook header name. .PARAMETER WebhookAuthZHeaderValue Provide webhook header value. .PARAMETER AllowSelfSignedWebhookCertificate Use this switch to allow self signed webhook certificate. #> Param( [Parameter(Mandatory = $true, ParameterSetName = "Default", HelpMessage="Subscription id in which CA setup is present.")] [string] [Alias("sid")] $SubscriptionId , [Parameter(Mandatory = $true, ParameterSetName = "Default", HelpMessage = "Orgnanization name for which scan will be performed.")] [Alias("oz")] [string] $OrganizationName, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage = "Project to be scanned within the organization.")] [Alias("pns", "ProjectNames", "pn")] [string] $ProjectName, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage = "PAT token secure string for organization to be scanned.")] [Alias("pat")] [System.Security.SecureString] $PATToken, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage = "KeyVault URL for PATToken")] [Alias("ptu")] [string] $PATTokenURL, [Parameter(Mandatory = $false, ParameterSetName = "Default")] [Alias("oai")] [switch] $RefreshOAuthToken, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage="Resource group name where CA setup is available. (Default : ADOScannerRG)")] [string] [Alias("rgn")] $ResourceGroupName, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage="Workspace ID of Log Analytics workspace where security scan results will be populated.")] [string] [Alias("lwid","wid","WorkspaceId")] $LAWSId, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage="Shared key of Log Analytics workspace which is used to monitor security scan results.")] [string] [Alias("lwkey","wkey","SharedKey")] $LAWSSharedKey, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage="Alternate workspace ID of Log Analytics workspace which is used to monitor security scan results.")] [string] [ValidateNotNullOrEmpty()] [Alias("alwid","awid")] $AltLAWSId, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage="Alternate shared key of Log Analytics workspace which is used to monitor security scan results.")] [string] [ValidateNotNullOrEmpty()] [Alias("alwkey","awkey")] $AltLAWSSharedKey, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage = "Use extended command to narrow down the scans.")] [Alias("ex")] [string] $ExtendedCommand, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage = "Overrides the default scan interval (24hrs) with the custom provided value.")] [Alias("si")] [int] $ScanIntervalInHours, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage = "Use to clear extended command.")] [Alias("cec")] [switch] $ClearExtendedCommand, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage = "Provide webhook url to enable it in CA setup.")] [Alias("wu")] [string] $WebhookUrl, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage = "Provide webhook header name.")] [Alias("wan")] [string] $WebhookAuthZHeaderName, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage = "Provide webhook header value.")] [Alias("wav")] [string] $WebhookAuthZHeaderValue, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage = "Use this switch to allow self signed webhook certificate.")] [Alias("awc")] [switch] $AllowSelfSignedWebhookCertificate, #Dev-Test support params below this [string] $RsrcTimeStamp, [string] $ContainerImageName, [string] $ModuleEnv, [bool] $UseDevTestImage, [int] $TriggerNextScanInMin ) Begin { [CommandHelper]::BeginCommand($PSCmdlet.MyInvocation); [ListenerHelper]::RegisterListeners(); } Process { try { if (-not [string]::IsNullOrEmpty($PATToken) -and -not [string]::IsNullOrEmpty($PATTokenURL)) { throw [SuppressedException] "'PATToken' and 'PATTokenURL' are exclusive parameters. Please use only one of them in the command" } if (-not [string]::IsNullOrEmpty($ExtendedCommand) -and $ClearExtendedCommand -eq $true) { throw [SuppressedException] "'ExtendedCommand' and 'ClearExtendedCommand' are exclusive parameters. Please use only one of them in the command" } else { $resolver = [Resolver]::new($OrganizationName) $caAccount = [CAAutomation]::new($SubscriptionId, $OrganizationName, $PATToken, $PATTokenURL, ` $ResourceGroupName, $LAWSId, $LAWSSharedKey, ` $AltLAWSId, $AltLAWSSharedKey, $ProjectName, $ExtendedCommand, ` $WebhookUrl, $WebhookAuthZHeaderName, $WebhookAuthZHeaderValue, $AllowSelfSignedWebhookCertificate, ` $RsrcTimeStamp, $ContainerImageName, $ModuleEnv, $UseDevTestImage, $TriggerNextScanInMin, ` $ScanIntervalInHours, $ClearExtendedCommand, $RefreshOAuthToken, $PSCmdlet.MyInvocation); return $caAccount.InvokeFunction($caAccount.UpdateAzSKADOContinuousAssurance); } } catch { [EventBase]::PublishGenericException($_); } } End { [ListenerHelper]::UnregisterListeners(); } } function Get-AzSKADOContinuousAssurance { <# .SYNOPSIS This command would help in getting details of Continuous Assurance Setup .PARAMETER SubscriptionId Subscription id in which CA setup is present. .PARAMETER OrganizationName Organization name for which CA is setup. .PARAMETER ResourceGroupName Resource group name where CA setup is available (Default : ADOScannerRG). .PARAMETER RsrcTimeStamp Timestamp of function app if multiple CA are setup in same resource group. #> Param( [Parameter(Mandatory = $true, ParameterSetName = "Default", HelpMessage="Subscription id in which CA setup is present.")] [string] [Alias("sid")] $SubscriptionId , [Parameter(Mandatory = $true, ParameterSetName = "Default", HelpMessage = "Orgnanization name for which scan will be performed.")] [Alias("oz")] [string] $OrganizationName, [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage="Resource group name where CA setup is available. (Default : ADOScannerRG)")] [string] [Alias("rg")] $ResourceGroupName , [Parameter(Mandatory = $false, ParameterSetName = "Default", HelpMessage="Timestamp of function app if multiple CA are setup in same resource group.")] [string] [Alias("rts")] $RsrcTimeStamp ) Begin { [CommandHelper]::BeginCommand($PSCmdlet.MyInvocation); [ListenerHelper]::RegisterListeners(); } Process { try { $resolver = [Resolver]::new($OrganizationName) $caAccount = [CAAutomation]::new($SubscriptionId, $OrganizationName, $ResourceGroupName, $RsrcTimeStamp, $PSCmdlet.MyInvocation); return $caAccount.InvokeFunction($caAccount.GetAzSKADOContinuousAssurance); } catch { [EventBase]::PublishGenericException($_); } } End { [ListenerHelper]::UnregisterListeners(); } } # SIG # Begin signature block # MIInuQYJKoZIhvcNAQcCoIInqjCCJ6YCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCC3wLhs67eLDSiz # A/P21SwXqmoksKQ60fAm0+Fg93nDrqCCDYEwggX/MIID56ADAgECAhMzAAACUosz # qviV8znbAAAAAAJSMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjEwOTAyMTgzMjU5WhcNMjIwOTAxMTgzMjU5WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQDQ5M+Ps/X7BNuv5B/0I6uoDwj0NJOo1KrVQqO7ggRXccklyTrWL4xMShjIou2I # sbYnF67wXzVAq5Om4oe+LfzSDOzjcb6ms00gBo0OQaqwQ1BijyJ7NvDf80I1fW9O # L76Kt0Wpc2zrGhzcHdb7upPrvxvSNNUvxK3sgw7YTt31410vpEp8yfBEl/hd8ZzA # v47DCgJ5j1zm295s1RVZHNp6MoiQFVOECm4AwK2l28i+YER1JO4IplTH44uvzX9o # RnJHaMvWzZEpozPy4jNO2DDqbcNs4zh7AWMhE1PWFVA+CHI/En5nASvCvLmuR/t8 # q4bc8XR8QIZJQSp+2U6m2ldNAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUNZJaEUGL2Guwt7ZOAu4efEYXedEw # UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1 # ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDY3NTk3MB8GA1UdIwQYMBaAFEhu # ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu # bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w # Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3 # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx # MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAFkk3 # uSxkTEBh1NtAl7BivIEsAWdgX1qZ+EdZMYbQKasY6IhSLXRMxF1B3OKdR9K/kccp # kvNcGl8D7YyYS4mhCUMBR+VLrg3f8PUj38A9V5aiY2/Jok7WZFOAmjPRNNGnyeg7 # l0lTiThFqE+2aOs6+heegqAdelGgNJKRHLWRuhGKuLIw5lkgx9Ky+QvZrn/Ddi8u # TIgWKp+MGG8xY6PBvvjgt9jQShlnPrZ3UY8Bvwy6rynhXBaV0V0TTL0gEx7eh/K1 # o8Miaru6s/7FyqOLeUS4vTHh9TgBL5DtxCYurXbSBVtL1Fj44+Od/6cmC9mmvrti # yG709Y3Rd3YdJj2f3GJq7Y7KdWq0QYhatKhBeg4fxjhg0yut2g6aM1mxjNPrE48z # 6HWCNGu9gMK5ZudldRw4a45Z06Aoktof0CqOyTErvq0YjoE4Xpa0+87T/PVUXNqf # 7Y+qSU7+9LtLQuMYR4w3cSPjuNusvLf9gBnch5RqM7kaDtYWDgLyB42EfsxeMqwK # WwA+TVi0HrWRqfSx2olbE56hJcEkMjOSKz3sRuupFCX3UroyYf52L+2iVTrda8XW # esPG62Mnn3T8AuLfzeJFuAbfOSERx7IFZO92UPoXE1uEjL5skl1yTZB3MubgOA4F # 8KoRNhviFAEST+nG8c8uIsbZeb08SeYQMqjVEmkwggd6MIIFYqADAgECAgphDpDS # AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 # IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0 # ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla # MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT # H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB # AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG # OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S # 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz # y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7 # 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u # M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33 # X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl # XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP # 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB # l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF # RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM # CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ # BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud # DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO # 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0 # LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y # Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p # Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y # Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB # FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw # cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA # XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY # 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj # 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd # d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ # Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf # wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ # aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j # NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B # xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96 # eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7 # r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I # RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIZjjCCGYoCAQEwgZUwfjELMAkG # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAlKLM6r4lfM52wAAAAACUjAN # BglghkgBZQMEAgEFAKCBsDAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQghylDzXya # v1VsJ82kz6TL4OHldbviGgfMp7aUJM343pgwRAYKKwYBBAGCNwIBDDE2MDSgFIAS # AE0AaQBjAHIAbwBzAG8AZgB0oRyAGmh0dHBzOi8vd3d3Lm1pY3Jvc29mdC5jb20g # MA0GCSqGSIb3DQEBAQUABIIBAM/5faU8dr4OQbkxNWC/3yHVt+uZdmQZo6DNtOfP # hfLUP9tMzIp5pa+Kmnk74lPm+XqWKdvWbzpgNQ0oD7F6/iKQXwQh/YgBa6xlA+AW # IYwCbv16/8TsGoj880ocqOx4QNvSavgKRcVyrTazuOUSumf2drz/jdxmO6SpTE3G # SUmwjhT4znXCCNdWHLS4FhoGWvILaNct4cCTcGFsZoOxTuBQo+yiGuDRqdANS5Xm # WkX0Uj2++VBm9dmj854SoOIp1gJupjV+1N1vzh3uHtuAPlzIWA0Ys/KeQ7PgZdXw # 5eTuyGEkneFsfQ/RPUDd0OXnt6k7uk+IwNR/F4kZV6/hBAyhghcWMIIXEgYKKwYB # BAGCNwMDATGCFwIwghb+BgkqhkiG9w0BBwKgghbvMIIW6wIBAzEPMA0GCWCGSAFl # AwQCAQUAMIIBWQYLKoZIhvcNAQkQAQSgggFIBIIBRDCCAUACAQEGCisGAQQBhFkK # AwEwMTANBglghkgBZQMEAgEFAAQgHxSBCebqCzckFyZfSLueP2DSMR2Koj8f7jvM # HFJnNNkCBmHCS8FbYhgTMjAyMjAxMTMxMjU0MDQuNTQ1WjAEgAIB9KCB2KSB1TCB # 0jELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl # ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMk # TWljcm9zb2Z0IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1U # aGFsZXMgVFNTIEVTTjo4NkRGLTRCQkMtOTMzNTElMCMGA1UEAxMcTWljcm9zb2Z0 # IFRpbWUtU3RhbXAgU2VydmljZaCCEWUwggcUMIIE/KADAgECAhMzAAABjAGXYkc2 # dmY7AAEAAAGMMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQI # EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv # ZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBD # QSAyMDEwMB4XDTIxMTAyODE5Mjc0NFoXDTIzMDEyNjE5Mjc0NFowgdIxCzAJBgNV # BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w # HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29m # dCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEmMCQGA1UECxMdVGhhbGVzIFRT # UyBFU046ODZERi00QkJDLTkzMzUxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0 # YW1wIFNlcnZpY2UwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDTSGhM # oRP5IaxrLD70EV2b65n6S8Q8Yt3mwXxeVPdTLhgapPzr4OvwbeTqr+VFqCLFEq+f # 6DYAVEv1W5moLW5O9rt1k30KGKi0ccWbLJBk9qVd0lMLycoituBMxcDCH+ZuGeah # rGwj2MaWK9iCLkY04Tu7pNXhQ62dU/yKiFNR80wqFlol3OZYOOFYLsuM9ciFqb1C # FGRXOuTF8kpzn0CxoYPc++JGSAegbF+l1Yc89pbyKIQeNzg8OYIqW5bcn4h1Tfwf # 4yQo+Z6QLsa1FMtcoEK5YpdLxONlj/CQ1zNY0Sj6Xknc5l0d5WKDGnMKd6yRl9wd # fGsJfaG57uom9auSwVK2Rls4bshiZp9gxCtka6WXvY+dLWgh1B1idHn+eBy9JBvX # UZDSQ0wPOIqxJ37mJ9RphsktnRcTE1XiotcJLrkOP7wXKAKO02+QOIHkez0jsr3P # FmxRvt8opIYRn3IDQmBNZtwA8Jg+24AdUnxQppP3rukmbv6veGBx7fxVTf2yl54c # eBoJLi9et6VMuJQwCXQ62TmdwpApzaQae+7A/ZEJLeQQQUDGifAufynJ53Kt5lNs # ExAGp/WjeSPSKU4nv9/8/dzWudpg7TUYMmia/ui2lvnP7WGtKgizy77p6u4koJOK # F3SL/xtzrsAoXvrCla69b0GFtQxOxaTDDivjZwIDAQABo4IBNjCCATIwHQYDVR0O # BBYEFJbOU4apgiFgiHlWnT6Iyt1Ai1IjMB8GA1UdIwQYMBaAFJ+nFV0AXmJdg/Tl # 0mWnG1M1GelyMF8GA1UdHwRYMFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0 # LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAy # MDEwKDEpLmNybDBsBggrBgEFBQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93 # d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVGltZS1T # dGFtcCUyMFBDQSUyMDIwMTAoMSkuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAww # CgYIKwYBBQUHAwgwDQYJKoZIhvcNAQELBQADggIBANdoxUVYwgmp1uVBkrqiSztx # 0JTB48CaYQh52zK6yBQwhCVCpqN8I/2IbnzI4VJHHaTn2PaEAFJkHEWZuRWPCFgQ # LXIk9Cb3jriBTPkb645bnWLy5554HeHaL4OahY0o1K6Ug3J9IaBbo8IMKJGo7eqf # wphXMvOh6Z8+Kv9RXHkICBVwQMAy3FtGtMdcEAFfIJrppDf6O6RYHlpDMvDqqEeH # Pscg5T2r9D1jY2dUEo9/MiXA+NvY2tAZ9CddOyx8UP3w6lEerTtlTHbWDimzxXfe # FJKQna4PCG2nlW0UacX4DHMUGUK9zfcs9OZexzOXLr7JCABHCY0d40DbrZaosskz # zgjPw5LVV8TU3rJgKQuODzX7MZeyO8waaMGWLLFnBdYZYmayi8HpPqHUat+a8wq5 # 04T3YPrtJHfNPcN0DknAv1MDNfxSGLRoZi2fm41QMVvEijMhEyktWk/9g4ueD6va # /yzyXJa/Rp+PBlgcEnrgxZU3Edxo22PORi1CN1nluHKRrp1f4O1AP1uHfOOLRKWt # 9UMgvERvo6PKq18aPuJZm8mtvgCohWAdBoPOC6LERL2J60WKQd9/qn3sLmqhtNNs # rA3QAQ/erm17Ij00g5WUmXSCLkht3nweJ/cks7q+n7nIdeOhIv8yWEWa8a1piZDA # PsrNOb24AMXgHM/+bHa/MIIHcTCCBVmgAwIBAgITMwAAABXF52ueAptJmQAAAAAA # FTANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp # bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw # b3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0 # aG9yaXR5IDIwMTAwHhcNMjEwOTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1WjB8MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNy # b3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEBBQADggIP # ADCCAgoCggIBAOThpkzntHIhC3miy9ckeb0O1YLT/e6cBwfSqWxOdcjKNVf2AX9s # SuDivbk+F2Az/1xPx2b3lVNxWuJ+Slr+uDZnhUYjDLWNE893MsAQGOhgfWpSg0S3 # po5GawcU88V29YZQ3MFEyHFcUTE3oAo4bo3t1w/YJlN8OWECesSq/XJprx2rrPY2 # vjUmZNqYO7oaezOtgFt+jBAcnVL+tuhiJdxqD89d9P6OU8/W7IVWTe/dvI2k45GP # sjksUZzpcGkNyjYtcI4xyDUoveO0hyTD4MmPfrVUj9z6BVWYbWg7mka97aSueik3 # rMvrg0XnRm7KMtXAhjBcTyziYrLNueKNiOSWrAFKu75xqRdbZ2De+JKRHh09/SDP # c31BmkZ1zcRfNN0Sidb9pSB9fvzZnkXftnIv231fgLrbqn427DZM9ituqBJR6L8F # A6PRc6ZNN3SUHDSCD/AQ8rdHGO2n6Jl8P0zbr17C89XYcz1DTsEzOUyOArxCaC4Q # 6oRRRuLRvWoYWmEBc8pnol7XKHYC4jMYctenIPDC+hIK12NvDMk2ZItboKaDIV1f # MHSRlJTYuVD5C4lh8zYGNRiER9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6bMURHXLv # jflSxIUXk8A8FdsaN8cIFRg/eKtFtvUeh17aj54WcmnGrnu3tz5q4i6tAgMBAAGj # ggHdMIIB2TASBgkrBgEEAYI3FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQWBBQqp1L+ # ZMSavoKRPEY1Kc8Q/y8E7jAdBgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacbUzUZ6XIw # XAYDVR0gBFUwUzBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDov # L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMG # A1UdJQQMMAoGCCsGAQUFBwMIMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsG # A1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJc # YmjRPZSQW9fOmhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9z # b2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIz # LmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWlj # cm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0 # MA0GCSqGSIb3DQEBCwUAA4ICAQCdVX38Kq3hLB9nATEkW+Geckv8qW/qXBS2Pk5H # ZHixBpOXPTEztTnXwnE2P9pkbHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6U03dmLq2 # HnjYNi6cqYJWAAOwBb6J6Gngugnue99qb74py27YP0h1AdkY3m2CDPVtI1TkeFN1 # JFe53Z/zjj3G82jfZfakVqr3lbYoVSfQJL1AoL8ZthISEV09J+BAljis9/kpicO8 # F7BUhUKz/AyeixmJ5/ALaoHCgRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTpkbKpW99J # o3QMvOyRgNI95ko+ZjtPu4b6MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0sHrYUP4K # WN1APMdUbZ1jdEgssU5HLcEUBHG/ZPkkvnNtyo4JvbMBV0lUZNlz138eW0QBjloZ # kWsNn6Qo3GcZKCS6OEuabvshVGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJsWkBRH58 # oWFsc/4Ku+xBZj1p/cvBQUl+fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7Fx0ViY1w # /ue10CgaiQuPNtq6TPmb/wrpNPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0dFtq0Z4+ # 7X6gMTN9vMvpe784cETRkPHIqzqKOghif9lwY1NNje6CbaUFEMFxBmoQtB1VM1iz # oXBm8qGCAtQwggI9AgEBMIIBAKGB2KSB1TCB0jELMAkGA1UEBhMCVVMxEzARBgNV # BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv # c29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0IElyZWxhbmQgT3Bl # cmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo4NkRGLTRC # QkMtOTMzNTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaIj # CgEBMAcGBSsOAwIaAxUANKLyFOur9DyimnB4bK5ks0Qmr9WggYMwgYCkfjB8MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNy # b3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIFAOWKczkw # IhgPMjAyMjAxMTMxNzQ1MjlaGA8yMDIyMDExNDE3NDUyOVowdDA6BgorBgEEAYRZ # CgQBMSwwKjAKAgUA5YpzOQIBADAHAgEAAgIK+jAHAgEAAgIRSzAKAgUA5YvEuQIB # ADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAIDB6EgoQow # CAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAIOiFJNf0lXzlv6rebTpR9r8utan # jlNyaZ5h1MWnryrIxqMBtXBMo6p556yzsQ1dga8Oha3s1c6QYvaXdRnMBBt4Sb/s # h+q+P464KOh9oXaUSn/iJ8v+zNYkK4MdW/An584u+z1G+p/si7xnNDcUZps+7beM # 8HvkwVPIY5XRS1nwMYIEDTCCBAkCAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNV # BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv # c29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAg # UENBIDIwMTACEzMAAAGMAZdiRzZ2ZjsAAQAAAYwwDQYJYIZIAWUDBAIBBQCgggFK # MBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQg71Fd # 8EOWzHEyiBZzUUfnmerThFPBaEhL+8G/DlvInKowgfoGCyqGSIb3DQEJEAIvMYHq # MIHnMIHkMIG9BCDVrYv4FSqQzwZ/xOYhBZ2B4pNOthcjA6h864mIGJhpnjCBmDCB # gKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH # EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNV # BAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAABjAGXYkc2dmY7 # AAEAAAGMMCIEIEsFzk/mHCws+XFm55spfMW5+JrDVKqmOAz1mPlH1G82MA0GCSqG # SIb3DQEBCwUABIICAGw2wrSjmBGColugWcMzZS2/ikUxlNis1lKTjw+fXaG/TuvC # +RAvf3f477/MDCfE/12fVQY1jcw0zHAIgUlxeFYyZYWK3TYf7lGvYCiFsKBEkSJL # RQXn8ilf55dvltvRRuCrMiPx4RBwh6RjtL+KSdrKRn368Q6cBZpFQ6EUz98SANO4 # f9W9huFEeDUybp7tPIww6PU7TgVeYCegRUPGfXZ92T9Zre3KPl+ICp1Fx64R6o6L # zJTEND0I1eiemriNTLWL+kQ7znP2TobqQBr32Sw37803TLxNiIoqVhjbebU2MhUF # V3Gss421HG1ZyT0GvUKBTgNsHjL+SZZ13OkZbixZUasSLMoCj2WkiWDI7poOjGV8 # wsN9HYjgLDT1IXc7X02gwGAAaIjdqENsXyFXVlgvilYAm0S1yMyakBrlaJMETtMy # ABBUAA6c6tYrDbtFStlAvex5si4Ni2suOPVbfpRfFqP2gly4zYHJG4aDOm4EyWQj # R+Crrth0YX04gPfpOgCks05I7lhCAa1ZgWRWBWJsjsQTHVWjPPOBFPFkYdmOAPM0 # hSwhpbWOnYzVBBYmqW6Ik8ytOMIHsusrrk+coXq53tYj3qTFGam6GkEEpt5FOrC9 # /lqZY3h8K59fkDthcjWy63gcZzgdFT1msL9G8fw0fQz7rJHb0SVQjK31YrZj # SIG # End signature block |