Private/estclient.ps1
|
using namespace System.Security.Cryptography.X509Certificates using namespace System.Security.Authentication using namespace System.Net.Http using namespace System.Net.Security # This existance of this function is important for tests, so it can be mocked Function CreateHttpClient($HttpMessageHandler) { $client = New-Object HttpClient($HttpMessageHandler) return $client } Function IsCertificateCaOfACertificateInTheCollection { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [System.Security.Cryptography.X509Certificates.X509Certificate2]$PossibleCaCertificate, [Parameter(Mandatory=$true)] [System.Security.Cryptography.X509Certificates.X509Certificate2Collection]$Certificates ) $issuedCertificates = $certificates | Where-Object { $_.Issuer -eq $PossibleCaCertificate.Subject } return $issuedCertificates.Count -gt 0 } # Define this callback in C#, so it doesn't require a PowerShell runspace to run. This way, it can be called back in a different thread. $csCodeSelectFirstCertificateCallback = @' public static class CertificateCallbacks { public static System.Security.Cryptography.X509Certificates.X509Certificate SelectFirstCertificate( object sender, string targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection localCertificates, System.Security.Cryptography.X509Certificates.X509Certificate remoteCertificate, string[] acceptableIssuers) { return localCertificates[0]; } public static System.Net.Security.LocalCertificateSelectionCallback SelectionCallback { get { return SelectFirstCertificate; } } } '@ Add-Type -TypeDefinition $csCodeSelectFirstCertificateCallback -Language CSharp Function RenewCertificateMTLS { [CmdletBinding()] [OutputType([System.Security.Cryptography.X509Certificates.X509Certificate2])] param ( [Parameter(Mandatory=$true)] [System.Security.Cryptography.X509Certificates.X509Certificate2]$Certificate, [Parameter(Mandatory=$false)] [string]$AppServiceUrl, [Parameter(Mandatory=$false)] [switch]$User, [Parameter(Mandatory=$false)] [switch]$Machine ) if (!$User -and !$Machine) { if ($Certificate.PSParentPath.StartsWith('Microsoft.PowerShell.Security\Certificate::CurrentUser\My')) { $User = $true } elseif ($Certificate.PSParentPath.StartsWith('Microsoft.PowerShell.Security\Certificate::LocalMachine\My')) { $Machine = $true } else { throw "You must specify either -user or -machine." } } elseif ($User -and $Machine) { throw "You must not specific both -user or -machine." } if ([string]::IsNullOrEmpty($AppServiceUrl)) { Write-Verbose "No AppServiceUrl was specified. Trying to get the AppServiceUrl from the certificate's AIA extension." if ($PSVersionTable.PSVersion.Major -lt 7) { $AiaExtension = $Certificate.Extensions | Where-Object { $_.Oid.Value -eq '1.3.6.1.5.5.7.1.1' } if ($null -eq $AiaExtension) { throw "No AppServiceUrl was specified and the certificate does not have an AIA extension to infer it from." } $Encoding = New-Object System.Text.UTF8Encoding $AppServiceUrl = [Regex]::Match($Encoding.GetString($AIA.RawData), 'https://.*?GetCACert').Value if ([string]::IsNullOrEmpty($AppServiceUrl)) { throw "No AppServiceUrl was specified and the certificate does not have any CA Issuers URLs in the AIA extension to infer it from." } } else { $AiaExtension = $Certificate.Extensions | Where-Object { $_ -is [X509AuthorityInformationAccessExtension] } if ($null -eq $AiaExtension) { throw "No AppServiceUrl was specified and the certificate does not have an AIA extension to infer it from." } $CaUrls = $AiaExtension.EnumerateCAIssuersUris() if ($CaUrls.Count -eq 0) { throw "No AppServiceUrl was specified and the certificate does not have any CA Issuers URLs in the AIA extension to infer it from." } $AppServiceUrl = $CaUrls[0] # This contains some path for the CA download that we still need to cut off } Write-Verbose "Found AIA CA URL in certificate: $AppServiceUrl" $AppServiceUrl = $AppServiceUrl.Substring(0, $AppServiceUrl.IndexOf('/', "https://".Length)) Write-Information "Inferred AppServiceUrl from AIA extension: $AppServiceUrl" } $AppServiceUrl = $AppServiceUrl.TrimEnd('/') $url = "$AppServiceUrl/.well-known/est/simplereenroll" # Use the same key algorithm as the original certificate if ($Certificate.PublicKey.Oid.Value -eq "1.2.840.10045.2.1") { $publicKey = $cert.PublicKey.GetECDiffieHellmanPublicKey().PublicKey $curve = $publicKey.ExportParameters().Curve $privateKey = [System.Security.Cryptography.ECDsa]::Create($curve) $oCertRequest = [System.Security.Cryptography.X509Certificates.CertificateRequest]::new($Certificate.Subject, $privateKey, [System.Security.Cryptography.HashAlgorithmName]::SHA256) } elseif ($Certificate.PublicKey.Oid.Value -eq "1.2.840.113549.1.1.1") { $privateKey = [System.Security.Cryptography.RSA]::Create($Certificate.PublicKey.Key.KeySize) $oCertRequest = [System.Security.Cryptography.X509Certificates.CertificateRequest]::new($Certificate.Subject, $privateKey, [System.Security.Cryptography.HashAlgorithmName]::SHA256, [System.Security.Cryptography.RSASignaturePadding]::Pkcs1) } else { throw "Unsupported key algorithm: $($Certificate.PublicKey.Oid.Value) ($($Certificate.PublicKey.Oid.FriendlyName))" } Write-Information "Private key created of type $($privateKey.SignatureAlgorithm) with $($privateKey.KeySize) bits" if ($PSVersionTable.PSVersion.Major -lt 7) { $sCertRequestDER = $oCertRequest.CreateSigningRequest() $sCertRequestB64 = [System.Convert]::ToBase64String($sCertRequestDER) $sCertRequest = "" # Append the encoded csr in chunks of 64 characters to compyly with PEM standard for ($i = 0; $i -lt $sCertRequestB64.Length; $i += 64) { $sCertRequest += $sCertRequestB64.Substring($i, [System.Math]::Min(64, $sCertRequestB64.Length - $i)) + "`n" } # Remove trailing newline $sCertRequest = $sCertRequest -replace '\n$' } else { $sCertRequest = $oCertRequest.CreateSigningRequestPem() } Write-Information "Certificate request created" # Create renewed version of certificate. # Invoke-WebRequest would be easiest option - but doesn't work due -- seemingly, the certificate is not being sent. Maybe, the server must require client certificates. #$Response = Invoke-WebRequest -Certificate $Certificate -Body $sCertRequest -ContentType "application/pkcs10" -Uri "$AppServiceUrl/.well-known/est/simplereenroll" -Method POST # So use HTTPClient instead. # HttpClientHandler works generally for mTLS. # However, it only works with certificates having the Client Authentication EKU. This is because Certificate Helper filters for this EKU: https://github.com/dotnet/runtime/blob/a0fdddab98ad95186d84d4667df4db8a4e651990/src/libraries/Common/src/System/Net/Security/CertificateHelper.cs#L12 # And HttpClientHandler sets this method as the Callback: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs#L271 # Hence, we need to use SocketsHttpHandler instead. It allows more control over the SSL options. Write-Debug "Cert Has Private Key: $($Certificate.HasPrivateKey)" if ($PSVersionTable.PSVersion.Major -lt 7) { Write-Verbose "Detected PowerShell 5: Using HttpClientHandler" Add-Type -AssemblyName System.Net.Http $handler = New-Object System.Net.Http.HttpClientHandler $handler.ClientCertificates.Add($Certificate) } else { Write-Verbose "Detected PowerShell 7: Using SocketsHttpHandler" $handler = New-Object SocketsHttpHandler # SocketsHttpHandler's ClientCertificateOptions is internal. So we need to use reflection to set it. If we leave it at 'Automatic', it would require the certificate to be in the store. try { $SocketHandlerType = $handler.GetType() $ClientCertificateOptionsProperty = $SocketHandlerType.GetProperty("ClientCertificateOptions", [System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic) $ClientCertificateOptionsProperty.SetValue($handler, [ClientCertificateOption]::Manual) } catch { Write-Warning "Couldn't set ClientCertificateOptions to Manual. This should cause an issue if the certificate is not in the MY store. This is probably due to a too recent .NET version (> 8.0)." } $handler.SslOptions.LocalCertificateSelectionCallback = [CertificateCallbacks]::SelectionCallback # This just selects the first certificate in the collection. We only provide a single certificate, so this suffices. $handler.SslOptions.ClientCertificates = [X509Certificate2Collection]::new() $null = $handler.SslOptions.ClientCertificates.Add($Certificate) } $requestmessage = [System.Net.Http.HttpRequestMessage]::new() $requestmessage.Content = [System.Net.Http.StringContent]::new( $sCertRequest, [System.Text.Encoding]::UTF8,"application/pkcs10" ) $requestmessage.Content.Headers.ContentType = "application/pkcs10" $requestmessage.Method = 'POST' $requestmessage.RequestUri = $url $client = CreateHttpClient -HttpMessageHandler $handler Write-Information "Sending renewal request to $url ..." try { $httpResponseMessage = $client.SendAsync($requestmessage).GetAwaiter().GetResult() } catch { # dump details of the exception, including InnerException $ex = $_.Exception Write-Error "$($ex.GetType()): $($ex.Message)" while ($ex.InnerException) { $ex = $ex.InnerException Write-Error "$($ex.GetType()): $($ex.Message)" } } if ($httpResponseMessage.StatusCode -ne [System.Net.HttpStatusCode]::OK) { throw "Failed to renew certificate. Status code: $($httpResponseMessage.StatusCode)" } $responseContent = $httpResponseMessage.Content.ReadAsStringAsync().Result $client.Dispose() $handler.Dispose() Write-Information "Received a successful response from $url" $binaryCertificateP7 = [System.Convert]::FromBase64String($responseContent) [X509Certificate2Collection]$collectionForNewCertificate = [X509Certificate2Collection]::new() if ($Machine) { $collectionForNewCertificate.Import($binaryCertificateP7, $null, [X509KeyStorageFlags]::MachineKeySet) $keyStorageFlag = [X509KeyStorageFlags]::MachineKeySet } else { $collectionForNewCertificate.Import($binaryCertificateP7, $null, [X509KeyStorageFlags]::UserKeySet) $keyStorageFlag = [X509KeyStorageFlags]::UserKeySet } if ($collectionForNewCertificate.Count -eq 0) { throw "No certificates were imported from $url" } else { Write-Verbose "Received $($collectionForNewCertificate.Count) certificates from $url" } $leafCertificate = $collectionForNewCertificate | Where-Object { -not (IsCertificateCaOfACertificateInTheCollection -PossibleCaCertificate $_ -Certificates $collectionForNewCertificate) } if ($leafCertificate.Count -ne 1) { throw "We received $($collectionForNewCertificate.Count) certificates from $url. Among them, we identified $($leafCertificate.Count) leaf certificates. We support only a single leaf certificate." } $newCertificate = $leafCertificate Write-Information "Merging new certificate with private key" if ($newCertificate.PublicKey.Oid.Value -eq "1.2.840.10045.2.1") { $newCertificateWithEphemeralPrivateKey = [ECDsaCertificateExtensions]::CopyWithPrivateKey($newCertificate, $privateKey) } elseif ($newCertificate.PublicKey.Oid.Value -eq "1.2.840.113549.1.1.1") { $newCertificateWithEphemeralPrivateKey = [RSACertificateExtensions]::CopyWithPrivateKey($newCertificate, $privateKey) } else { throw "Unsupported key algorithm: $($Certificate.PublicKey.Oid.Value) ($($Certificate.PublicKey.Oid.FriendlyName))" } Write-Verbose "New certificate with private key: $($newCertificateWithEphemeralPrivateKey.Subject)" $securePassword = CreateRandomSecureStringPassword $binNewCertPfx = $newCertificateWithEphemeralPrivateKey.Export([X509ContentType]::Pkcs12, $securePassword) $issuedCertificateAndPrivate = [X509Certificate2]::new($binNewCertPfx, $securePassword, $keyStorageFlag -bor [X509KeyStorageFlags]::PersistKeySet) Write-Information "Adding the new certificate to the store" if ($Machine) { $store = [X509Store]::new("My", [StoreLocation]::LocalMachine) $store.Open([OpenFlags]::ReadWrite -bor [OpenFlags]::OpenExistingOnly) } else { $store = [X509Store]::new("My", [StoreLocation]::CurrentUser) $store.Open([OpenFlags]::ReadWrite -bor [OpenFlags]::OpenExistingOnly) } $store.Add($issuedCertificateAndPrivate) $store.Close() Write-Information "Certificate added to the store $($store.Name). It is valid until $($issuedCertificateAndPrivate.NotAfter.ToString('u'))" $store.Dispose() return $issuedCertificateAndPrivate } Function CreateRandomSecureStringPassword { $securePassword = [System.Security.SecureString]::new() $random = [System.Security.Cryptography.RandomNumberGenerator]::Create() $bytes = [byte[]]::new(16) $random.GetBytes($bytes) $bytes | ForEach-Object { $securePassword.AppendChar([char]$_) } return $securePassword } Function GetSCEPmanCerts { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [string]$AppServiceUrl, [Parameter(Mandatory=$false)] [switch]$User, [Parameter(Mandatory=$false)] [switch]$Machine, [Parameter(Mandatory=$false)] [string]$FilterString, [Parameter(Mandatory=$false)] [AllowNull()] [Nullable[System.Int32]]$ValidityThresholdDays, [Parameter(Mandatory=$false)] [switch]$AllowInvalid ) if (!$User -and !$Machine -or $User -and $Machine) { throw "You must specify either -user or -machine." } $rootCaUrl = "$AppServiceUrl/.well-known/est/cacerts" # this returns a Base64-encoded PKCS#7 file $dlRootCertResponse = Invoke-WebRequest -Uri $rootCaUrl if ($dlRootCertResponse.StatusCode -eq 200) { Write-Information "Root certificate was downloaded" } else { Write-Error "Failed to download root certificate from $rootCaUrl" return $null } # Load the downloaded certificate [string]$b64P7 = [System.Text.Encoding]::ASCII.GetString($dlRootCertResponse.Content) [byte[]]$binP7 = [System.Convert]::FromBase64String($b64P7) $certCollection = [System.Security.Cryptography.X509Certificates.X509Certificate2Collection]::new() $certCollection.Import($binP7) if ($certCollection.Length -ne 1) { throw "We downloaded $($certCollection.Length) from $rootCaUrl. Currently, we support only a single Root CA without intermediate CAs." } else { $rootCert = $certCollection[0] } # Find all certificates in the 'My' stores that are issued by the downloaded certificate if ($Machine) { $certs = Get-ChildItem -Path "Cert:\LocalMachine\My" Write-Verbose "Found $($certs.Count) machine certificates" } elseif ($User) { $certs = Get-ChildItem -Path "Cert:\CurrentUser\My" Write-Verbose "Found $($certs.Count) user certificates" } $certs = $certs | Where-Object { $_.Issuer -eq $rootCert.Subject } Write-Verbose "Found $($certs.Count) certificates issued by the root certificate $($rootCert.Subject)" $certs = $certs | Where-Object { $_.HasPrivateKey } # We can only renew certificates with private keys Write-Verbose "Found $($certs.Count) certificates with private keys" if ($FilterString) { $certs = $certs | Where-Object { $_.Subject -Match $FilterString } } Write-Verbose "Found $($certs.Count) certificates with filter string '$FilterString'" # Assume certificates with the same subject are the same. For each subject, we continue only with one having the longest remaining validity $certGroups = $certs | Group-Object -Property Subject $certs = $certGroups | ForEach-Object { $_.Group | Sort-Object -Property NotAfter -Descending | Select-Object -First 1 } Write-Verbose "Found $($certs.Count) unique subjects" if (!($ValidityThresholdDays)) { $ValidityThresholdDays = 30 # Default is 30 days } $ValidityThreshold = New-TimeSpan -Days $ValidityThresholdDays $certs = $certs | Where-Object { $ValidityThreshold -ge $_.NotAfter.Subtract([DateTime]::UtcNow) } Write-Verbose "Found $($certs.Count) certificates that are within $ValidityThresholdDays days of expiry" if (!$AllowInvalid) { $certs = $certs | Where-Object { $_.Verify() } Write-Verbose "Found $($certs.Count) certificates that are valid (chaining to a trusted Root CA and neither revoked nor expired)" } Write-Information "There are $($certs.Count) certificates applicable for renewal" $certs | Out-String | Write-Verbose return $certs } # SIG # Begin signature block # MIIsiwYJKoZIhvcNAQcCoIIsfDCCLHgCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBgL0bkTi80f0Ik # zhDyule6lMZsjplkLZpoSMkm6dvQyqCCFA4wggVyMIIDWqADAgECAhB2U/6sdUZI # k/Xl10pIOk74MA0GCSqGSIb3DQEBDAUAMFMxCzAJBgNVBAYTAkJFMRkwFwYDVQQK # ExBHbG9iYWxTaWduIG52LXNhMSkwJwYDVQQDEyBHbG9iYWxTaWduIENvZGUgU2ln # bmluZyBSb290IFI0NTAeFw0yMDAzMTgwMDAwMDBaFw00NTAzMTgwMDAwMDBaMFMx # CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMSkwJwYDVQQD # EyBHbG9iYWxTaWduIENvZGUgU2lnbmluZyBSb290IFI0NTCCAiIwDQYJKoZIhvcN # AQEBBQADggIPADCCAgoCggIBALYtxTDdeuirkD0DcrA6S5kWYbLl/6VnHTcc5X7s # k4OqhPWjQ5uYRYq4Y1ddmwCIBCXp+GiSS4LYS8lKA/Oof2qPimEnvaFE0P31PyLC # o0+RjbMFsiiCkV37WYgFC5cGwpj4LKczJO5QOkHM8KCwex1N0qhYOJbp3/kbkbuL # ECzSx0Mdogl0oYCve+YzCgxZa4689Ktal3t/rlX7hPCA/oRM1+K6vcR1oW+9YRB0 # RLKYB+J0q/9o3GwmPukf5eAEh60w0wyNA3xVuBZwXCR4ICXrZ2eIq7pONJhrcBHe # OMrUvqHAnOHfHgIB2DvhZ0OEts/8dLcvhKO/ugk3PWdssUVcGWGrQYP1rB3rdw1G # R3POv72Vle2dK4gQ/vpY6KdX4bPPqFrpByWbEsSegHI9k9yMlN87ROYmgPzSwwPw # jAzSRdYu54+YnuYE7kJuZ35CFnFi5wT5YMZkobacgSFOK8ZtaJSGxpl0c2cxepHy # 1Ix5bnymu35Gb03FhRIrz5oiRAiohTfOB2FXBhcSJMDEMXOhmDVXR34QOkXZLaRR # kJipoAc3xGUaqhxrFnf3p5fsPxkwmW8x++pAsufSxPrJ0PBQdnRZ+o1tFzK++Ol+ # A/Tnh3Wa1EqRLIUDEwIrQoDyiWo2z8hMoM6e+MuNrRan097VmxinxpI68YJj8S4O # JGTfAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0G # A1UdDgQWBBQfAL9GgAr8eDm3pbRD2VZQu86WOzANBgkqhkiG9w0BAQwFAAOCAgEA # Xiu6dJc0RF92SChAhJPuAW7pobPWgCXme+S8CZE9D/x2rdfUMCC7j2DQkdYc8pzv # eBorlDICwSSWUlIC0PPR/PKbOW6Z4R+OQ0F9mh5byV2ahPwm5ofzdHImraQb2T07 # alKgPAkeLx57szO0Rcf3rLGvk2Ctdq64shV464Nq6//bRqsk5e4C+pAfWcAvXda3 # XaRcELdyU/hBTsz6eBolSsr+hWJDYcO0N6qB0vTWOg+9jVl+MEfeK2vnIVAzX9Rn # m9S4Z588J5kD/4VDjnMSyiDN6GHVsWbcF9Y5bQ/bzyM3oYKJThxrP9agzaoHnT5C # JqrXDO76R78aUn7RdYHTyYpiF21PiKAhoCY+r23ZYjAf6Zgorm6N1Y5McmaTgI0q # 41XHYGeQQlZcIlEPs9xOOe5N3dkdeBBUO27Ql28DtR6yI3PGErKaZND8lYUkqP/f # obDckUCu3wkzq7ndkrfxzJF0O2nrZ5cbkL/nx6BvcbtXv7ePWu16QGoWzYCELS/h # AtQklEOzFfwMKxv9cW/8y7x1Fzpeg9LJsy8b1ZyNf1T+fn7kVqOHp53hWVKUQY9t # W76GlZr/GnbdQNJRSnC0HzNjI3c/7CceWeQIh+00gkoPP/6gHcH1Z3NFhnj0qinp # J4fGGdvGExTDOUmHTaCX4GUT9Z13Vunas1jHOvLAzYIwggboMIIE0KADAgECAhB3 # vQ4Ft1kLth1HYVMeP3XtMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNVBAYTAkJFMRkw # FwYDVQQKExBHbG9iYWxTaWduIG52LXNhMSkwJwYDVQQDEyBHbG9iYWxTaWduIENv # ZGUgU2lnbmluZyBSb290IFI0NTAeFw0yMDA3MjgwMDAwMDBaFw0zMDA3MjgwMDAw # MDBaMFwxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTIw # MAYDVQQDEylHbG9iYWxTaWduIEdDQyBSNDUgRVYgQ29kZVNpZ25pbmcgQ0EgMjAy # MDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMsg75ceuQEyQ6BbqYoj # /SBerjgSi8os1P9B2BpV1BlTt/2jF+d6OVzA984Ro/ml7QH6tbqT76+T3PjisxlM # g7BKRFAEeIQQaqTWlpCOgfh8qy+1o1cz0lh7lA5tD6WRJiqzg09ysYp7ZJLQ8LRV # X5YLEeWatSyyEc8lG31RK5gfSaNf+BOeNbgDAtqkEy+FSu/EL3AOwdTMMxLsvUCV # 0xHK5s2zBZzIU+tS13hMUQGSgt4T8weOdLqEgJ/SpBUO6K/r94n233Hw0b6nskEz # IHXMsdXtHQcZxOsmd/KrbReTSam35sOQnMa47MzJe5pexcUkk2NvfhCLYc+YVaMk # oog28vmfvpMusgafJsAMAVYS4bKKnw4e3JiLLs/a4ok0ph8moKiueG3soYgVPMLq # 7rfYrWGlr3A2onmO3A1zwPHkLKuU7FgGOTZI1jta6CLOdA6vLPEV2tG0leis1Ult # 5a/dm2tjIF2OfjuyQ9hiOpTlzbSYszcZJBJyc6sEsAnchebUIgTvQCodLm3HadNu # twFsDeCXpxbmJouI9wNEhl9iZ0y1pzeoVdwDNoxuz202JvEOj7A9ccDhMqeC5LYy # AjIwfLWTyCH9PIjmaWP47nXJi8Kr77o6/elev7YR8b7wPcoyPm593g9+m5XEEofn # GrhO7izB36Fl6CSDySrC/blTAgMBAAGjggGtMIIBqTAOBgNVHQ8BAf8EBAMCAYYw # EwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4E # FgQUJZ3Q/FkJhmPF7POxEztXHAOSNhEwHwYDVR0jBBgwFoAUHwC/RoAK/Hg5t6W0 # Q9lWULvOljswgZMGCCsGAQUFBwEBBIGGMIGDMDkGCCsGAQUFBzABhi1odHRwOi8v # b2NzcC5nbG9iYWxzaWduLmNvbS9jb2Rlc2lnbmluZ3Jvb3RyNDUwRgYIKwYBBQUH # MAKGOmh0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5jb20vY2FjZXJ0L2NvZGVzaWdu # aW5ncm9vdHI0NS5jcnQwQQYDVR0fBDowODA2oDSgMoYwaHR0cDovL2NybC5nbG9i # YWxzaWduLmNvbS9jb2Rlc2lnbmluZ3Jvb3RyNDUuY3JsMFUGA1UdIAROMEwwQQYJ # KwYBBAGgMgECMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8vd3d3Lmdsb2JhbHNpZ24u # Y29tL3JlcG9zaXRvcnkvMAcGBWeBDAEDMA0GCSqGSIb3DQEBCwUAA4ICAQAldaAJ # yTm6t6E5iS8Yn6vW6x1L6JR8DQdomxyd73G2F2prAk+zP4ZFh8xlm0zjWAYCImbV # YQLFY4/UovG2XiULd5bpzXFAM4gp7O7zom28TbU+BkvJczPKCBQtPUzosLp1pnQt # pFg6bBNJ+KUVChSWhbFqaDQlQq+WVvQQ+iR98StywRbha+vmqZjHPlr00Bid/XSX # hndGKj0jfShziq7vKxuav2xTpxSePIdxwF6OyPvTKpIz6ldNXgdeysEYrIEtGiH6 # bs+XYXvfcXo6ymP31TBENzL+u0OF3Lr8psozGSt3bdvLBfB+X3Uuora/Nao2Y8nO # ZNm9/Lws80lWAMgSK8YnuzevV+/Ezx4pxPTiLc4qYc9X7fUKQOL1GNYe6ZAvytOH # X5OKSBoRHeU3hZ8uZmKaXoFOlaxVV0PcU4slfjxhD4oLuvU/pteO9wRWXiG7n9dq # cYC/lt5yA9jYIivzJxZPOOhRQAyuku++PX33gMZMNleElaeEFUgwDlInCI2Oor0i # xxnJpsoOqHo222q6YV8RJJWk4o5o7hmpSZle0LQ0vdb5QMcQlzFSOTUpEYck08T7 # qWPLd0jV+mL8JOAEek7Q5G7ezp44UCb0IXFl1wkl1MkHAHq4x/N36MXU4lXQ0x72 # f1LiSY25EXIMiEQmM2YBRN/kMw4h3mKJSAfa9TCCB6gwggWQoAMCAQICDF3VjaKN # us83AvC1UTANBgkqhkiG9w0BAQsFADBcMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQ # R2xvYmFsU2lnbiBudi1zYTEyMDAGA1UEAxMpR2xvYmFsU2lnbiBHQ0MgUjQ1IEVW # IENvZGVTaWduaW5nIENBIDIwMjAwHhcNMjUxMTI3MTcwNDI2WhcNMjcxMTI4MTcw # NDI2WjCCAQwxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRIwEAYDVQQF # EwlIUkIgMTIzODExEzARBgsrBgEEAYI3PAIBAxMCREUxFzAVBgsrBgEEAYI3PAIB # AhMGSGVzc2VuMSIwIAYLKwYBBAGCNzwCAQETEU9mZmVuYmFjaCBhbSBNYWluMQsw # CQYDVQQGEwJERTEPMA0GA1UECBMGSGVzc2VuMRowGAYDVQQHExFPZmZlbmJhY2gg # YW0gTWFpbjEZMBcGA1UECQwQS2Fpc2Vyc3RyYcOfZSAzOTEXMBUGA1UEChMOZ2x1 # ZWNra2FuamEgQUcxFzAVBgNVBAMTDmdsdWVja2thbmphIEFHMIICIjANBgkqhkiG # 9w0BAQEFAAOCAg8AMIICCgKCAgEAkQoXi0dUFVttodx+Ydj1O6EZZqgDdlSGDA/6 # x1UCkMrWNVEW+LdbUGU8KW7fUcKPCAcDJNrXfXxZeBht2G4pPvhaMz/kBdSK6bI1 # sqo1WSN//beapdUefQpq/wgnUneq13tEJQAke6EWdLyidObcogBSp9wCXBbMWsTO # utgCONjyu8AilmzRY+94lO7VwUA2LGGPX8FRAEt5AMzifsEo2lIEKiDou2H8HUUC # PibiChiuT3oGIDYYnCA/RzS44E0cAuAzlD3NQNCeIDzfoFiUD8mAC1gYU6i8yIej # jUGl8+kpbpBYjgzwbsiCBn0rDhrlpJ3MHkZCrp82kzWK0l7c3ukNvdlGcU4tKdXk # AHgpJecdYUDvz9iaYFvYEivF+Jg+Tc8ZnzsP5/q3KKw4g0QiJ+MXgvwJx8OSvAKW # tkwkLxgE9oxufs3Y8xsmwyWqxWDBcyzzvs6yISnUaeTtGmyB8BsEbahDFrxHhV6U # nwxNpJ+iM+j08J1tNIW0AXjY6ojGOIC8IIL+EiK34MXJ6Jxy22mntMnc6ztK6c7H # IKiRHIPX4jXtg7IYRS/k5muuIt/xKzN7qtF9xJbaZi8jRE6fgWDwszLJUMHSLthh # yKTsUEvuqZ79WnSHErg26EPQYirAY/IFt7Z7+3SDW2WI8uG2qY6hkpE0hm+/F3uS # M+s98jUCAwEAAaOCAbYwggGyMA4GA1UdDwEB/wQEAwIHgDCBnwYIKwYBBQUHAQEE # gZIwgY8wTAYIKwYBBQUHMAKGQGh0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5jb20v # Y2FjZXJ0L2dzZ2NjcjQ1ZXZjb2Rlc2lnbmNhMjAyMC5jcnQwPwYIKwYBBQUHMAGG # M2h0dHA6Ly9vY3NwLmdsb2JhbHNpZ24uY29tL2dzZ2NjcjQ1ZXZjb2Rlc2lnbmNh # MjAyMDBVBgNVHSAETjBMMEEGCSsGAQQBoDIBAjA0MDIGCCsGAQUFBwIBFiZodHRw # czovL3d3dy5nbG9iYWxzaWduLmNvbS9yZXBvc2l0b3J5LzAHBgVngQwBAzAJBgNV # HRMEAjAAMEcGA1UdHwRAMD4wPKA6oDiGNmh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5j # b20vZ3NnY2NyNDVldmNvZGVzaWduY2EyMDIwLmNybDATBgNVHSUEDDAKBggrBgEF # BQcDAzAfBgNVHSMEGDAWgBQlndD8WQmGY8Xs87ETO1ccA5I2ETAdBgNVHQ4EFgQU # q/cn5ijjtp0mG1yoiF02hg4dx4IwDQYJKoZIhvcNAQELBQADggIBAJ1TZv/rvy2w # jANcL/kb6rTk+/6L7l49UghLghUKFVfrdEEc+21iexA7zlkvhM0TrhdiFU7TjDky # InPctzsDlqwUhawEx4PT8ZkZkZzm25YWaqtZH44st/Fz59KiG+85NUdRd+0cL3Y8 # NR66z3xfI6K3W/nrIcE6RHm/opOM+L02Hd2MBligLnoFYcTvR3NPCA21A6+IOaYM # n5YZzNKFXWry8ZHpWjnE4u9mxHYpS1zu2aIkwL8mfYM5moYoh0PAcp9XA5Sm4KrV # LeIzZ3HIy4EzLCbFBP+OGFpkqq8pTtmYItG+g1rYEg5a8egrY83zJMHazaTFBgRI # MNXCgeMZhC8O6NsAtbj3FSbiYKg1hNwZzHYL+uL3jcPZjuUoOpmvXu67xWs4ZfdT # Mluy5E7FyWwtnOjr/04EXWyKATYMDIkd47Wqam/ZB7umF5T5YPnmTlv18ArEXuVQ # EEpS/cN90DtRz2OGruu+V9bg3fk6NKDJLve8detDOTTBN0C/bFGxI5YLHmwVAdaq # pz3t14ShRjVcxP7aN0bEL3YOuQvjnjQGe29H6n/MPf8UG4WYMd+a8qIP4HROLJq0 # YJylzYBglqoQeQC/OG+PtWTvL9oByPVYNc+llAuap/xmWSLZgAqPbi+PAfow69Lg # bppHUCnJhNkXD/mJ4qB0KvPG+bzL19dEMYIX0zCCF88CAQEwbDBcMQswCQYDVQQG # EwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEyMDAGA1UEAxMpR2xvYmFs # U2lnbiBHQ0MgUjQ1IEVWIENvZGVTaWduaW5nIENBIDIwMjACDF3VjaKNus83AvC1 # UTANBglghkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkG # CSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEE # AYI3AgEVMC8GCSqGSIb3DQEJBDEiBCAZibiCQ8ZELt0CdanxCX4ZUjWCZEFlbYnS # wqwftYeoEDANBgkqhkiG9w0BAQEFAASCAgAa3GOTNAEzDUuaVh3Wsh8bLSGsy1RX # sPt3gm7pAOPT3oYYslOTYMX1X9jRHpv9nLDQFZnzqnFkvnt8j7zySNpk28qj9MhP # kYizAH4Vwzzu3Uq+EYirvKOuuotWYNUNroKBdzIV1EVK18Zmsp7NfeFGYDc+cwDF # J+coUDvAgRJ9bnCHVo2xtf2S97wLAnoho/4D3yIOBI9MDE5u0NJ9gEMykRF9ZXgI # 4BsV+pG1vlt0GG1FmqD1HULd00giF/bwChN6CwSZhXP0nmdvkUUGuFTOSMfewawt # GOQgAYcDGcwhz4JGVbBHKlDtJscknCDcvDWS6bhuICcV6dLnCApBder2KVk3RIkd # PvBjpJE+4ZLocgf0q3S2sLrW0cBBBB4eT1MNn/j4edGvwPMSwV3oNoeUSQc0TuB8 # Lfnjr94Sa909Nf29PpXGu3jjs1YzjY2rs+NTI98JItvYwSIuqtL3I3zYXoNkhTQu # 61EEhQ21VglVgkKYooclvHZ59lN1nMHmOY1IBK1vQlhf0i5PWkWokF6CkVMdwOXm # zZJGkO++e5QgFcr7bi7wrtYZTuX4bN/dj7MMDfJaIKJeRidOV8o6cGcSRJWIA6Sj # Sm+r97NlZmhz3+cWk4jwp6NBH7p/3E/+4qiNggA1qnKjkrzCRud02M0IST1oK1FC # O2c9Yp+qwb1Xt6GCFLEwghStBgorBgEEAYI3AwMBMYIUnTCCFJkGCSqGSIb3DQEH # AqCCFIowghSGAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFpBgsqhkiG9w0BCRABBKCC # AVgEggFUMIIBUAIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUABCC83Ipl # o9T6ytUm6VHPfeqVU50iDxGtbhkhDTCie0SjzQIGacZiIdBvGBIyMDI2MDMzMTEw # MTgwOC40N1owBIACAfSggemkgeYwgeMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX # YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg # Q29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlv # bnMgTGltaXRlZDEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjQ5MUEtMDVFMC1E # OTQ3MTUwMwYDVQQDEyxNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lIFN0YW1waW5n # IEF1dGhvcml0eaCCDykwggeCMIIFaqADAgECAhMzAAAABeXPD/9mLsmHAAAAAAAF # MA0GCSqGSIb3DQEBDAUAMHcxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3Nv # ZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jvc29mdCBJZGVudGl0eSBWZXJp # ZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAyMDAeFw0yMDEx # MTkyMDMyMzFaFw0zNTExMTkyMDQyMzFaMGExCzAJBgNVBAYTAlVTMR4wHAYDVQQK # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJs # aWMgUlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwMIICIjANBgkqhkiG9w0BAQEFAAOC # Ag8AMIICCgKCAgEAnnznUmP94MWfBX1jtQYioxwe1+eXM9ETBb1lRkd3kcFdcG9/ # sqtDlwxKoVIcaqDb+omFio5DHC4RBcbyQHjXCwMk/l3TOYtgoBjxnG/eViS4sOx8 # y4gSq8Zg49REAf5huXhIkQRKe3Qxs8Sgp02KHAznEa/Ssah8nWo5hJM1xznkRsFP # u6rfDHeZeG1Wa1wISvlkpOQooTULFm809Z0ZYlQ8Lp7i5F9YciFlyAKwn6yjN/kR # 4fkquUWfGmMopNq/B8U/pdoZkZZQbxNlqJOiBGgCWpx69uKqKhTPVi3gVErnc/qi # +dR8A2MiAz0kN0nh7SqINGbmw5OIRC0EsZ31WF3Uxp3GgZwetEKxLms73KG/Z+Mk # euaVDQQheangOEMGJ4pQZH55ngI0Tdy1bi69INBV5Kn2HVJo9XxRYR/JPGAaM6xG # l57Ei95HUw9NV/uC3yFjrhc087qLJQawSC3xzY/EXzsT4I7sDbxOmM2rl4uKK6eE # purRduOQ2hTkmG1hSuWYBunFGNv21Kt4N20AKmbeuSnGnsBCd2cjRKG79+TX+sTe # hawOoxfeOO/jR7wo3liwkGdzPJYHgnJ54UxbckF914AqHOiEV7xTnD1a69w/UTxw # jEugpIPMIIE67SFZ2PMo27xjlLAHWW3l1CEAFjLNHd3EQ79PUr8FUXetXr0CAwEA # AaOCAhswggIXMA4GA1UdDwEB/wQEAwIBhjAQBgkrBgEEAYI3FQEEAwIBADAdBgNV # HQ4EFgQUa2koOjUvSGNAz3vYr0npPtk92yEwVAYDVR0gBE0wSzBJBgRVHSAAMEEw # PwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9j # cy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAKBggrBgEFBQcDCDAZBgkrBgEEAYI3 # FAIEDB4KAFMAdQBiAEMAQTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFMh+ # 0mqFKhvKGZgEByfPUBBPaKiiMIGEBgNVHR8EfTB7MHmgd6B1hnNodHRwOi8vd3d3 # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBJZGVudGl0eSUy # MFZlcmlmaWNhdGlvbiUyMFJvb3QlMjBDZXJ0aWZpY2F0ZSUyMEF1dGhvcml0eSUy # MDIwMjAuY3JsMIGUBggrBgEFBQcBAQSBhzCBhDCBgQYIKwYBBQUHMAKGdWh0dHA6 # Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwSWRl # bnRpdHklMjBWZXJpZmljYXRpb24lMjBSb290JTIwQ2VydGlmaWNhdGUlMjBBdXRo # b3JpdHklMjAyMDIwLmNydDANBgkqhkiG9w0BAQwFAAOCAgEAX4h2x35ttVoVdedM # eGj6TuHYRJklFaW4sTQ5r+k77iB79cSLNe+GzRjv4pVjJviceW6AF6ycWoEYR0LY # haa0ozJLU5Yi+LCmcrdovkl53DNt4EXs87KDogYb9eGEndSpZ5ZM74LNvVzY0/nP # ISHz0Xva71QjD4h+8z2XMOZzY7YQ0Psw+etyNZ1CesufU211rLslLKsO8F2aBs2c # Io1k+aHOhrw9xw6JCWONNboZ497mwYW5EfN0W3zL5s3ad4Xtm7yFM7Ujrhc0aqy3 # xL7D5FR2J7x9cLWMq7eb0oYioXhqV2tgFqbKHeDick+P8tHYIFovIP7YG4ZkJWag # 1H91KlELGWi3SLv10o4KGag42pswjybTi4toQcC/irAodDW8HNtX+cbz0sMptFJK # +KObAnDFHEsukxD+7jFfEV9Hh/+CSxKRsmnuiovCWIOb+H7DRon9TlxydiFhvu88 # o0w35JkNbJxTk4MhF/KgaXn0GxdH8elEa2Imq45gaa8D+mTm8LWVydt4ytxYP/bq # jN49D9NZ81coE6aQWm88TwIf4R4YZbOpMKN0CyejaPNN41LGXHeCUMYmBx3PkP8A # DHD1J2Cr/6tjuOOCztfp+o9Nc+ZoIAkpUcA/X2gSMkgHAPUvIdtoSAHEUKiBhI6J # QivRepyvWcl+JYbYbBh7pmgAXVswggefMIIFh6ADAgECAhMzAAAAWvYNZ4yF7d0I # AAAAAABaMA0GCSqGSIb3DQEBDAUAMGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMg # UlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwMB4XDTI2MDEwODE4NTkwM1oXDTI3MDEw # NzE4NTkwM1owgeMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw # DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x # LTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEn # MCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjQ5MUEtMDVFMC1EOTQ3MTUwMwYDVQQD # EyxNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lIFN0YW1waW5nIEF1dGhvcml0eTCC # AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAO/0O0eWjgUb9rnHcQLRdfWP # N4H+91a3YnlaP46E1m4uD+JKx6csWMStX79fxLJUAqHJqQWE19UlNMhS9jEB32dA # J4yuWsHyUuM+dphjDz4E5jl4gYGZEmaOrKvNt+KqlFayyg/oTg3BlLRu4aBq8668 # A5qlHcfsuh6DdSqFID1ixJFZzHrZFG1iGBG7U1Bn2ONLDo7jbwX5rMcPduTAUw/c # 7M3WhSxQBuZpQiz8RQGKIqCKfIxgQkKdzpCpU0SWQOE/DgTXbz3c15KMRCdkGlL2 # zb+lnuSV4sseQm3qflZiZckLyn2xJI8ZXDkq+Ig+b/rsPPIfI8di228WvK1j67JX # pyeVCaSUO9ErzlLnTrnjQkeXVQIp73xuVBVrmvoTf/v4a7MnrmuKSyIXc5vJUHEG # B345+O8omFt1w8b+Xg9D9PKIRqDPEv7HRk0C+Yvxu8FvHJvSocSIZK+v/FmKFOip # YnpP76yAmJNnyheucShOgk8QiU53USn/+AyMb7xW905gZnyNqb29HeVdQ175pDHJ # GEz8Cx5wiHeVliGz5hABucFDylR9z3LSTmB6+3ZuIxeG9BZS46P6ANPkuVuD5m8w # gc7GLLzg73CsDF09ukt8Uf8dTcMBX3ro+7/k9M6Xt8WPG7IL9v/4DvyMY03tkb9Y # 9Ri6HWavXRPYRCUePspPAgMBAAGjggHLMIIBxzAdBgNVHQ4EFgQUjmOyQ6twMcP1 # ZbRytJxI4fnXmcIwHwYDVR0jBBgwFoAUa2koOjUvSGNAz3vYr0npPtk92yEwbAYD # VR0fBGUwYzBhoF+gXYZbaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9j # cmwvTWljcm9zb2Z0JTIwUHVibGljJTIwUlNBJTIwVGltZXN0YW1waW5nJTIwQ0El # MjAyMDIwLmNybDB5BggrBgEFBQcBAQRtMGswaQYIKwYBBQUHMAKGXWh0dHA6Ly93 # d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwUHVibGlj # JTIwUlNBJTIwVGltZXN0YW1waW5nJTIwQ0ElMjAyMDIwLmNydDAMBgNVHRMBAf8E # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMA4GA1UdDwEB/wQEAwIHgDBmBgNV # HSAEXzBdMFEGDCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3 # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wCAYGZ4EM # AQQCMA0GCSqGSIb3DQEBDAUAA4ICAQCAlM8r+t3hIb2h1lDTAx+iYkQlxFuU7QON # eyIFIBZ29xvGl8pehKxErDzIniOpIX/eluUAwQKoaI0zwuKAdR0mrSHXCniMoLNk # o5W+5r7sXNamKX7QMV3BfGOX3gi9qVfxyUe7AHXbqQ8KBQHNYCnNFtQQHgARrlYh # tyAKol5ctM0CAc/y3oY7bTMsVJvnA5u7DVWPeXoST2KEMDeLBvJYq0IJZ6yMpDOW # LZ4UP82bksyShIB/XdawirIGLdseudryRxVMk313mAcjGRb59+Ittt6otVvYQWqH # +PGrTUzEcez8aQuO3umoNZjKuFoX5VsPP/gSZse+orhG3zfZk9IDyE3DfUFrhvkv # 6H0tijK1D0uIGhwMBWSm9ktQ6oeU+aurZFx3MI+LODnHsbRFZAy11uMvwKq+ZNC1 # Se4tIM1u9piWAhnTPoh6mULKikHOVhHaO953tkzDCtjsse5GUKOx9yg9nqHKWMgn # ODp62/uPPzC/yDEISrXCcU7UB7tATr3zWNEdtM4d009iXWI6dV/SdcIIX44rpoLy # CLw+nXjxp+fY/dygLO7UdSQaVaUFVj3K2nVyuujPspt5Lunc5FvuYPqmi/z8kASm # mwbiF+W0P0UTWFaC84MWfU2h6MDg5s0oxmdNFK76jXr3wZfdSoV7FCKfq5GdeGoy # 5UwDQwMC0DGCA9QwggPQAgEBMHgwYTELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1p # Y3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFB1YmxpYyBS # U0EgVGltZXN0YW1waW5nIENBIDIwMjACEzMAAABa9g1njIXt3QgAAAAAAFowDQYJ # YIZIAWUDBAIBBQCgggEtMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkq # hkiG9w0BCQQxIgQg6FSuGQZQzWBUQyQqEqT2H100bH3yteYx9x3mMvegOE4wgd0G # CyqGSIb3DQEJEAIvMYHNMIHKMIHHMIGgBCBiuWRAi+p96PRsBt3TwW3jNozgPQS+ # Qco1CVm/NaU0QzB8MGWkYzBhMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9z # b2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUHVibGljIFJTQSBU # aW1lc3RhbXBpbmcgQ0EgMjAyMAITMwAAAFr2DWeMhe3dCAAAAAAAWjAiBCCWofRG # Yr2WWWM1UtiBEYSsy2zgHeiPXmlQTsaALjwHLDANBgkqhkiG9w0BAQsFAASCAgC4 # aujR8VE41A70xf1HB5dN2P3g9RlLDHO7tstirREkp8OoVlO24c5VT66xzOl91Gnv # 8/afWFZpFSELunACYMGgHdq+Lg53HJ/GZbyxJKs5unhnra5W1PMoB8AQaaq2oIZ9 # xJpJYiO0fSiud8meNUswYo0IZUZFVFLd71RahWEDDx4FigEfXHrtV8tFaLfX6rI5 # c1Zi1NvML90rPYfCDETTmUCPYb2LKykjhSq7BJnwa2jyKtCTnp8zNS7JQlm1uzZw # x97rA/y2qQ4gvXiBrV0su9WVio+dqt4g0BqLFMUZBOfEPR6l6jEMQ7GIFx4WQrsU # Jm/LCvqdb8Xei+E42Rvue5Qa8v13rkprT6MTAz90pLy/qy50f1pD1dP8+92HQs3G # Cj/bVcdddIVadZzmg2Po76Qao8qGUupHkplpYLhZodiGqWl+PSp6TyxrXTwpY9TH # cHMsfTKzSuWFKLexAWmy06Dw5zg1T922K4Aieh/T0Kyz70aKl91C4dvCp6ITdlFM # /m49CYZb2hPrDmFiAzXcfsNtAHoKIKUFFnv5L1akG4U3BUm06Bfut7kMsd2FI3iT # GB9pqI9lnSSMHBSBNkDojVPw2Rt+ut2Ij+Pp0FF7U1GWEpieLnReH3axGrGPVpTs # 1RHxf94hlZc1SYqOvpCKS5GKxhd+jw8us0OosxX9mA== # SIG # End signature block |