Functions/Get-IssuedCertificate.ps1
<#
.SYNOPSIS Allows for Submission of a Certificate Request to a Certification Authority. Allows for retrieval of a previously issued Certificate from a Certification Authority. .PARAMETER CertificateRequest The BASE64 encoded Certificate Request to be submitted to the Certification Authority. .PARAMETER RequestId The Request Identifier that was given to a previously submitted Certificate Request. .PARAMETER ConfigString The Configuration String for the Certificate Authority to connect to, either in the Form of "<Hostname>\<Common-Name-of-CA>" for a RPC/DCOM Enrollment or in for Form of "https://<Hostname>/<Common-Name-of-CA>_CES_<Authentication-Type>/service.svc/CES" for a WSTEP (Certificate Enrollment Web Service) Enrollment. .PARAMETER CertificateTemplate Optional: The name of the Certificate Template to request a Certificate from. Must be used if the Certificate request does not contain this information. .PARAMETER Credential Credentials when performing a WSTEP Enrollment with Username/Password Authentication. .PARAMETER ClientCertificate Thumbprint of an authentication Certificate when performing a WSTEP Enrollment with Client Certificate Authentication. .PARAMETER MachineContext Uses the machine's identity for submitting the certificate request. .OUTPUTS An object representing the Enrollment/Retrieval result. #> Function Get-IssuedCertificate { [CmdletBinding()] param ( [Parameter( ParameterSetName="Submit", Mandatory=$True, ValuefromPipeline=$True )] [ValidateNotNullOrEmpty()] [String] $CertificateRequest, [Parameter( ParameterSetName="Retrieve", Mandatory=$True )] [ValidateRange(1, [Int]::MaxValue)] [Int] $RequestId, [Alias("Machine")] [Parameter(Mandatory=$False)] [Switch] $MachineContext = $False, [Alias("Config")] [Parameter(Mandatory=$True)] [ValidateNotNullOrEmpty()] [String] $ConfigString, [Parameter( ParameterSetName="Submit", Mandatory=$False )] [ValidateNotNullOrEmpty()] [String] $CertificateTemplate, [Parameter(Mandatory=$False)] [System.Management.Automation.PSCredential] $Credential, [Parameter(Mandatory=$False)] [ValidatePattern("^[0-9a-fA-F]{40}$")] [String] $ClientCertificate, [Alias("Attrib")] [Parameter( ParameterSetName="Submit", Mandatory=$False )] [String[]] $RequestAttributes ) begin {} process { # Ensuring we work with Elevation when using the machine identity If ($MachineContext.IsPresent) { If (-not ( [Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent() ).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Write-Error -Message "This must be run with Elevation (Run as Administrator) when using the Machine Context!" return } } # https://docs.microsoft.com/en-us/windows/win32/api/certcli/nn-certcli-icertrequest $CertRequest = New-Object -ComObject CertificateAuthority.Request # Configuring the Certificate Request Interface when using the WSTEP Protocol # https://docs.microsoft.com/en-us/windows/win32/api/certcli/nf-certcli-icertrequest3-setcredential If ($ConfigString.StartsWith("https://")) { # WSTEP with Username and Password Authentication If ($ConfigString.EndsWith( "UsernamePassword/service.svc/CES", [System.StringComparison]::OrdinalIgnoreCase )) { If ($Credential) { $CertRequest.SetCredential( [Int]$null, # no Window Handle $X509EnrollmentAuthFlags.X509AuthUsername, $Credential.UserName, [Runtime.InteropServices.Marshal]::PtrToStringAuto( [Runtime.InteropServices.Marshal]::SecureStringToBSTR($Credential.Password) ) ) } Else { Write-Error -Message "You must provide Authentication Credentials." return } } # WSTEP with Client Certificate Authentication If ($ConfigString.EndsWith( "Certificate/service.svc/CES", [System.StringComparison]::OrdinalIgnoreCase )) { If ($ClientCertificate) { $CertRequest.SetCredential( [Int]$null, # no Window Handle $X509EnrollmentAuthFlags.X509AuthCertificate, $ClientCertificate, [String]::Empty ) } Else { Write-Error -Message "You must provide a Client Authentication Certificate Thumbprint." return } } # WSTEP with Kerberos Authentication If ($ConfigString.EndsWith( "Kerberos/service.svc/CES", [System.StringComparison]::OrdinalIgnoreCase )) { $CertRequest.SetCredential( [Int]$null, # no Window Handle $X509EnrollmentAuthFlags.X509AuthKerberos, [String]::Empty, [String]::Empty ) } } # Submit a Certificate Request If ($CertificateRequest) { # Additional attributes can be specified here # https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/certutil # Names and values must be colon separated, while multiple name, value pairs must be newline separated. # For example: CertificateTemplate:User\nEMail:User@Domain.com where the \n sequence is converted to a newline separator. If ($CertificateTemplate) { $RequestAttributes += "CertificateTemplate:$($CertificateTemplate)" # Names and values must be colon separated } $Flags = $RequestFlags.CR_IN_ENCODEANY If ($MachineContext.IsPresent) { $Flags = $Flags -bor $RequestFlags.CR_IN_MACHINE } Try { # https://docs.microsoft.com/en-us/windows/win32/api/certcli/nf-certcli-icertrequest-submit $Status = $CertRequest.Submit( $Flags, $CertificateRequest, $($RequestAttributes -join [Environment]::NewLine), # multiple name, value pairs must be newline separated. $ConfigString ) } Catch { Write-Error -Message $PSItem.Exception.Message return } } # Retrieve a pending Certificate Request If ($RequestId) { Try { # https://docs.microsoft.com/en-us/windows/win32/api/certcli/nf-certcli-icertrequest-retrievepending $Status = $CertRequest.RetrievePending( $RequestId, $ConfigString ) } Catch { Write-Error -Message $PSItem.Exception.Message return } } # Properly formatting Return Code and translate into a meaningful message $StatusCode = "0x" + ('{0:x}' -f $CertRequest.GetLastStatus()) $StatusCodeInt = $CertRequest.GetLastStatus() $StatusMessage = (New-Object System.ComponentModel.Win32Exception($CertRequest.GetLastStatus())).Message # Process the Submission Result and return it Switch ($Status) { $DispositionType.CR_DISP_INCOMPLETE { [PSCustomObject]@{ RequestId = $CertRequest.GetRequestId() Disposition = $Status Result = "Request is incomplete" StatusCode = $StatusCode StatusCodeInt = $StatusCodeInt StatusMessage = $StatusMessage Certificate = $null RawCertificate = $null } } $DispositionType.CR_DISP_ERROR { [PSCustomObject]@{ RequestId = $CertRequest.GetRequestId() Disposition = $Status Result = "There was an error during submission" StatusCode = $StatusCode StatusCodeInt = $StatusCodeInt StatusMessage = $StatusMessage Certificate = $null RawCertificate = $null } } $DispositionType.CR_DISP_DENIED { [PSCustomObject]@{ RequestId = $CertRequest.GetRequestId() Disposition = $Status Result = "Request was denied" StatusCode = $StatusCode StatusCodeInt = $StatusCodeInt StatusMessage = $StatusMessage Certificate = $null RawCertificate = $null } } $DispositionType.CR_DISP_ISSUED { # https://docs.microsoft.com/en-us/windows/win32/api/certcli/nf-certcli-icertrequest-getcertificate # https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.x509certificate2.import $CertificateObject = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $CertificateObject.Import( [Convert]::FromBase64String( $CertRequest.GetCertificate($RequestFlags.CR_OUT_BASE64) ) ) [PSCustomObject]@{ RequestId = $CertRequest.GetRequestId() Disposition = $Status Result = "Certificate was issued" StatusCode = $StatusCode StatusCodeInt = $StatusCodeInt StatusMessage = $StatusMessage Certificate = $CertificateObject RawCertificate = $CertRequest.GetCertificate($RequestFlags.CR_OUT_BASE64HEADER) } } $DispositionType.CR_DISP_ISSUED_OUT_OF_BAND { [PSCustomObject]@{ RequestId = $CertRequest.GetRequestId() Disposition = $Status Result = "Certificate was issued out of band" StatusCode = $StatusCode StatusCodeInt = $StatusCodeInt StatusMessage = $StatusMessage Certificate = $null RawCertificate = $null } } $DispositionType.CR_DISP_UNDER_SUBMISSION { [PSCustomObject]@{ RequestId = $CertRequest.GetRequestId() Disposition = $Status Result = "Request was taken under submission" StatusCode = $StatusCode StatusCodeInt = $StatusCodeInt StatusMessage = $StatusMessage Certificate = $null RawCertificate = $null } } $DispositionType.CR_DISP_REVOKED { [PSCustomObject]@{ RequestId = $CertRequest.GetRequestId() Disposition = $Status Result = "Certificate has been revoked" StatusCode = $StatusCode StatusCodeInt = $StatusCodeInt StatusMessage = $StatusMessage Certificate = $null RawCertificate = $null } } # This should never happen, but just to be on the safe side default{ Write-Error -Message "Retrieved unsupported Disposition Code $Status from the Certification Authority." } } [void]([System.Runtime.Interopservices.Marshal]::ReleaseComObject($CertRequest)) } end {} } # SIG # Begin signature block # MIIk6AYJKoZIhvcNAQcCoIIk2TCCJNUCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAGZ7ZB5LHA8OYh # 1tL/e/DDswXFkJJK5eRLlMcMVVIaTKCCHqswggVAMIIEKKADAgECAhEAjyqX/F4u # bPBaKM2QGtlbKTANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJHQjEbMBkGA1UE # CBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRgwFgYDVQQK # Ew9TZWN0aWdvIExpbWl0ZWQxJDAiBgNVBAMTG1NlY3RpZ28gUlNBIENvZGUgU2ln # bmluZyBDQTAeFw0yMDExMjAwMDAwMDBaFw0yMzExMjAyMzU5NTlaMIGHMQswCQYD # VQQGEwJERTEOMAwGA1UEEQwFOTE2MDIxHTAbBgNVBAcMFETDvHJyd2FuZ2VuIEhh # bHNiYWNoMRUwEwYDVQQJDAxXZWloZXJ3ZWcgMTUxGDAWBgNVBAoMD1V3ZSBHcmFk # ZW5lZ2dlcjEYMBYGA1UEAwwPVXdlIEdyYWRlbmVnZ2VyMIIBIjANBgkqhkiG9w0B # AQEFAAOCAQ8AMIIBCgKCAQEA53wYl/2oLVZBtzGBVrhekovOH+jLXaqR8bcrXUEt # GzZS5mhld6V58oliKsdanM2WGRtGga/ew1QKAqlEO3LPWQd/6O+T6ewH1IJy0xxy # Zv3zsEDySr+2iAZaOqUdxAV8ROuW/fPGJCR3nrRO2vH047z+aAi9S5sZbiO21634 # BRXw94cl4JArB62gSfehtyCqO5oBLjWdz9/41pfrCQPyIoalfL4Ksdt+WEAJqy9T # JyEF/8GWbGxko/yx/p1k03QjtNT2SM7kDw2JYCnsn2hPPS18q4ca6sZqqUAxBQl0 # P1E0POzP4I3XD8uNuSF8lrCegjxdHuDycgE4fZ1/5giY9QIDAQABo4IBrzCCAasw # HwYDVR0jBBgwFoAUDuE6qFM6MdWKvsG7rWcaA4WtNA4wHQYDVR0OBBYEFCmcAsJF # JdY/qAsyvvsYLFw96N2aMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBMG # A1UdJQQMMAoGCCsGAQUFBwMDMBEGCWCGSAGG+EIBAQQEAwIEEDBKBgNVHSAEQzBB # MDUGDCsGAQQBsjEBAgEDAjAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3RpZ28u # Y29tL0NQUzAIBgZngQwBBAEwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5z # ZWN0aWdvLmNvbS9TZWN0aWdvUlNBQ29kZVNpZ25pbmdDQS5jcmwwcwYIKwYBBQUH # AQEEZzBlMD4GCCsGAQUFBzAChjJodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3Rp # Z29SU0FDb2RlU2lnbmluZ0NBLmNydDAjBggrBgEFBQcwAYYXaHR0cDovL29jc3Au # c2VjdGlnby5jb20wHQYDVR0RBBYwFIESdXdlQGdyYWRlbmVnZ2VyLmV1MA0GCSqG # SIb3DQEBCwUAA4IBAQCEQ6MLH2xJoylM/1EVGcnHx1yfR4N0KTpMZmUHeDKHbhVa # 75UQJRd3/Wy9knpqk8NGnPaS8XNOUgR8A5EoO5djvZfp4JLtUVOM28TI0U+avrtP # olQHtCRrpb12kCqG5/E5DQNFL9qTK0/cngkXQFiJncjF+AAfWOL+5e4zIPWMVJaw # PKFIyT47S6BjD5NopviPxcJY3uQ3y5WFqpeYMWL1cpMpC26tvEQbecJLGW51m3l8 # MiaPtxieiuEje8YplJdBOOBDVO+NTJvhiOhOhM2Nnp/PcdqYAuiLpAcv2ekcHp6Q # svBWxRbwb23mjni1DipueBqn98FCTQkNDQLb6KRuMIIFgTCCBGmgAwIBAgIQOXJE # Ovkit1HX02wQ3TE1lTANBgkqhkiG9w0BAQwFADB7MQswCQYDVQQGEwJHQjEbMBkG # A1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYD # VQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRl # IFNlcnZpY2VzMB4XDTE5MDMxMjAwMDAwMFoXDTI4MTIzMTIzNTk1OVowgYgxCzAJ # BgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJzZXkg # Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMS4wLAYDVQQDEyVV # U0VSVHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG # 9w0BAQEFAAOCAg8AMIICCgKCAgEAgBJlFzYOw9sIs9CsVw127c0n00ytUINh4qog # TQktZAnczomfzD2p7PbPwdzx07HWezcoEStH2jnGvDoZtF+mvX2do2NCtnbyqTsr # kfjib9DsFiCQCT7i6HTJGLSR1GJk23+jBvGIGGqQIjy8/hPwhxR79uQfjtTkUcYR # Z0YIUcuGFFQ/vDP+fmyc/xadGL1RjjWmp2bIcmfbIWax1Jt4A8BQOujM8Ny8nkz+ # rwWWNR9XWrf/zvk9tyy29lTdyOcSOk2uTIq3XJq0tyA9yn8iNK5+O2hmAUTnAU5G # U5szYPeUvlM3kHND8zLDU+/bqv50TmnHa4xgk97Exwzf4TKuzJM7UXiVZ4vuPVb+ # DNBpDxsP8yUmazNt925H+nND5X4OpWaxKXwyhGNVicQNwZNUMBkTrNN9N6frXTps # NVzbQdcS2qlJC9/YgIoJk2KOtWbPJYjNhLixP6Q5D9kCnusSTJV882sFqV4Wg8y4 # Z+LoE53MW4LTTLPtW//e5XOsIzstAL81VXQJSdhJWBp/kjbmUZIO8yZ9HE0XvMns # QybQv0FfQKlERPSZ51eHnlAfV1SoPv10Yy+xUGUJ5lhCLkMaTLTwJUdZ+gQek9Qm # RkpQgbLevni3/GcV4clXhB4PY9bpYrrWX1Uu6lzGKAgEJTm4Diup8kyXHAc/DVL1 # 7e8vgg8CAwEAAaOB8jCB7zAfBgNVHSMEGDAWgBSgEQojPpbxB+zirynvgqV/0DCk # tDAdBgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgGG # MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAGBgRVHSAAMEMGA1UdHwQ8MDow # OKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL0FBQUNlcnRpZmljYXRlU2Vy # dmljZXMuY3JsMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29j # c3AuY29tb2RvY2EuY29tMA0GCSqGSIb3DQEBDAUAA4IBAQAYh1HcdCE9nIrgJ7cz # 0C7M7PDmy14R3iJvm3WOnnL+5Nb+qh+cli3vA0p+rvSNb3I8QzvAP+u431yqqcau # 8vzY7qN7Q/aGNnwU4M309z/+3ri0ivCRlv79Q2R+/czSAaF9ffgZGclCKxO/WIu6 # pKJmBHaIkU4MiRTOok3JMrO66BQavHHxW/BBC5gACiIDEOUMsfnNkjcZ7Tvx5Dq2 # +UUTJnWvu6rvP3t3O9LEApE9GQDTF1w52z97GA1FzZOFli9d31kWTz9RvdVFGD/t # So7oBmF0Ixa1DVBzJ0RHfxBdiSprhTEUxOipakyAvGp4z7h/jnZymQyd/teRCBah # o1+VMIIF9TCCA92gAwIBAgIQHaJIMG+bJhjQguCWfTPTajANBgkqhkiG9w0BAQwF # ADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcT # C0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAs # BgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcN # MTgxMTAyMDAwMDAwWhcNMzAxMjMxMjM1OTU5WjB8MQswCQYDVQQGEwJHQjEbMBkG # A1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRgwFgYD # VQQKEw9TZWN0aWdvIExpbWl0ZWQxJDAiBgNVBAMTG1NlY3RpZ28gUlNBIENvZGUg # U2lnbmluZyBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIYijTKF # ehifSfCWL2MIHi3cfJ8Uz+MmtiVmKUCGVEZ0MWLFEO2yhyemmcuVMMBW9aR1xqkO # UGKlUZEQauBLYq798PgYrKf/7i4zIPoMGYmobHutAMNhodxpZW0fbieW15dRhqb0 # J+V8aouVHltg1X7XFpKcAC9o95ftanK+ODtj3o+/bkxBXRIgCFnoOc2P0tbPBrRX # BbZOoT5Xax+YvMRi1hsLjcdmG0qfnYHEckC14l/vC0X/o84Xpi1VsLewvFRqnbyN # VlPG8Lp5UEks9wO5/i9lNfIi6iwHr0bZ+UYc3Ix8cSjz/qfGFN1VkW6KEQ3fBiSV # fQ+noXw62oY1YdMCAwEAAaOCAWQwggFgMB8GA1UdIwQYMBaAFFN5v1qqK0rPVIDh # 2JvAnfKyA2bLMB0GA1UdDgQWBBQO4TqoUzox1Yq+wbutZxoDha00DjAOBgNVHQ8B # Af8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHSUEFjAUBggrBgEFBQcD # AwYIKwYBBQUHAwgwEQYDVR0gBAowCDAGBgRVHSAAMFAGA1UdHwRJMEcwRaBDoEGG # P2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FDZXJ0aWZpY2F0 # aW9uQXV0aG9yaXR5LmNybDB2BggrBgEFBQcBAQRqMGgwPwYIKwYBBQUHMAKGM2h0 # dHA6Ly9jcnQudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FBZGRUcnVzdENBLmNy # dDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG # 9w0BAQwFAAOCAgEATWNQ7Uc0SmGk295qKoyb8QAAHh1iezrXMsL2s+Bjs/thAIia # G20QBwRPvrjqiXgi6w9G7PNGXkBGiRL0C3danCpBOvzW9Ovn9xWVM8Ohgyi33i/k # lPeFM4MtSkBIv5rCT0qxjyT0s4E307dksKYjalloUkJf/wTr4XRleQj1qZPea3FA # mZa6ePG5yOLDCBaxq2NayBWAbXReSnV+pbjDbLXP30p5h1zHQE1jNfYw08+1Cg4L # BH+gS667o6XQhACTPlNdNKUANWlsvp8gJRANGftQkGG+OY96jk32nw4e/gdREmaD # JhlIlc5KycF/8zoFm/lv34h/wCOe0h5DekUxwZxNqfBZslkZ6GqNKQQCd3xLS81w # vjqyVVp4Pry7bwMQJXcVNIr5NsxDkuS6T/FikyglVyn7URnHoSVAaoRXxrKdsbwc # Ctp8Z359LukoTBh+xHsxQXGaSynsCz1XUNLK3f2eBVHlRHjdAd6xdZgNVCT98E7j # 4viDvXK6yz067vBeF5Jobchh+abxKgoLpbn0nu6YMgWFnuv5gynTxix9vTp3Los3 # QqBqgu07SqqUEKThDfgXxbZaeTMYkuO1dfih6Y4KJR7kHvGfWocj/5+kUZ77OYAR # zdu1xKeogG/lU9Tg46LC0lsa+jImLWpXcBw8pFguo/NbSwfcMlnzh6cabVgwggbs # MIIE1KADAgECAhAwD2+s3WaYdHypRjaneC25MA0GCSqGSIb3DQEBDAUAMIGIMQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKTmV3IEplcnNleTEUMBIGA1UEBxMLSmVyc2V5 # IENpdHkxHjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEuMCwGA1UEAxMl # VVNFUlRydXN0IFJTQSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xOTA1MDIw # MDAwMDBaFw0zODAxMTgyMzU5NTlaMH0xCzAJBgNVBAYTAkdCMRswGQYDVQQIExJH # cmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoTD1Nl # Y3RpZ28gTGltaXRlZDElMCMGA1UEAxMcU2VjdGlnbyBSU0EgVGltZSBTdGFtcGlu # ZyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMgbAa/ZLH6ImX0B # mD8gkL2cgCFUk7nPoD5T77NawHbWGgSlzkeDtevEzEk0y/NFZbn5p2QWJgn71TJS # eS7JY8ITm7aGPwEFkmZvIavVcRB5h/RGKs3EWsnb111JTXJWD9zJ41OYOioe/M5Y # SdO/8zm7uaQjQqzQFcN/nqJc1zjxFrJw06PE37PFcqwuCnf8DZRSt/wflXMkPQEo # vA8NT7ORAY5unSd1VdEXOzQhe5cBlK9/gM/REQpXhMl/VuC9RpyCvpSdv7QgsGB+ # uE31DT/b0OqFjIpWcdEtlEzIjDzTFKKcvSb/01Mgx2Bpm1gKVPQF5/0xrPnIhRfH # uCkZpCkvRuPd25Ffnz82Pg4wZytGtzWvlr7aTGDMqLufDRTUGMQwmHSCIc9iVrUh # cxIe/arKCFiHd6QV6xlV/9A5VC0m7kUaOm/N14Tw1/AoxU9kgwLU++Le8bwCKPRt # 2ieKBtKWh97oaw7wW33pdmmTIBxKlyx3GSuTlZicl57rjsF4VsZEJd8GEpoGLZ8D # Xv2DolNnyrH6jaFkyYiSWcuoRsDJ8qb/fVfbEnb6ikEk1Bv8cqUUotStQxykSYtB # ORQDHin6G6UirqXDTYLQjdprt9v3GEBXc/Bxo/tKfUU2wfeNgvq5yQ1TgH36tjlY # Mu9vGFCJ10+dM70atZ2h3pVBeqeDAgMBAAGjggFaMIIBVjAfBgNVHSMEGDAWgBRT # eb9aqitKz1SA4dibwJ3ysgNmyzAdBgNVHQ4EFgQUGqH4YRkgD8NBd0UojtE1XwYS # BFUwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAwEwYDVR0lBAww # CgYIKwYBBQUHAwgwEQYDVR0gBAowCDAGBgRVHSAAMFAGA1UdHwRJMEcwRaBDoEGG # P2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FDZXJ0aWZpY2F0 # aW9uQXV0aG9yaXR5LmNybDB2BggrBgEFBQcBAQRqMGgwPwYIKwYBBQUHMAKGM2h0 # dHA6Ly9jcnQudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FBZGRUcnVzdENBLmNy # dDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG # 9w0BAQwFAAOCAgEAbVSBpTNdFuG1U4GRdd8DejILLSWEEbKw2yp9KgX1vDsn9Fqg # uUlZkClsYcu1UNviffmfAO9Aw63T4uRW+VhBz/FC5RB9/7B0H4/GXAn5M17qoBwm # WFzztBEP1dXD4rzVWHi/SHbhRGdtj7BDEA+N5Pk4Yr8TAcWFo0zFzLJTMJWk1vSW # Vgi4zVx/AZa+clJqO0I3fBZ4OZOTlJux3LJtQW1nzclvkD1/RXLBGyPWwlWEZuSz # xWYG9vPWS16toytCiiGS/qhvWiVwYoFzY16gu9jc10rTPa+DBjgSHSSHLeT8AtY+ # dwS8BDa153fLnC6NIxi5o8JHHfBd1qFzVwVomqfJN2Udvuq82EKDQwWli6YJ/9Gh # lKZOqj0J9QVst9JkWtgqIsJLnfE5XkzeSD2bNJaaCV+O/fexUpHOP4n2HKG1qXUf # cb9bQ11lPVCBbqvw0NP8srMftpmWJvQ8eYtcZMzN7iea5aDADHKHwW5NWtMe6vBE # 5jJvHOsXTpTDeGUgOw9Bqh/poUGd/rG4oGUqNODeqPk85sEwu8CgYyz8XBYAqNDE # f+oRnR4GxqZtMl20OAkrSQeq/eww2vGnL8+3/frQo4TZJ577AWZ3uVYQ4SBuxq6x # +ba6yDVdM3aO8XwgDCp3rrWiAoa6Ke60WgCxjKvj+QrJVF3UuWp0nr1Irpgwggb1 # MIIE3aADAgECAhA5TCXhfKBtJ6hl4jvZHSLUMA0GCSqGSIb3DQEBDAUAMH0xCzAJ # BgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcT # B1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDElMCMGA1UEAxMcU2Vj # dGlnbyBSU0EgVGltZSBTdGFtcGluZyBDQTAeFw0yMzA1MDMwMDAwMDBaFw0zNDA4 # MDIyMzU5NTlaMGoxCzAJBgNVBAYTAkdCMRMwEQYDVQQIEwpNYW5jaGVzdGVyMRgw # FgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxLDAqBgNVBAMMI1NlY3RpZ28gUlNBIFRp # bWUgU3RhbXBpbmcgU2lnbmVyICM0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC # CgKCAgEApJMoUkvPJ4d2pCkcmTjA5w7U0RzsaMsBZOSKzXewcWWCvJ/8i7u7lZj7 # JRGOWogJZhEUWLK6Ilvm9jLxXS3AeqIO4OBWZO2h5YEgciBkQWzHwwj6831d7yGa # wn7XLMO6EZge/NMgCEKzX79/iFgyqzCz2Ix6lkoZE1ys/Oer6RwWLrCwOJVKz4VQ # q2cDJaG7OOkPb6lampEoEzW5H/M94STIa7GZ6A3vu03lPYxUA5HQ/C3PVTM4egkc # B9Ei4GOGp7790oNzEhSbmkwJRr00vOFLUHty4Fv9GbsfPGoZe267LUQqvjxMzKyK # BJPGV4agczYrgZf6G5t+iIfYUnmJ/m53N9e7UJ/6GCVPE/JefKmxIFopq6NCh3fg # 9EwCSN1YpVOmo6DtGZZlFSnF7TMwJeaWg4Ga9mBmkFgHgM1Cdaz7tJHQxd0BQGq2 # qBDu9o16t551r9OlSxihDJ9XsF4lR5F0zXUS0Zxv5F4Nm+x1Ju7+0/WSL1KF6NpE # USqizADKh2ZDoxsA76K1lp1irScL8htKycOUQjeIIISoh67DuiNye/hU7/hrJ7CF # 9adDhdgrOXTbWncC0aT69c2cPcwfrlHQe2zYHS0RQlNxdMLlNaotUhLZJc/w09CR # QxLXMn2YbON3Qcj/HyRU726txj5Ve/Fchzpk8WBLBU/vuS/sCRMCAwEAAaOCAYIw # ggF+MB8GA1UdIwQYMBaAFBqh+GEZIA/DQXdFKI7RNV8GEgRVMB0GA1UdDgQWBBQD # DzHIkSqTvWPz0V1NpDQP0pUBGDAOBgNVHQ8BAf8EBAMCBsAwDAYDVR0TAQH/BAIw # ADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDBKBgNVHSAEQzBBMDUGDCsGAQQBsjEB # AgEDCDAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3RpZ28uY29tL0NQUzAIBgZn # gQwBBAIwRAYDVR0fBD0wOzA5oDegNYYzaHR0cDovL2NybC5zZWN0aWdvLmNvbS9T # ZWN0aWdvUlNBVGltZVN0YW1waW5nQ0EuY3JsMHQGCCsGAQUFBwEBBGgwZjA/Bggr # BgEFBQcwAoYzaHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvUlNBVGltZVN0 # YW1waW5nQ0EuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdvLmNv # bTANBgkqhkiG9w0BAQwFAAOCAgEATJtlWPrgec/vFcMybd4zket3WOLrvctKPHXe # fpRtwyLHBJXfZWlhEwz2DJ71iSBewYfHAyTKx6XwJt/4+DFlDeDrbVFXpoyEUghG # HCrC3vLaikXzvvf2LsR+7fjtaL96VkjpYeWaOXe8vrqRZIh1/12FFjQn0inL/+0t # 2v++kwzsbaINzMPxbr0hkRojAFKtl9RieCqEeajXPawhj3DDJHk6l/ENo6NbU9ir # ALpY+zWAT18ocWwZXsKDcpCu4MbY8pn76rSSZXwHfDVEHa1YGGti+95sxAqpbNMh # RnDcL411TCPCQdB6ljvDS93NkiZ0dlw3oJoknk5fTtOPD+UTT1lEZUtDZM9I+Gdn # uU2/zA2xOjDQoT1IrXpl5Ozf4AHwsypKOazBpPmpfTXQMkCgsRkqGCGyyH0FcRpL # Jzaq4Jgcg3Xnx35LhEPNQ/uQl3YqEqxAwXBbmQpA+oBtlGF7yG65yGdnJFxQjQEg # 3gf3AdT4LhHNnYPl+MolHEQ9J+WwhkcqCxuEdn17aE+Nt/cTtO2gLe5zD9kQup2Z # LHzXdR+PEMSU5n4k5ZVKiIwn1oVmHfmuZHaR6Ej+yFUK7SnDH944psAU+zI9+KmD # YjbIw74Ahxyr+kpCHIkD3PVcfHDZXXhO7p9eIOYJanwrCKNI9RX8BE/fzSEceuX1 # jhrUuUAxggWTMIIFjwIBATCBkTB8MQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl # YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRgwFgYDVQQKEw9TZWN0 # aWdvIExpbWl0ZWQxJDAiBgNVBAMTG1NlY3RpZ28gUlNBIENvZGUgU2lnbmluZyBD # QQIRAI8ql/xeLmzwWijNkBrZWykwDQYJYIZIAWUDBAIBBQCggYQwGAYKKwYBBAGC # NwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgoiJ0AkrH # G2JxX58oUA/Uoy335BhroboepLo6K0sf6HkwDQYJKoZIhvcNAQEBBQAEggEAI1j0 # 5oYloMfI9NSFzZVCw94wMHFLG42Q6woOne13kARXQFo9q4tNRiyD36gO8042++hy # Oixjji4EL8A/4EDKi6R1rMx9Aa2yAXUFBbyQ2ab35krMtIYWd3sssevv0TcXUMU8 # mmd3hXs0X3goMrtPzDUHvsRS4HVLbYYaSPjjdeMS6YBz0TblVFtWmBFS2Q8KxLvo # RBsAAMK7n5gCAHpjbUSuhrVzTFN/CemCyiV+toA8IjRk4d3Uh9EtMUGqrClhGJct # MKIltP/7cnHZi7P9bk2rFnG4BSVXCwiu6/Kka/tE+xyq3A4kKmOBBvfTwD3zj1YX # sN5xH6jbTKHbBvlPFqGCA0swggNHBgkqhkiG9w0BCQYxggM4MIIDNAIBATCBkTB9 # MQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYD # VQQHEwdTYWxmb3JkMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxJTAjBgNVBAMT # HFNlY3RpZ28gUlNBIFRpbWUgU3RhbXBpbmcgQ0ECEDlMJeF8oG0nqGXiO9kdItQw # DQYJYIZIAWUDBAICBQCgeTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqG # SIb3DQEJBTEPFw0yMzA1MzAxMTI3MzFaMD8GCSqGSIb3DQEJBDEyBDD+Q42zMrvW # RDOhtxe/4qYzqdZNaZ1LlzxmmbhcbHIoWcv+69h905X+Xnvn9ax4EmwwDQYJKoZI # hvcNAQEBBQAEggIAi2rPHNoEa6JcnngGCjJxGDrlvdMpqMlaL04wE+ATW+U87csE # 2H4IYD2oDBo2YUL4QzUKJ6fZmYuiR3q7j9p2W5zhj9Lh7LkAgBfcygY1uytqJAdU # z87lj6EnqOyhQUK87MFWwaDKf+LtID+ypO03BwDjh0wr7zOG+4V3gGVJ2cq2QfX/ # 00UXecNb8dNXNTK/syf97tHqHI2mbRLvZwgXM8Yj5RL8QC3RSi1acgNQB3eesX4k # DFqSo1M2jLYAI0uvMjJGwBFSDZqIn3ga0HSD8zPM9MzTx/0YJsfMtjVe69+zlaay # DquMHeVjuDoiG3gjkEUwx9pJ11KqXjZ644uv6MKdxUlnuKBRAWdq+fxrK5kBo0Dt # PIfaKxILhDE5MtCABSx/Qtmj0cRPH1ufVr/cCJWRU+rYvEovmos8OXHj41dreVg2 # csAtHyZAWXRZwvLUN/XvDdxNicApzTGWA3EThlPlyilh4s/3Fw6yLNwdfK3GuaXu # E0UcsDA+Xj8ygIwpReKZJTIFKmGNIGosa3xI6/IUn10O3dB2ivpVWzirPvInFmOz # 8LkhFVy2nqWpN47fwLsAH3UWC49Fs0jS5S48KMwaiD0XFOoevlYWMnrDOX4P9VhI # 60KSyn8TS3jiPFtcz4qS+ssGAkopaVTSsmRp1IA/H3nVbBVS1XsVKbQuIqA= # SIG # End signature block |