Obs/bin/ObsDep/content/Powershell/Roles/Common/CertHelpers.psm1
# -------------------------------------------------------------- # Copyright � Microsoft Corporation. All Rights Reserved. # Microsoft Corporation (or based on where you live, one of its affiliates) licenses this sample code for your internal testing purposes only. # Microsoft provides the following sample code AS IS without warranty of any kind. The sample code arenot supported under any Microsoft standard support program or services. # Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. # The entire risk arising out of the use or performance of the sample code remains with you. # In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the code be liable for any damages whatsoever # (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) # arising out of the use of or inability to use the sample code, even if Microsoft has been advised of the possibility of such damages. # --------------------------------------------------------------- Function PrettyTime() { return "[" + (Get-Date -Format o) + "]" } Function Log($msg) { Write-Verbose $( $(PrettyTime) + " " + $msg) -Verbose } function GetSubjectName([bool] $UseManagementAddress) { if ($UseManagementAddress -eq $true) { # When IP Address is specified, we are currently looking just for IPv4 corpnet ip address # In the final design, only computer names will be used for subject names $corpIPAddresses = get-netIpAddress -AddressFamily IPv4 -PrefixOrigin Dhcp -ErrorAction Ignore if ($corpIPAddresses -ne $null -and $corpIPAddresses[0] -ne $null) { $mesg = [System.String]::Format("Using IP Address {0} for certificate subject name", $corpIPAddresses[0].IPAddress); Log $mesg return $corpIPAddresses[0].IPAddress } else { Log "Unable to find management IP address "; } } $hostFqdn = [System.Net.Dns]::GetHostByName(($env:computerName)).HostName; $mesg = [System.String]::Format("Using computer name {0} for certificate subject name", $hostFqdn); Log $mesg return $hostFqdn ; } function GenerateSelfSignedCertificate([string] $subjectName) { $cryptographicProviderName = "Microsoft Base Cryptographic Provider v1.0"; [int] $privateKeyLength = 1024; $sslServerOidString = "1.3.6.1.5.5.7.3.1"; $sslClientOidString = "1.3.6.1.5.5.7.3.2"; [int] $validityPeriodInYear = 5; $name = new-object -com "X509Enrollment.CX500DistinguishedName.1" $name.Encode("CN=" + $SubjectName, 0) $mesg = [System.String]::Format("Generating certificate with subject Name {0}", $subjectName); Log $mesg #Generate Key $key = new-object -com "X509Enrollment.CX509PrivateKey.1" $key.ProviderName = $cryptographicProviderName $key.KeySpec = 1 #X509KeySpec.XCN_AT_KEYEXCHANGE $key.Length = $privateKeyLength $key.MachineContext = 1 $key.ExportPolicy = 0x2 #X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG $key.Create() #Configure Eku $serverauthoid = new-object -com "X509Enrollment.CObjectId.1" $serverauthoid.InitializeFromValue($sslServerOidString) $clientauthoid = new-object -com "X509Enrollment.CObjectId.1" $clientauthoid.InitializeFromValue($sslClientOidString) $ekuoids = new-object -com "X509Enrollment.CObjectIds.1" $ekuoids.add($serverauthoid) $ekuoids.add($clientauthoid) $ekuext = new-object -com "X509Enrollment.CX509ExtensionEnhancedKeyUsage.1" $ekuext.InitializeEncode($ekuoids) # Set the hash algorithm to sha512 instead of the default sha1 $hashAlgorithmObject = New-Object -ComObject X509Enrollment.CObjectId $hashAlgorithmObject.InitializeFromAlgorithmName( $ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, $ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, $AlgorithmFlags.AlgorithmFlagsNone, "SHA512") #Request Cert $cert = new-object -com "X509Enrollment.CX509CertificateRequestCertificate.1" $cert.InitializeFromPrivateKey(2, $key, "") $cert.Subject = $name $cert.Issuer = $cert.Subject $cert.NotBefore = (get-date).ToUniversalTime() $cert.NotAfter = $cert.NotBefore.AddYears($validityPeriodInYear); $cert.X509Extensions.Add($ekuext) $cert.HashAlgorithm = $hashAlgorithmObject $cert.Encode() $enrollment = new-object -com "X509Enrollment.CX509Enrollment.1" $enrollment.InitializeFromRequest($cert) $certdata = $enrollment.CreateRequest(0) $enrollment.InstallResponse(2, $certdata, 0, "") Log "Successfully added cert to local machine store"; } function GivePermissionToNetworkService($targetCert) { $targetCertPrivKey = $targetCert.PrivateKey $privKeyCertFile = Get-Item -path "$ENV:ProgramData\Microsoft\Crypto\RSA\MachineKeys\*" | where {$_.Name -eq $targetCertPrivKey.CspKeyContainerInfo.UniqueKeyContainerName} $privKeyAcl = Get-Acl $privKeyCertFile $permission = "NT AUTHORITY\NETWORK SERVICE","Read","Allow" $accessRule = new-object System.Security.AccessControl.FileSystemAccessRule $permission $privKeyAcl.AddAccessRule($accessRule) Set-Acl $privKeyCertFile.FullName $privKeyAcl } Function AddCertToLocalMachineStore($certFullPath, $storeName, $securePassword) { $rootName = "LocalMachine" # create a representation of the certificate file $certificate = new-object System.Security.Cryptography.X509Certificates.X509Certificate2 if($securePassword -eq $null) { $certificate.import($certFullPath) } else { # https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509keystorageflags(v=vs.110).aspx $certificate.import($certFullPath, $securePassword, "MachineKeySet,PersistKeySet") } # import into the store $store = new-object System.Security.Cryptography.X509Certificates.X509Store($storeName, $rootName) $store.open("MaxAllowed") $store.add($certificate) $store.close() } Function GetSubjectFqdnFromCertificatePath($certFullPath) { # create a representation of the certificate file $certificate = new-object System.Security.Cryptography.X509Certificates.X509Certificate2 $certificate.import($certFullPath) return GetSubjectFqdnFromCertificate $certificate ; } Function GetSubjectFqdnFromCertificate([System.Security.Cryptography.X509Certificates.X509Certificate2] $certificate) { $mesg = [System.String]::Format("Parsing Subject Name {0} to get Subject Fqdn ", $certificate.Subject) Log $mesg $subjectFqdn = $certificate.Subject.Split('=')[1] ; return $subjectFqdn; } function Get-Certs($path){ $flags = [System.Security.Cryptography.X509Certificates.OpenFlags]"ReadOnly" $rootName = [System.Security.Cryptography.X509Certificates.StoreLocation]"LocalMachine" $store = New-Object System.Security.Cryptography.X509Certificates.X509Store($path, $rootName) $store.Open($flags) $certs = $store.Certificates $store.Close() return $certs } <# .Synopsis Export the Azure Stack cert to the file share #> function Export-AzSCertificateToShare { [CmdletBinding()] Param ( [Parameter(Mandatory = $true, HelpMessage="The CustomerConfiguration.xml")] [ValidateNotNull()] [CloudEngine.Configurations.EceInterfaceParameters] $Parameters, [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $CertBase64String, [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $ProtectedCertPwd, [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $CertificateName, [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $CertificateRoleId ) Import-Module Microsoft.AzureStack.Security.CngDpapi $clusterName = Get-ManagementClusterName $Parameters $externalCertificatesInfo = $Parameters.Roles['CertificateManagement'].PublicConfiguration.PublicInfo.ExternalCertConfigurations.Certificates | Where Type -EQ 'AzureAD' | Select -First 1 $certificateConfigXml = $externalCertificatesInfo.Certificate | Where Name -EQ $CertificateName $domainRole = $Parameters.Roles["Domain"].PublicConfiguration $domainName = $domainRole.PublicInfo.DomainConfiguration.DomainName Trace-Execution "$($MyInvocation.InvocationName) : Retreiving the cert information with cert name '$CertificateName' and cert role Id '$CertificateRoleId'..." $certificateInfo = (($externalCertificatesInfo.Certificate | Where Name -EQ $CertificateName).Consumers.Consumer | Where Name -EQ $CertificateRoleId | Select -First 1) Trace-Execution "$($MyInvocation.InvocationName) : Retrieved the unprocessed extension host cert path: $($certificateInfo.Location)" $certLocation = Get-SharePath $Parameters $certificateInfo.Location $clusterName Trace-Execution "$($MyInvocation.InvocationName) : Retrieved the extension host cert path: $certLocation" $protectToGMSA = $certificateInfo.ProtectTo if($protectToGMSA -ne $null) { Trace-Execution "$($MyInvocation.InvocationName) : ProtectTo parameter specified: $protectToGMSA" } Trace-Execution "$($MyInvocation.InvocationName) : Retreiving the Azure Stack internal CA Certificate password..." $securityInfo = $Parameters.Roles["Cloud"].PublicConfiguration.PublicInfo.SecurityInfo $certUser = $securityInfo.CACertUsers.User | Where Role -EQ "CACertificateUser" $certCredential = $Parameters.GetCredential($certUser.Credential) $exportCertPassword = $certCredential.GetNetworkCredential().SecurePassword if ($exportCertPassword.Length -eq 0) { throw "The Azure Stack internal cert password should not be empty" } Trace-Execution "$($MyInvocation.InvocationName) : Retrive the Azure Stack internal CA Certificate password." Trace-Execution "$($MyInvocation.InvocationName) : Converting cert from base64 string to binary..." $certBytes = [System.Convert]::FromBase64String($CertBase64String) Trace-Execution "$($MyInvocation.InvocationName) : Converting the protected password to local secure string..." $certPwdCipher = [System.Convert]::FromBase64String($ProtectedCertPwd) $certPwdCipherUnprotected = [Microsoft.AzureStack.Security.CngDpapi.ProtectionDescriptor]::UnprotectSecret($certPwdCipher) $certPwdString = [System.Text.Encoding]::UTF8.GetString($certPwdCipherUnprotected) $certPwd = ConvertTo-SecureString $certPwdString -AsPlainText -Force Trace-Execution "$($MyInvocation.InvocationName) : decrypting the cert with input password..." try { # SyslogClient cert location may have not been been provided. If this is the first time # processing a SyslogClient cert - by PEP cmdlet Set-SyslogClient - the path # must be checked and created before exporting the cert to the share location. # Also, doing the same for Container Registry certificate as it will be supplied # by the customer via Import-AzsContainerRegistrySslCertificate after deployment. if (($CertificateName -eq "SyslogClient") -or ($CertificateName -eq "Container Registry") -and !(Test-Path -Path $certLocation)) { Trace-Execution "$($MyInvocation.InvocationName) : $CertificateName certificate location: $certLocation was not found" $CertSharePath = Split-Path -Path $certLocation Trace-Execution "$($MyInvocation.InvocationName) : Checking $CertificateName certificate share path: $CertSharePath" if (!(Test-Path -Path $CertSharePath)) { Trace-Execution "$($MyInvocation.InvocationName) : $CertificateName certificate share path: $CertSharePath was not found" Trace-Execution "$($MyInvocation.InvocationName) : Creating $CertificateName certificate share path: $CertSharePath" New-Item -Path $CertSharePath -ItemType Directory -Force -ErrorAction Stop Trace-Execution "$($MyInvocation.InvocationName) : Verifying $CertificateName certificate share path: $CertSharePath was created" if (!(Test-Path -Path $CertSharePath)) { Throw "Failed to find and create $CertificateName certificate share path: $CertSharePath" } Trace-Execution "$($MyInvocation.InvocationName) : $CertificateName certificate share path: $CertSharePath was created successfully" } else { Trace-Execution "$($MyInvocation.InvocationName) : $CertificateName certificate share path: $CertSharePath was found" } } Trace-Execution "$($MyInvocation.InvocationName) : exporting the original binary to location $certLocation ..." Set-Content -Value $certBytes -Path $certLocation -Encoding Byte -Force if (!(Test-Path -Path $certLocation)) { Throw "Failed temporary creation of $CertificateName using cert bytes into $certLocation" } Trace-Execution "$($MyInvocation.InvocationName) : importing the original cert ..." $cert = Import-PfxCertificateSafe -Filepath $certLocation -CertStoreLocation cert:\LocalMachine\My -Password $certPwd -Exportable if ($null -eq $cert) { Throw "Failed local import of $CertificateName from share: $certLocation using provided certificate password" } if($protectToGMSA -ne $null) { Trace-Execution "$($MyInvocation.InvocationName) : exporting the cert binary to location $certLocation with Azure Stack internal password and $protectToGMSA account protection..." Export-PfxCertificate -Cert $cert -FilePath $certLocation -Password $exportCertPassword -ProtectTo @("$domainName\$protectToGMSA") } else { Trace-Execution "$($MyInvocation.InvocationName) : exporting the cert binary to location $certLocation with Azure Stack internal password..." Export-PfxCertificate -Cert $cert -FilePath $certLocation -Password $exportCertPassword } if (!(Test-Path -Path $certLocation)) { Throw "Failed exporting $CertificateName to certificate location $certLocation" } } catch { Remove-Item $certLocation -Force -Confirm:$false -Verbose -ErrorAction SilentlyContinue throw } } <# .Synopsis Imports certificates onto specific node based on role Id #> function Import-CertificateToNodesCertStore { [CmdletBinding()] Param ( [Parameter(Mandatory = $true, HelpMessage="The CustomerConfiguration.xml")] [ValidateNotNull()] [CloudEngine.Configurations.EceInterfaceParameters] $Parameters, [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $CertificateName, [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $CertificateRoleId, [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $CertificateType ) $clusterName = Get-ManagementClusterName $Parameters # Get certificate role Id definition Trace-Execution "$($MyInvocation.InvocationName) : Retrieving role definition for [$CertificateRoleId]" $roleDefinition = $Parameters.Roles[$CertificateRoleId].PublicConfiguration Trace-Execution "$($MyInvocation.InvocationName) : Retreiving the cert information based on type $CertificateType for role Id '$CertificateRoleId'..." $certificateInfo = $roleDefinition.PublicInfo.Certificates.Certificate | ? Type -EQ $CertificateType Trace-Execution "$($MyInvocation.InvocationName) : Retrieved the unprocessed cert path: $($certificateInfo.CertFile)" $certPath = "" try { $certPath = Get-SharePath $Parameters $certificateInfo.CertFile $clusterName Trace-Execution "$($MyInvocation.InvocationName) : Retrieved the cert path: $certPath" } catch { throw "Failed retrieving certificate path: $_" } # check if certificate is available if (![System.IO.File]::Exists($certPath)) { Trace-Execution "$($MyInvocation.InvocationName) : Certificate [$CertificateName] to import to nodes cert store is not available." return } Trace-Execution "$($MyInvocation.InvocationName) : Cert [$CertificateName] exists with path: $certPath" # Retrieve Azure Stack internal CA certificate password Trace-Execution "$($MyInvocation.InvocationName) : Retreiving the Azure Stack internal CA Certificate password..." $securityInfo = $Parameters.Roles["Cloud"].PublicConfiguration.PublicInfo.SecurityInfo $certUser = $securityInfo.CACertUsers.User | Where Role -EQ "CACertificateUser" $certCredential = $Parameters.GetCredential($certUser.Credential) $certSecurePassword = $certCredential.GetNetworkCredential().SecurePassword if ($certSecurePassword.Length -eq 0) { throw "The Azure Stack internal cert password should not be empty" } Trace-Execution "$($MyInvocation.InvocationName) : Retrived Azure Stack internal CA Certificate password." # Retrieve domain admin $domainAdminUser = $securityInfo.DomainUsers.User | ? Role -EQ $Parameters.Configuration.Role.PrivateInfo.Accounts.DomainAdminAccountID $domainAdmincredential = $Parameters.GetCredential($domainAdminUser.Credential) # Retrieve FQDN Trace-Execution "$($MyInvocation.InvocationName) : Retrieving domain role" $domainRole = $Parameters.Roles["Domain"].PublicConfiguration Trace-Execution "$($MyInvocation.InvocationName) : Retrieving domain name" $domainName = $domainRole.PublicInfo.DomainConfiguration.DomainName Trace-Execution "$($MyInvocation.InvocationName) : Retrieving domain FQDN" $domainFqdn = $domainRole.PublicInfo.DomainConfiguration.FQDN Trace-Execution "$($MyInvocation.InvocationName) : Domain FQDN is [$domainFqdn]" # retrieve nodes based on certificate role Id $roleVMNames = $roleDefinition.Nodes.Node.Name Trace-Execution "$($MyInvocation.InvocationName) : Role VM names are [$roleVMNames]" $roleVMNames = $roleVMNames | ForEach-Object {"$_.$domainFqdn"} Trace-Execution "$($MyInvocation.InvocationName) : Role VM FQDN are [$roleVMNames]" $certName = $CertificateName $certPermissions = $certificateInfo.Permissions.Permission $certStoreLocation = $certificateInfo.CertStore.Location if ($certPermissions -eq $null) { throw "Failed to retrieve certificate permissions" } if ($certStoreLocation -eq $null) { throw "Failed to retrieve certificate location" } $scriptBlock = { # Import certificate $cert = $null try { Write-Verbose "Importing certificate [$Using:certName] from path [$Using:certPath] with private key" -Verbose $cert = Import-PfxCertificateSafe -CertStoreLocation $Using:certStoreLocation -Exportable -Password $Using:certSecurePassword -FilePath $Using:certPath } catch { throw "Failed importing certificate into store", $_ } # Acl certificate private key try { $certPrivKey = $cert.PrivateKey $privKeyCertFile = Get-Item -path "$ENV:ProgramData\Microsoft\Crypto\RSA\MachineKeys\*" | where {$_.Name -eq $certPrivKey.CspKeyContainerInfo.UniqueKeyContainerName} if (!$privKeyCertFile) { throw "Was unable to retrieve certificate private key file" } $privKeyAcl = Get-Acl $privKeyCertFile foreach($permission in $Using:certPermissions) { $curPermission = $permission.User, $permission.Rights, "Allow" $accessRule = new-object System.Security.AccessControl.FileSystemAccessRule $curPermission $privKeyAcl.AddAccessRule($accessRule) } # To access private key of the certificate (for example during mutual authentication) we need to # acl the certificate private key file with the identified user(s) and permissions defined in role definition. Set-Acl $privKeyCertFile.FullName $privKeyAcl } catch { throw "Failed ACLing certificate private key", $_ } } Trace-Execution "Import certificate [$CertificateName] to machine(s) [$roleVMNames]..." $session = New-PSSession -ComputerName $roleVMNames -Credential $domainAdmincredential -Authentication Credssp try { Invoke-Command -Session $session -ScriptBlock $scriptBlock } catch { throw "Failed importing certificate on nodes", $_ } finally { $session | Remove-PSSession -ErrorAction Ignore | Out-Null } Trace-Execution "Finished importing certificate [$CertificateName] on machine(s) [$roleVMNames]" } <# .Synopsis Check whether a dev cert is present indicating this is an internal lab environment. #> function Test-DevCertPresent { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [CloudEngine.Configurations.EceInterfaceParameters] $Parameters ) $invokeCommandParams = @{ ScriptBlock = { Get-ChildItem "Cert:\LocalMachine\My" | where Subject -match "microsoftazurestacksupportteam" } } # Depending on where this code is running, we can check for the dev certificate in a different location. if ($env:ComputerName -eq $Parameters.Roles["DeploymentMachine"].PublicConfiguration.Nodes.Node.Name) { $invokeCommandParams.ComputerName = $Parameters.Roles["BareMetal"].PublicConfiguration.Nodes.Node.Name | select -First 1 Trace-Execution "Testing for presence of dev certificate on $($invokeCommandParams.ComputerName)." } else { Trace-Execution "Testing for presence of dev certificate on $env:ComputerName." } if (Invoke-Command @invokeCommandParams) { Trace-Execution "Found the dev certificate, indicating this is an internal environment." return $true } Trace-Execution "Dev certificate not found." return $false } Export-ModuleMember -Function AddCertToLocalMachineStore Export-ModuleMember -Function Export-AzSCertificateToShare Export-ModuleMember -Function GenerateSelfSignedCertificate Export-ModuleMember -Function Get-Certs Export-ModuleMember -Function GetSubjectFqdnFromCertificate Export-ModuleMember -Function GetSubjectFqdnFromCertificatePath Export-ModuleMember -Function GetSubjectName Export-ModuleMember -Function GivePermissionToNetworkService Export-ModuleMember -Function Import-CertificateToNodesCertStore Export-ModuleMember -Function Log Export-ModuleMember -Function PrettyTime Export-ModuleMember -Function Test-DevCertPresent # SIG # Begin signature block # MIIoKgYJKoZIhvcNAQcCoIIoGzCCKBcCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCASUbRL2iOrtico # tjC/ZFC0z+etQEJhww7qrg2mgn0SW6CCDXYwggX0MIID3KADAgECAhMzAAADTrU8 # esGEb+srAAAAAANOMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjMwMzE2MTg0MzI5WhcNMjQwMzE0MTg0MzI5WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQDdCKiNI6IBFWuvJUmf6WdOJqZmIwYs5G7AJD5UbcL6tsC+EBPDbr36pFGo1bsU # p53nRyFYnncoMg8FK0d8jLlw0lgexDDr7gicf2zOBFWqfv/nSLwzJFNP5W03DF/1 # 1oZ12rSFqGlm+O46cRjTDFBpMRCZZGddZlRBjivby0eI1VgTD1TvAdfBYQe82fhm # WQkYR/lWmAK+vW/1+bO7jHaxXTNCxLIBW07F8PBjUcwFxxyfbe2mHB4h1L4U0Ofa # +HX/aREQ7SqYZz59sXM2ySOfvYyIjnqSO80NGBaz5DvzIG88J0+BNhOu2jl6Dfcq # jYQs1H/PMSQIK6E7lXDXSpXzAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUnMc7Zn/ukKBsBiWkwdNfsN5pdwAw # RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW # MBQGA1UEBRMNMjMwMDEyKzUwMDUxNjAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci # tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG # CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu # Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0 # MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAD21v9pHoLdBSNlFAjmk # mx4XxOZAPsVxxXbDyQv1+kGDe9XpgBnT1lXnx7JDpFMKBwAyIwdInmvhK9pGBa31 # TyeL3p7R2s0L8SABPPRJHAEk4NHpBXxHjm4TKjezAbSqqbgsy10Y7KApy+9UrKa2 # kGmsuASsk95PVm5vem7OmTs42vm0BJUU+JPQLg8Y/sdj3TtSfLYYZAaJwTAIgi7d # hzn5hatLo7Dhz+4T+MrFd+6LUa2U3zr97QwzDthx+RP9/RZnur4inzSQsG5DCVIM # pA1l2NWEA3KAca0tI2l6hQNYsaKL1kefdfHCrPxEry8onJjyGGv9YKoLv6AOO7Oh # JEmbQlz/xksYG2N/JSOJ+QqYpGTEuYFYVWain7He6jgb41JbpOGKDdE/b+V2q/gX # UgFe2gdwTpCDsvh8SMRoq1/BNXcr7iTAU38Vgr83iVtPYmFhZOVM0ULp/kKTVoir # IpP2KCxT4OekOctt8grYnhJ16QMjmMv5o53hjNFXOxigkQWYzUO+6w50g0FAeFa8 # 5ugCCB6lXEk21FFB1FdIHpjSQf+LP/W2OV/HfhC3uTPgKbRtXo83TZYEudooyZ/A # Vu08sibZ3MkGOJORLERNwKm2G7oqdOv4Qj8Z0JrGgMzj46NFKAxkLSpE5oHQYP1H # tPx1lPfD7iNSbJsP6LiUHXH1MIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq # hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 # IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQG # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQg # Q29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC # CgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03 # a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akr # rnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0Rrrg # OGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy # 4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9 # sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAh # dCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8k # A/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTB # w3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmn # Eyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90 # lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0w # ggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2o # ynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD # VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBa # BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny # bC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsG # AQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29t # L3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNV # HSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3 # dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsG # AQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABl # AG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKb # C5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11l # hJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6 # I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0 # wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560 # STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQam # ASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGa # J+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ah # XJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA # 9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33Vt # Y5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr # /Xmfwb1tbWrJUnMTDXpQzTGCGgowghoGAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp # Z25pbmcgUENBIDIwMTECEzMAAANOtTx6wYRv6ysAAAAAA04wDQYJYIZIAWUDBAIB # BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO # MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIBYLCnIwE3ZtKPjT2FAeAcxV # M54l6IjsIS6Z3aE1tf2FMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A # cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB # BQAEggEAOGkKUMkQ5cVNhcnsS341gGiSQ33ldq20wzjSA84z+8NsIWVYksvKMWCu # Gry6UY2mkPSFcWpCanaX14g+c10sJPDCiggBKzVndENwjW6A/vZHTlLYYyigvyGT # +JzSwcszAwptZvQ2UTrCuTA2FJdfrNDZQo0bPpeIBohVZQMNeXoxRY9bYTWlTrr8 # 65dYJwJc7aqRsqI/HZsMZ8U4cL4zwp7qMzbW2wq/KgdpeMUrwjOW9F72Lo8DcWfq # Y2a8IDzH0VfbFcF5BZ2t0Qqg5UUPnLD/khI8ackTrEHvApBgJ42NWaIUVm4/vQgf # UgPmMCDsLWxO9FGBnMPhuxkK1JG+jqGCF5QwgheQBgorBgEEAYI3AwMBMYIXgDCC # F3wGCSqGSIb3DQEHAqCCF20wghdpAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFSBgsq # hkiG9w0BCRABBKCCAUEEggE9MIIBOQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl # AwQCAQUABCBtocmHE7tm1Vhsdw1/lM9EQiM6+49eKf+TC4FS3q0jaAIGZMvn7DWt # GBMyMDIzMDgwNzIxMzMzMi42NjVaMASAAgH0oIHRpIHOMIHLMQswCQYDVQQGEwJV # UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1l # cmljYSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046MzcwMy0w # NUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2Wg # ghHqMIIHIDCCBQigAwIBAgITMwAAAdTk6QMvwKxprAABAAAB1DANBgkqhkiG9w0B # AQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYD # VQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAeFw0yMzA1MjUxOTEy # MjdaFw0yNDAyMDExOTEyMjdaMIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz # aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv # cnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25z # MScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046MzcwMy0wNUUwLUQ5NDcxJTAjBgNV # BAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0GCSqGSIb3DQEB # AQUAA4ICDwAwggIKAoICAQCYU94tmwIkl353SWej1ybWcSAbu8FLwTEtOvw3uXMp # a1DnDXDwbtkLc+oT8BNti8t+38TwktfgoAM9N/BOHyT4CpXB1Hwn1YYovuYujoQV # 9kmyU6D6QttTIKN7fZTjoNtIhI5CBkwS+MkwCwdaNyySvjwPvZuxH8RNcOOB8ABD # hJH+vw/jev+G20HE0Gwad323x4uA4tLkE0e9yaD7x/s1F3lt7Ni47pJMGMLqZQCK # 7UCUeWauWF9wZINQ459tSPIe/xK6ttLyYHzd3DeRRLxQP/7c7oPJPDFgpbGB2HRJ # aE0puRRDoiDP7JJxYr+TBExhI2ulZWbgL4CfWawwb1LsJmFWJHbqGr6o0irW7IqD # kf2qEbMRT1WUM15F5oBc5Lg18lb3sUW7kRPvKwmfaRBkrmil0H/tv3HYyE6A490Z # FEcPk6dzYAKfCe3vKpRVE4dPoDKVnCLUTLkq1f/pnuD/ZGHJ2cbuIer9umQYu/Fz # 1DBreC8CRs3zJm48HIS3rbeLUYu/C93jVIJOlrKAv/qmYRymjDmpfzZvfvGBGUbO # px+4ofwqBTLuhAfO7FZz338NtsjDzq3siR0cP74p9UuNX1Tpz4KZLM8GlzZLje3a # HfD3mulrPIMipnVqBkkY12a2slsbIlje3uq8BSrj725/wHCt4HyXW4WgTGPizyEx # TQIDAQABo4IBSTCCAUUwHQYDVR0OBBYEFDzajMdwtAZ6EoB5Hedcsru0DHZJMB8G # A1UdIwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRYMFYwVKBSoFCG # Tmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUy # MFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEFBQcBAQRgMF4w # XAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2Vy # dHMvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3J0MAwG # A1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/BAQD # AgeAMA0GCSqGSIb3DQEBCwUAA4ICAQC0xUPP+ytwktdRhYlZ9Bk4/bLzLOzq+wcC # 7VAaRQHGRS+IPyU/8OLiVoXcoyKKKiRQ7K9c90OdM+qL4PizKnStLDBsWT+ds1ha # yNkTwnhVcZeA1EGKlNZvdlTsCUxJ5C7yoZQmA+2lpk04PGjcFhH1gGRphz+tcDNK # /CtKJ+PrEuNj7sgmBop/JFQcYymiP/vr+dudrKQeStcTV9W13cm2FD5F/XWO37Ti # +G4Tg1BkU25RA+t8RCWy/IHug3rrYzqUcdVRq7UgRl40YIkTNnuco6ny7vEBmWFj # cr7Skvo/QWueO8NAvP2ZKf3QMfidmH1xvxx9h9wVU6rvEQ/PUJi3popYsrQKuogp # hdPqHZ5j9OoQ+EjACUfgJlHnn8GVbPW3xGplCkXbyEHheQNd/a3X/2zpSwEROOcy # 1YaeQquflGilAf0y40AFKqW2Q1yTb19cRXBpRzbZVO+RXUB4A6UL1E1Xjtzr/b9q # z9U4UNV8wy8Yv/07bp3hAFfxB4mn0c+PO+YFv2YsVvYATVI2lwL9QDSEt8F0RW6L # ekxPfvbkmVSRwP6pf5AUfkqooKa6pfqTCndpGT71HyiltelaMhRUsNVkaKzAJrUo # ESSj7sTP1ZGiS9JgI+p3AO5fnMht3mLHMg68GszSH4Wy3vUDJpjUTYLtaTWkQtz6 # UqZPN7WXhjCCB3EwggVZoAMCAQICEzMAAAAVxedrngKbSZkAAAAAABUwDQYJKoZI # hvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw # DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x # MjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAy # MDEwMB4XDTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIyNVowfDELMAkGA1UEBhMC # VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV # BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp # bWUtU3RhbXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC # AQDk4aZM57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXIyjVX9gF/bErg4r25Phdg # M/9cT8dm95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjoYH1qUoNEt6aORmsHFPPF # dvWGUNzBRMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1yaa8dq6z2Nr41JmTamDu6 # GnszrYBbfowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v3byNpOORj7I5LFGc6XBp # Dco2LXCOMcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pGve2krnopN6zL64NF50Zu # yjLVwIYwXE8s4mKyzbnijYjklqwBSru+cakXW2dg3viSkR4dPf0gz3N9QZpGdc3E # XzTdEonW/aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYrbqgSUei/BQOj0XOmTTd0 # lBw0gg/wEPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlMjgK8QmguEOqEUUbi0b1q # GFphAXPKZ6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSLW6CmgyFdXzB0kZSU2LlQ # +QuJYfM2BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AFemzFER1y7435UsSFF5PA # PBXbGjfHCBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIurQIDAQABo4IB3TCCAdkw # EgYJKwYBBAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIEFgQUKqdS/mTEmr6CkTxG # NSnPEP8vBO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMFwGA1UdIARV # MFMwUQYMKwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWlj # cm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAK # BggrBgEFBQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC # AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX # zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v # cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI # KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDANBgkqhkiG # 9w0BAQsFAAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv6lwUtj5OR2R4sQaTlz0x # M7U518JxNj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZnOlNN3Zi6th542DYunKmC # VgADsAW+iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1bSNU5HhTdSRXud2f8449 # xvNo32X2pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4rPf5KYnDvBewVIVCs/wM # nosZiefwC2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU6ZGyqVvfSaN0DLzskYDS # PeZKPmY7T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDFNLB62FD+CljdQDzHVG2d # Y3RILLFORy3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/HltEAY5aGZFrDZ+kKNxn # GSgkujhLmm77IVRrakURR6nxt67I6IleT53S0Ex2tVdUCbFpAUR+fKFhbHP+Crvs # QWY9af3LwUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKiexcdFYmNcP7ntdAoGokL # jzbaukz5m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTmdHRbatGePu1+oDEzfbzL # 6Xu/OHBE0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZqELQdVTNYs6FwZvKhggNN # MIICNQIBATCB+aGB0aSBzjCByzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp # bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw # b3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEn # MCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjM3MDMtMDVFMC1EOTQ3MSUwIwYDVQQD # ExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMKAQEwBwYFKw4DAhoDFQAt # M12Wjo2xxA5sduzB/3HdzZmiSKCBgzCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w # IFBDQSAyMDEwMA0GCSqGSIb3DQEBCwUAAgUA6HusWTAiGA8yMDIzMDgwNzE3NDYw # MVoYDzIwMjMwODA4MTc0NjAxWjB0MDoGCisGAQQBhFkKBAExLDAqMAoCBQDoe6xZ # AgEAMAcCAQACAjdHMAcCAQACAhKlMAoCBQDofP3ZAgEAMDYGCisGAQQBhFkKBAIx # KDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJKoZI # hvcNAQELBQADggEBAHITE8uGuO9UrbNbg6/0phE8qAnlqPLB+BAuaQKkGq7N/FLI # b261b0KeMJTiQtuqSXKoO4oZaIl94fCGwk1dq3BvwVurvjjSFFkK1yEqHbHVqljg # tuxV+w/MjvX3BcuRBc5Oq+29u4nQLtrXyLobx0tFjr2NxPLFncG4T2m+qBtzPKP5 # fEv+irZVz+Cu43fac2uo88pL4VcYEe1yjqTKwInWdb017DxjYagpHoSpqK2+J/ty # 0ZCHKYnbLjL5fKX4VAII4jH3/DcwA9TyVP0JGAZCEQZf3gZcbajmREj89jlHNsOp # 5gv6qVIZkl5o1mY20MIiuR7KajENxrGo93c8pxoxggQNMIIECQIBATCBkzB8MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNy # b3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAdTk6QMvwKxprAABAAAB1DAN # BglghkgBZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8G # CSqGSIb3DQEJBDEiBCA22jU8CRmugp0gcOdf5UIrNpZdzGXejdBIEEA5s+XvRDCB # +gYLKoZIhvcNAQkQAi8xgeowgecwgeQwgb0EIMzqh/rYFKXOlzvWS5xCtPi9aU+f # BUkxIriXp2WTPWI3MIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh # c2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBD # b3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIw # MTACEzMAAAHU5OkDL8CsaawAAQAAAdQwIgQg7EOEZOoomDBv8SkbDLdBbzGn9fTn # Z8ys1vZyNyrK+3IwDQYJKoZIhvcNAQELBQAEggIAY/EEuaUlNwKJLzA2YC/J4zSg # a38Y5wceC8vwKHS5f4Zgq3wSlMZ7cEuxzkoDwyC2r6A7GZVVOCaZTpv5yjGM/6Ub # PyIVgzaG0EyT/RZjG/dmTYznO+92Vw9TnCNKRFFX2xR5xuJMMtOpprCZqb5X3Oaa # uaXNE6RFDHs5v8BN8R4h28JeGdNSmfyBW14LUV/zxGonJQYO31elgdQTj+bctebT # 3wgila2V8Io1+QfwQQ0k10kWuqaMV4MiqkuhUptCW637cv9DnjKeWeYZT4H42BMC # F+GRzIAS4XtehP9wwv9NKNQVuNjTBTGuyySbkV+HhWYs4R6silFU6cvACoINWaNM # fcePvbKGojdIGeC8jxHd/XV+gYvxQr+Yge7DJFDrQOyWtFHhjqLDbQjSCh1ltL0p # fSbWCCsfVSxYfEpPQlbTWdobNVX1KAhl07owcTIvt4NYTZHm/JfDE//Mym2xLdH4 # 36o/LshsUx/9wlLmlm4VAt15LroUwMrqRXQxf+qHxChRbafdyXjDkRY+PL65UF/f # kiv6L975Z60mjNUP0Sxx/dXDEeyvJTCYCXwAS11ZgYnsQl6G30mmkbd5J3R0KP6U # 4y4rrum+qNdbpsSUk4P07iPACRjlKln9dV2nhI9WNmIc4jKqaYjU36gmnlNq3CxJ # 1r3JfwwRNnYNqOIhKYU= # SIG # End signature block |