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. .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("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 { # 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 } Try { # https://docs.microsoft.com/en-us/windows/win32/api/certcli/nf-certcli-icertrequest-submit $Status = $CertRequest.Submit( $RequestFlags.CR_IN_ENCODEANY, $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 # MIIk6gYJKoZIhvcNAQcCoIIk2zCCJNcCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCxYoNfSbQwxZ0k # Ksm1EI40oRmJ1ODv/+OJxjXJHSAz2qCCHqwwggVAMIIEKKADAgECAhEAjyqX/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+QrJVF3UuWp0nr1Irpgwggb2 # MIIE3qADAgECAhEAkDl/mtJKOhPyvZFfCDipQzANBgkqhkiG9w0BAQwFADB9MQsw # CQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQH # EwdTYWxmb3JkMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxJTAjBgNVBAMTHFNl # Y3RpZ28gUlNBIFRpbWUgU3RhbXBpbmcgQ0EwHhcNMjIwNTExMDAwMDAwWhcNMzMw # ODEwMjM1OTU5WjBqMQswCQYDVQQGEwJHQjETMBEGA1UECBMKTWFuY2hlc3RlcjEY # MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSwwKgYDVQQDDCNTZWN0aWdvIFJTQSBU # aW1lIFN0YW1waW5nIFNpZ25lciAjMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC # AgoCggIBAJCycT954dS5ihfMw5fCkJRy7Vo6bwFDf3NaKJ8kfKA1QAb6lK8KoYO2 # E+RLFQZeaoogNHF7uyWtP1sKpB8vbH0uYVHQjFk3PqZd8R5dgLbYH2DjzRJqiB/G # /hjLk0NWesfOA9YAZChWIrFLGdLwlslEHzldnLCW7VpJjX5y5ENrf8mgP2xKrdUA # T70KuIPFvZgsB3YBcEXew/BCaer/JswDRB8WKOFqdLacRfq2Os6U0R+9jGWq/fzD # POgNnDhm1fx9HptZjJFaQldVUBYNS3Ry7qAqMfwmAjT5ZBtZ/eM61Oi4QSl0AT8N # 4BN3KxE8+z3N0Ofhl1tV9yoDbdXNYtrOnB786nB95n1LaM5aKWHToFwls6UnaKNY # /fUta8pfZMdrKAzarHhB3pLvD8Xsq98tbxpUUWwzs41ZYOff6Bcio3lBYs/8e/OS # 2q7gPE8PWsxu3x+8Iq+3OBCaNKcL//4dXqTz7hY4Kz+sdpRBnWQd+oD9AOH++DrU # w167aU1ymeXxMi1R+mGtTeomjm38qUiYPvJGDWmxt270BdtBBcYYwFDk+K3+rGNh # R5G8RrVGU2zF9OGGJ5OEOWx14B0MelmLLsv0ZCxCR/RUWIU35cdpp9Ili5a/xq3g # vbE39x/fQnuq6xzp6z1a3fjSkNVJmjodgxpXfxwBws4cfcz7lhXFAgMBAAGjggGC # MIIBfjAfBgNVHSMEGDAWgBQaofhhGSAPw0F3RSiO0TVfBhIEVTAdBgNVHQ4EFgQU # JS5oPGuaKyQUqR+i3yY6zxSm8eAwDgYDVR0PAQH/BAQDAgbAMAwGA1UdEwEB/wQC # MAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwSgYDVR0gBEMwQTA1BgwrBgEEAbIx # AQIBAwgwJTAjBggrBgEFBQcCARYXaHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwCAYG # Z4EMAQQCMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwuc2VjdGlnby5jb20v # U2VjdGlnb1JTQVRpbWVTdGFtcGluZ0NBLmNybDB0BggrBgEFBQcBAQRoMGYwPwYI # KwYBBQUHMAKGM2h0dHA6Ly9jcnQuc2VjdGlnby5jb20vU2VjdGlnb1JTQVRpbWVT # dGFtcGluZ0NBLmNydDAjBggrBgEFBQcwAYYXaHR0cDovL29jc3Auc2VjdGlnby5j # b20wDQYJKoZIhvcNAQEMBQADggIBAHPa7Whyy8K5QKExu7QDoy0UeyTntFsVfajp # /a3Rkg18PTagadnzmjDarGnWdFckP34PPNn1w3klbCbojWiTzvF3iTl/qAQF2jTD # FOqfCFSr/8R+lmwr05TrtGzgRU0ssvc7O1q1wfvXiXVtmHJy9vcHKPPTstDrGb4V # LHjvzUWgAOT4BHa7V8WQvndUkHSeC09NxKoTj5evATUry5sReOny+YkEPE7jghJi # 67REDHVBwg80uIidyCLxE2rbGC9ueK3EBbTohAiTB/l9g/5omDTkd+WxzoyUbNsD # bSgFR36bLvBk+9ukAzEQfBr7PBmA0QtwuVVfR745ZM632iNUMuNGsjLY0imGyRVd # gJWvAvu00S6dOHw14A8c7RtHSJwialWC2fK6CGUD5fEp80iKCQFMpnnyorYamZTr # lyjhvn0boXztVoCm9CIzkOSEU/wq+sCnl6jqtY16zuTgS6Ezqwt2oNVpFreOZr9f # +h/EqH+noUgUkQ2C/L1Nme3J5mw2/ndDmbhpLXxhL+2jsEn+W75pJJH/k/xXaZJL # 2QU/bYZy06LQwGTSOkLBGgP70O2aIbg/r6ayUVTVTMXKHxKNV8Y57Vz/7J8mdq1k # ZmfoqjDg0q23fbFqQSduA4qjdOCKCYJuv+P2t7yeCykYaIGhnD9uFllLFAkJmuau # v2AV3Yb1MYIFlDCCBZACAQEwgZEwfDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy # ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2Vj # dGlnbyBMaW1pdGVkMSQwIgYDVQQDExtTZWN0aWdvIFJTQSBDb2RlIFNpZ25pbmcg # Q0ECEQCPKpf8Xi5s8FoozZAa2VspMA0GCWCGSAFlAwQCAQUAoIGEMBgGCisGAQQB # gjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYK # KwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIA3ZdF2Q # 51+dzBOMSodPQC1hdvWjEVNgP66TyoRZG3JEMA0GCSqGSIb3DQEBAQUABIIBAJSN # 4qJwcm5Co/rnWbBQhdrWdsvN7mivOGxnXGswG2K33UwvkFh/EaaJ3/v6cSmpMHYx # cje+XMBIch/0L7se+B+iGBsuiywJ7go+2rGHLfB7aNPqCG4Ac8wdxinDepS1E14C # JYHpozfy7KhbOxXPrc+/NXKal8dHSCmabR/anzL7kN0eOulRbXbCGoqfWoInf2iy # PRNwDvKLZeEo6Zg5GFm5X5mdE6eSZikrnLAeb2iwKEuY02oKWB8OqgFiCxejmdn8 # dzRaoCDZSn3QstNb1BwwAjmoVuUg5uOjFs7n9mC/Smu3rrNfb3IHyHOUvkwJMf1r # ijaMQfI2ZBpnqffxdaChggNMMIIDSAYJKoZIhvcNAQkGMYIDOTCCAzUCAQEwgZIw # fTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G # A1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSUwIwYDVQQD # ExxTZWN0aWdvIFJTQSBUaW1lIFN0YW1waW5nIENBAhEAkDl/mtJKOhPyvZFfCDip # QzANBglghkgBZQMEAgIFAKB5MBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJ # KoZIhvcNAQkFMQ8XDTIyMTIxMzE5MDE0NlowPwYJKoZIhvcNAQkEMTIEMEDCxLRW # 6FC/SF+axdkd7rBdnEvC0vjBjJeTqrfIhzjOyYShW+UUmSJQ690tp/xs7DANBgkq # hkiG9w0BAQEFAASCAgAUvohi6+aNbr1pROWgdAOdyf9QG6ZfbFUWz/NR6dcy6hk/ # 4hjnEn7fCbgw3bY22+XdIMpr0w3+BhnysSMSXTi+BCFkg1QGN19zm45Tu40kJnyR # L+LU/r6eUvBZMMAg23Ae1BlgGvNqAfD2WmvjzYpZN0HnXCFlHssf/tmQ55dbE2ta # xCCqkz+UcDDKqXUOLWlOFPIo8LjXtbYqWIAnX+uh3FgybcJ2Ik4mMF24DrysL2Cd # 6IbF1ICIofq49JCVxUHxuNOT86uYSkaac03nA4dGfzuj6oaHyaTzHirwJueYJ4hS # q3GBFlhzBTc+lS8DNLuyfeLQonVvtSI+lsjN0jUEQ58iqJmeAZzBaC9Ze4lNeH87 # lriKsWKuPAqtziIaHo+mbYHh2FUlEP5q4MJR+BS7j0ThB0QuJItiJKMgmz6vi36P # 1qE+k4zZjYh/5m/tyAdwesicjf8oEp++sgGMVVIOpIR9YkL+pkMkvfedd2Jya0YC # /VRJ1vkY86mKfrau+Zx2sOPg79daIYCAKgWsGXb8lldVeLT1KG4E7+YpANzU26zu # ODOJASXN9XIEPfWmAQ9v5KvbFxuW65ai2cV3JTYNE45SIyQ6J4uG+NnHZMnq0POG # GCoprIpjHEzIHFIJgnjDjkunpzqmpEUMvkXkz8HNpYXkRd1xM1371HeXmGopzA== # SIG # End signature block |