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 # MIIviAYJKoZIhvcNAQcCoIIveTCCL3UCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBgL0bkTi80f0Ik # zhDyule6lMZsjplkLZpoSMkm6dvQyqCCFDUwggWQMIIDeKADAgECAhAFmxtXno4h # MuI5B72nd3VcMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV # BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0xMzA4MDExMjAwMDBaFw0z # ODAxMTUxMjAwMDBaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ # bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 # IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB # AL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/z # G6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZ # anMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7s # Wxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL # 2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfb # BHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3 # JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3c # AORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqx # YxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0 # viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aL # T8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjQjBAMA8GA1Ud # EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTs1+OC0nFdZEzf # Lmc/57qYrhwPTzANBgkqhkiG9w0BAQwFAAOCAgEAu2HZfalsvhfEkRvDoaIAjeNk # aA9Wz3eucPn9mkqZucl4XAwMX+TmFClWCzZJXURj4K2clhhmGyMNPXnpbWvWVPjS # PMFDQK4dUPVS/JA7u5iZaWvHwaeoaKQn3J35J64whbn2Z006Po9ZOSJTROvIXQPK # 7VB6fWIhCoDIc2bRoAVgX+iltKevqPdtNZx8WorWojiZ83iL9E3SIAveBO6Mm0eB # cg3AFDLvMFkuruBx8lbkapdvklBtlo1oepqyNhR6BvIkuQkRUNcIsbiJeoQjYUIp # 5aPNoiBB19GcZNnqJqGLFNdMGbJQQXE9P01wI4YMStyB0swylIQNCAmXHE/A7msg # dDDS4Dk0EIUhFQEI6FUy3nFJ2SgXUE3mvk3RdazQyvtBuEOlqtPDBURPLDab4vri # RbgjU2wGb2dVf0a1TD9uKFp5JtKkqGKX0h7i7UqLvBv9R0oN32dmfrJbQdA75PQ7 # 9ARj6e/CVABRoIoqyc54zNXqhwQYs86vSYiv85KZtrPmYQ/ShQDnUBrkG5WdGaG5 # nLGbsQAe79APT0JsyQq87kP6OnGlyE0mpTX9iV28hWIdMtKgK1TtmlfB2/oQzxm3 # i0objwG2J5VT6LaJbVu8aNQj6ItRolb58KaAoNYes7wPD1N1KarqE3fk3oyBIa0H # EEcRrYc9B9F1vM/zZn4wggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0G # CSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ # bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 # IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTla # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C # 0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce # 2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0da # E6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6T # SXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoA # FdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7Oh # D26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM # 1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z # 8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05 # huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNY # mtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP # /2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0T # AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYD # VR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMG # A1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYY # aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2Fj # ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNV # HR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU # cnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAN # BgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95Ry # sQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HL # IvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5Btf # Q/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnh # OE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIh # dXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV # 9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/j # wVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYH # Ki8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmC # XBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l # /aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZW # eE4wggfpMIIF0aADAgECAhAE0w/ewLw2E3KQ6RwmFyT5MA0GCSqGSIb3DQEBCwUA # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwHhcNMjMxMTE2MDAwMDAwWhcNMjYxMTE1MjM1OTU5WjCB8TET # MBEGCysGAQQBgjc8AgEDEwJERTEXMBUGCysGAQQBgjc8AgECEwZIZXNzZW4xIjAg # BgsrBgEEAYI3PAIBARMRT2ZmZW5iYWNoIGFtIE1haW4xHTAbBgNVBA8MFFByaXZh # dGUgT3JnYW5pemF0aW9uMRIwEAYDVQQFEwlIUkIgMTIzODExCzAJBgNVBAYTAkRF # MQ8wDQYDVQQIEwZIZXNzZW4xGjAYBgNVBAcTEU9mZmVuYmFjaCBhbSBNYWluMRcw # FQYDVQQKEw5nbHVlY2trYW5qYSBBRzEXMBUGA1UEAxMOZ2x1ZWNra2FuamEgQUcw # ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDOkzyWiAT0dzoCrdo4dTaE # UjIJKcht/Gvb3OOJ/WpNQYJius0XbgOcyBu+7+yGANG0SKDbGxuy8gl6FDMkMKXS # g4ukpw2GLeMNATJ+MBd5FL3MwTSyZS0SljlAbIdyo7ydBeCNrCqKsJoBLARTdxSu # fsxRtgsEOM3AqkT51Z+oSb3fOpAvG3E6fj6ViQP2C37m3t9LvCzNJO6TQ94ylKFg # WxOLmHlBnvBEK6wLsL3FRWl0avXTNvheH7XmY7vI9Othb469+V+FJVBbmD7SE0f5 # miAND4wpNGObz76r2TsHFcgTHah8EGKTJeo0+m3AM158ILT2cN35v8z7X4RbJ7L5 # k4eMFNoWKwPc72UPZKdlo0OQuutL5ehtFhopnB7WUUFCNV4+KQGYo9cKEeufGqV0 # xrIcdH409ejAuMleNZ4CLyU5LE5qVkYxLgdjDdCdxbk2ADSTOwQtpLJExnhf/jkc # 9sRTys9i6NtpE+hb6xbAJ7p4vQt3iLMDQHy6l98HNJNlmY3Phvk0ViUIzRC7qgv7 # Fe+5bE6FkFc/J4rrx6AUTJek/WvkhbvJp39IvspHUxTYC34l9y8Dcnxk3XU2TASn # JR6yKElD+OetRKE0rS9VcuL7kJrTY9det5Kv1hzoZj3zPqd5X+cqqV5hzE3aI3TP # 1v0zICGYf5ayeA1zg9aCkQIDAQABo4ICAjCCAf4wHwYDVR0jBBgwFoAUaDfg67Y7 # +F8Rhvv+YXsIiGX0TkIwHQYDVR0OBBYEFOTb7LJoGHhU5+5fcQSNJKUzQX0kMD0G # A1UdIAQ2MDQwMgYFZ4EMAQMwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdp # Y2VydC5jb20vQ1BTMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD # AzCBtQYDVR0fBIGtMIGqMFOgUaBPhk1odHRwOi8vY3JsMy5kaWdpY2VydC5jb20v # RGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0Ex # LmNybDBToFGgT4ZNaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1 # c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcmwwgZQGCCsG # AQUFBwEBBIGHMIGEMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j # b20wXAYIKwYBBQUHMAKGUGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp # Q2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3J0 # MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggIBAMkcpd3bsp6QPtw6hZFySq8n # 50F0KYvrGH0MnQipkz7lV5RvFjl/cBf5gRSrebMIV1rvQMttrFxC06Y3zTbU6t4E # z1nDX76GZV7bmomreROITlH43UvsYacedTmiPp+SFDF5hjDz71XHaATzaSSL5puE # GRrGCyEh2Y/tw823jtk7jDLZrjb74kbGIB21/uUkjOWkhNGN55rDa933sjJuoZx2 # /pVSSmHxo+Bvc3td67EY4ylZj4CsBHmr6afeGKtZFT/QtnilYq+5nARiCDVKSHP0 # svNpmOCDZJg+aaq+TBAtvu6ddAogZ4FHtpOFQ+NQZeO9jWNn/9bYDdBlwejQKPqZ # 0p3oO+25FyYe8dxr1j82TyefL4mC486nVbSSk3XCu+LUKRmMkOh8cSKXyIP06RIz # LWQSpS1zenI+DREJ6VJHI/pBhRZGr9i6gwOIVaKva2t/AnaCkI4ulJd8iq6/lI+z # DvuLPjRqQOv2+Zf+1jbNV2I0BttmiFfXGDeAOCEaiF82lak6CcwkrGj3Hbt7YjuF # Zd7qCJWHG4pVrpJhwEScp+1+kDLpWGlupiPJv4XDhKUEqJPQ2KGhMzE0JDd8V7Si # 4gXvAoEZAPb1sjLcatDHYJX1acsAHEoYD2Um1Lx0pARy4LcHsTPrETz4EiiGg/iE # qeoXQDjtJraR++BTJXQyMYIaqTCCGqUCAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUG # A1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQg # RzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhAE0w/ewLw2 # E3KQ6RwmFyT5MA0GCWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKA # AKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO # MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIBmJuIJDxkQu3QJ1qfEJfhlS # NYJkQWVtidLCrB+1h6gQMA0GCSqGSIb3DQEBAQUABIICAAS7GrL9DWTYFQ4S4ONp # EY5B6qQTM6MgZ9pBwQbSeSt0G1Lff8TdOQfJqZj0KB7Cdqi+WLTGYFwODe1PhSbT # v1xANSiyAFJzgLbEC0qy80UcXU/FqPS8Bcc7MzXQl6FZONUTuIrLiuIahFESjbmb # WoRBEY5gA93rGBc5Feusj++r/5YYLRfW6Dm+SKWqqvfhLGONd7Wbhma2CKLpXuvG # yIXBnGoAQ03/QQLDAtQw+H2Mvw1rdlh0Ggnwrz9brHG+7eIpEZbTkRPQkaqohcGH # 1GhEJL/GnqqA02Ge2ZwmGmDE2kMUjJ00OXMd67r8A9+i4EsJU30/152y7v4QCDeC # ONOtBTX+Sv78443KzRxyLRY2PzkeAcrbbq9HBWD3Kwm+WW6XG17p6SUE5doEIk5H # MvQufVWSbANDCOtE0jKVGnBGUyimk7/oLe3OAFS3Wzj+zAfhvaCaG5pVBjSUJ9Y2 # KB2W3ShJ/m7troPoPg0DbiO+PJjT1bym3rqe1mSsSc5g/Pwj8yK8CTzwHESgqnmJ # tvScIDBTiH0o1E/2RfZJePE6F6+0meCT1k/iPPIvU7D9xmh1J46eJvDO76b3if6H # M/KBlpOac1MnJ7DxQx/BO7b+epPBCTatVru1eqxj7EvYMNTvVmgc9Z54vXZzJC0n # TdJzrd0tPJ5Xqu3kn5/MX/zNoYIXdjCCF3IGCisGAQQBgjcDAwExghdiMIIXXgYJ # KoZIhvcNAQcCoIIXTzCCF0sCAQMxDzANBglghkgBZQMEAgEFADB3BgsqhkiG9w0B # CRABBKBoBGYwZAIBAQYJYIZIAYb9bAcBMDEwDQYJYIZIAWUDBAIBBQAEIHzJu1bH # jaC6ZEXfklZWGOsAuI5E1i37tv5gmcZ5RSySAhACCeenEy6hzCrZOUj/JyZ8GA8y # MDI1MDgyMDA5NDMyMVqgghM6MIIG7TCCBNWgAwIBAgIQCoDvGEuN8QWC0cR2p5V0 # aDANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNl # cnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgVGltZVN0YW1w # aW5nIFJTQTQwOTYgU0hBMjU2IDIwMjUgQ0ExMB4XDTI1MDYwNDAwMDAwMFoXDTM2 # MDkwMzIzNTk1OVowYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ # bmMuMTswOQYDVQQDEzJEaWdpQ2VydCBTSEEyNTYgUlNBNDA5NiBUaW1lc3RhbXAg # UmVzcG9uZGVyIDIwMjUgMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB # ANBGrC0Sxp7Q6q5gVrMrV7pvUf+GcAoB38o3zBlCMGMyqJnfFNZx+wvA69HFTBdw # bHwBSOeLpvPnZ8ZN+vo8dE2/pPvOx/Vj8TchTySA2R4QKpVD7dvNZh6wW2R6kSu9 # RJt/4QhguSssp3qome7MrxVyfQO9sMx6ZAWjFDYOzDi8SOhPUWlLnh00Cll8pjrU # cCV3K3E0zz09ldQ//nBZZREr4h/GI6Dxb2UoyrN0ijtUDVHRXdmncOOMA3CoB/iU # SROUINDT98oksouTMYFOnHoRh6+86Ltc5zjPKHW5KqCvpSduSwhwUmotuQhcg9tw # 2YD3w6ySSSu+3qU8DD+nigNJFmt6LAHvH3KSuNLoZLc1Hf2JNMVL4Q1OpbybpMe4 # 6YceNA0LfNsnqcnpJeItK/DhKbPxTTuGoX7wJNdoRORVbPR1VVnDuSeHVZlc4seA # O+6d2sC26/PQPdP51ho1zBp+xUIZkpSFA8vWdoUoHLWnqWU3dCCyFG1roSrgHjSH # lq8xymLnjCbSLZ49kPmk8iyyizNDIXj//cOgrY7rlRyTlaCCfw7aSUROwnu7zER6 # EaJ+AliL7ojTdS5PWPsWeupWs7NpChUk555K096V1hE0yZIXe+giAwW00aHzrDch # Ic2bQhpp0IoKRR7YufAkprxMiXAJQ1XCmnCfgPf8+3mnAgMBAAGjggGVMIIBkTAM # BgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTkO/zyMe39/dfzkXFjGVBDz2GM6DAfBgNV # HSMEGDAWgBTvb1NK6eQGfHrK4pBW9i/USezLTjAOBgNVHQ8BAf8EBAMCB4AwFgYD # VR0lAQH/BAwwCgYIKwYBBQUHAwgwgZUGCCsGAQUFBwEBBIGIMIGFMCQGCCsGAQUF # BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXQYIKwYBBQUHMAKGUWh0dHA6 # Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFRpbWVTdGFt # cGluZ1JTQTQwOTZTSEEyNTYyMDI1Q0ExLmNydDBfBgNVHR8EWDBWMFSgUqBQhk5o # dHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRUaW1lU3Rh # bXBpbmdSU0E0MDk2U0hBMjU2MjAyNUNBMS5jcmwwIAYDVR0gBBkwFzAIBgZngQwB # BAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQBlKq3xHCcEua5gQezR # CESeY0ByIfjk9iJP2zWLpQq1b4URGnwWBdEZD9gBq9fNaNmFj6Eh8/YmRDfxT7C0 # k8FUFqNh+tshgb4O6Lgjg8K8elC4+oWCqnU/ML9lFfim8/9yJmZSe2F8AQ/UdKFO # tj7YMTmqPO9mzskgiC3QYIUP2S3HQvHG1FDu+WUqW4daIqToXFE/JQ/EABgfZXLW # U0ziTN6R3ygQBHMUBaB5bdrPbF6MRYs03h4obEMnxYOX8VBRKe1uNnzQVTeLni2n # HkX/QqvXnNb+YkDFkxUGtMTaiLR9wjxUxu2hECZpqyU1d0IbX6Wq8/gVutDojBIF # eRlqAcuEVT0cKsb+zJNEsuEB7O7/cuvTQasnM9AWcIQfVjnzrvwiCZ85EE8LUkqR # hoS3Y50OHgaY7T/lwd6UArb+BOVAkg2oOvol/DJgddJ35XTxfUlQ+8Hggt8l2Yv7 # roancJIFcbojBcxlRcGG0LIhp6GvReQGgMgYxQbV1S3CrWqZzBt1R9xJgKf47Cdx # VRd/ndUlQ05oxYy2zRWVFjF7mcr4C34Mj3ocCVccAvlKV9jEnstrniLvUxxVZE/r # ptb7IRE2lskKPIJgbaP5t2nGj/ULLi49xTcBZU8atufk+EMF/cWuiC7POGT75qaL # 6vdCvHlshtjdNXOCIUjsarfNZzCCBrQwggScoAMCAQICEA3HrFcF/yGZLkBDIgw6 # SYYwDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lD # ZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGln # aUNlcnQgVHJ1c3RlZCBSb290IEc0MB4XDTI1MDUwNzAwMDAwMFoXDTM4MDExNDIz # NTk1OVowaTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEw # PwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IFRpbWVTdGFtcGluZyBSU0E0MDk2 # IFNIQTI1NiAyMDI1IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB # ALR4MdMKmEFyvjxGwBysddujRmh0tFEXnU2tjQ2UtZmWgyxU7UNqEY81FzJsQqr5 # G7A6c+Gh/qm8Xi4aPCOo2N8S9SLrC6Kbltqn7SWCWgzbNfiR+2fkHUiljNOqnIVD # /gG3SYDEAd4dg2dDGpeZGKe+42DFUF0mR/vtLa4+gKPsYfwEu7EEbkC9+0F2w4QJ # LVSTEG8yAR2CQWIM1iI5PHg62IVwxKSpO0XaF9DPfNBKS7Zazch8NF5vp7eaZ2CV # NxpqumzTCNSOxm+SAWSuIr21Qomb+zzQWKhxKTVVgtmUPAW35xUUFREmDrMxSNlr # /NsJyUXzdtFUUt4aS4CEeIY8y9IaaGBpPNXKFifinT7zL2gdFpBP9qh8SdLnEut/ # GcalNeJQ55IuwnKCgs+nrpuQNfVmUB5KlCX3ZA4x5HHKS+rqBvKWxdCyQEEGcbLe # 1b8Aw4wJkhU1JrPsFfxW1gaou30yZ46t4Y9F20HHfIY4/6vHespYMQmUiote8lad # jS/nJ0+k6MvqzfpzPDOy5y6gqztiT96Fv/9bH7mQyogxG9QEPHrPV6/7umw052Ak # yiLA6tQbZl1KhBtTasySkuJDpsZGKdlsjg4u70EwgWbVRSX1Wd4+zoFpp4Ra+MlK # M2baoD6x0VR4RjSpWM8o5a6D8bpfm4CLKczsG7ZrIGNTAgMBAAGjggFdMIIBWTAS # BgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTvb1NK6eQGfHrK4pBW9i/USezL # TjAfBgNVHSMEGDAWgBTs1+OC0nFdZEzfLmc/57qYrhwPTzAOBgNVHQ8BAf8EBAMC # AYYwEwYDVR0lBAwwCgYIKwYBBQUHAwgwdwYIKwYBBQUHAQEEazBpMCQGCCsGAQUF # BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQQYIKwYBBQUHMAKGNWh0dHA6 # Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3J0 # MEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdp # Q2VydFRydXN0ZWRSb290RzQuY3JsMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCG # SAGG/WwHATANBgkqhkiG9w0BAQsFAAOCAgEAF877FoAc/gc9EXZxML2+C8i1NKZ/ # zdCHxYgaMH9Pw5tcBnPw6O6FTGNpoV2V4wzSUGvI9NAzaoQk97frPBtIj+ZLzdp+ # yXdhOP4hCFATuNT+ReOPK0mCefSG+tXqGpYZ3essBS3q8nL2UwM+NMvEuBd/2vmd # YxDCvwzJv2sRUoKEfJ+nN57mQfQXwcAEGCvRR2qKtntujB71WPYAgwPyWLKu6Rna # ID/B0ba2H3LUiwDRAXx1Neq9ydOal95CHfmTnM4I+ZI2rVQfjXQA1WSjjf4J2a7j # LzWGNqNX+DF0SQzHU0pTi4dBwp9nEC8EAqoxW6q17r0z0noDjs6+BFo+z7bKSBwZ # XTRNivYuve3L2oiKNqetRHdqfMTCW/NmKLJ9M+MtucVGyOxiDf06VXxyKkOirv6o # 02OoXN4bFzK0vlNMsvhlqgF2puE6FndlENSmE+9JGYxOGLS/D284NHNboDGcmWXf # wXRy4kbu4QFhOm0xJuF2EZAOk5eCkhSxZON3rGlHqhpB/8MluDezooIs8CVnrpHM # iD2wL40mm53+/j7tFaxYKIqL0Q4ssd8xHZnIn/7GELH3IdvG2XlM9q7WP/UwgOkw # /HQtyRN62JK4S1C8uw3PdBunvAZapsiI5YKdvlarEvf8EA+8hcpSM9LHJmyrxaFt # oza2zNaQ9k+5t1wwggWNMIIEdaADAgECAhAOmxiO+dAt5+/bUOIIQBhaMA0GCSqG # SIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx # GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFz # c3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBaFw0zMTExMDkyMzU5NTla # MGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsT # EHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9v # dCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL/mkHNo3rvkXUo8 # MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/zG6Q4FutWxpdtHauy # efLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZanMylNEQRBAu34Lz # B4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7sWxq868nPzaw0QF+x # embud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL2pNe3I6PgNq2kZhA # kHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfbBHMqbpEBfCFM1Lyu # GwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3JFxGj2T3wWmIdph2 # PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3cAORFJYm2mkQZK37A # lLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqxYxhElRp2Yn72gLD7 # 6GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0viastkF13nqsX40/ # ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aLT8LWRV+dIPyhHsXA # j6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIBNjAPBgNVHRMBAf8EBTAD # AQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwPTzAfBgNVHSMEGDAWgBRF # 66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMCAYYweQYIKwYBBQUHAQEE # bTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYB # BQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3Vy # ZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0aHR0cDovL2NybDMuZGln # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDARBgNVHSAECjAI # MAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0NcVec4X6CjdBs9thbX979X # B72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnovLbc47/T/gLn4offyct4k # vFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65ZyoUi0mcudT6cGAxN3J0TU # 53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFWjuyk1T3osdz9HNj0d1pc # VIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPFmCLBsln1VWvPJ6tsds5v # Iy30fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9ztwGpn1eqXijiuZQxggN8 # MIIDeAIBATB9MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5j # LjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1lU3RhbXBpbmcgUlNB # NDA5NiBTSEEyNTYgMjAyNSBDQTECEAqA7xhLjfEFgtHEdqeVdGgwDQYJYIZIAWUD # BAIBBQCggdEwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJ # BTEPFw0yNTA4MjAwOTQzMjFaMCsGCyqGSIb3DQEJEAIMMRwwGjAYMBYEFN1iMKyG # Ci0wa9o4sWh5UjAH+0F+MC8GCSqGSIb3DQEJBDEiBCAHWEoXjKECN52mRpJg4k6T # KadENoR1R8pjrwJj1MKZfDA3BgsqhkiG9w0BCRACLzEoMCYwJDAiBCBKoD+iLNdc # hMVck4+CjmdrnK7Ksz/jbSaaozTxRhEKMzANBgkqhkiG9w0BAQEFAASCAgCfpEx6 # I7COqE4/UTeQr5L11+AOByXC8veo7GuhPzxZaWBUsbRUiIXNgFGZg8pu7K/nlXL0 # AEPkLx/w4t8xtPwNJilTcckgDqSlj6vhY6iOzxeGKcSXpsBVnA5+bQ0XF+QbZKAN # L5L04DQ8FxjDWfbelsc9Z+zza3F6XN3w/vjRkefyN3naO8Rosxknf37YmnCn2Vj0 # q3NXhCy/atC5ocFssQSuVVpmkl5ESpcDhR8W1JOncmUExvs0popDMW99QAipeflG # zwDGio8JV2qd3jyFc09/seOQWzQ1+ka/G0BlcBA972abU7Q3Bf7BK1kJJi0bxeKU # hAhrFWiTb9Qcn/z/E+apOPtJP2YTlcSipDccw5SSrlzMvdUkpOKOF6PEceCSySec # cRyoGW3xvrC2kzNKsBbj77Ts5SEuDtPxlM2M/io0dn+XV0Vz8e25nF15QGHGgddj # vcuJkas8tH/xCe7vaA2imVxBOFIyb9c0LqITOi0HFl7yGNrIynCCG+8PGKCGxy5q # QvXjlIOr0ti5dVW6i8wbdaOuV1D0r9X5JZCYbFKQTcx6I0S21/IANCG9TMiV+Y8c # R5zlARVTdVJh6ooo3k1l6cIdX6Z9HgIHaH4txw6KDDhbw3SYcE7obGdG7MptAGbm # 9+Armc2kQC74V7LODrRUfySIx8AQKsYnYFsA8g== # SIG # End signature block |