Private/Add-ADFSTkSPRelyingPartyTrust.ps1
function Add-ADFSTkSPRelyingPartyTrust { param ( [Parameter(Mandatory = $true, Position = 0)] $sp ) $Continue = $true ### EntityId $entityID = $sp.entityID $rpParams = @{ Identifier = $sp.entityID EncryptionCertificateRevocationCheck = 'None' SigningCertificateRevocationCheck = 'None' ClaimsProviderName = @("Active Directory") ErrorAction = 'Stop' SignatureAlgorithm = Get-ADFSTkSecureHashAlgorithm -EntityId $entityID -CertificateSignatureAlgorithm $SigningCertificate.SignatureAlgorithm.Value SamlResponseSignature = Get-ADFSTkSamlResponseSignature -EntityId $entityID } Write-ADFSTkLog (Get-ADFSTkLanguageText addRPAddingRP -f $entityId) -EntryType Information -EventID 41 ### Name, DisplayName $Name = (Split-Path $sp.entityID -NoQualifier).TrimStart('/') -split '/' | select -First 1 #region Token Encryption Certificate Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPGettingEncryptionert) $CertificateString = ($sp.SPSSODescriptor.KeyDescriptor | ? use -eq "encryption" | select -ExpandProperty KeyInfo).X509Data.X509Certificate if ($CertificateString -eq $null) { #Check if any certificates without 'use'. Should we use this? Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPEncryptionCertNotFound) $CertificateString = ($sp.SPSSODescriptor.KeyDescriptor | ? use -ne "signing" | select -ExpandProperty KeyInfo).X509Data.X509Certificate #or shoud 'use' not be present? } if ($CertificateString -ne $null) { $rpParams.EncryptionCertificate = $null try { #May be more certificates! #If more than one, choose the one with furthest end date. $CertificateString | % { Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPConvertingEncrytionCert) $EncryptionCertificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $CertificateBytes = [system.Text.Encoding]::UTF8.GetBytes($_) $EncryptionCertificate.Import($CertificateBytes) if ($rpParams.EncryptionCertificate -eq $null) { $rpParams.EncryptionCertificate = $EncryptionCertificate } elseif ($rpParams.EncryptionCertificate.NotAfter -lt $EncryptionCertificate.NotAfter) { $rpParams.EncryptionCertificate = $EncryptionCertificate } Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPConvertionEncryptionCertDone) } if ($CertificateString -is [Object[]]) { #Just for logging! Write-ADFSTkLog (Get-ADFSTkLanguageText addRPMultipleEncryptionCertsFound -f $EncryptionCertificate.Thumbprint) -EntryType Warning -EventID 30 } } catch { Write-ADFSTkLog (Get-ADFSTkLanguageText addRPCouldNotImportEncrytionCert) -EntryType Error -EventID 21 $Continue = $false } } #endregion #region Token Signing Certificate #Add all signing certificates if there are more than one Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPGetSigningCert) #$rpParams.SignatureAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1" $CertificateString = ($sp.SPSSODescriptor.KeyDescriptor | ? use -eq "signing" | select -ExpandProperty KeyInfo).X509Data.X509Certificate if ($CertificateString -eq $null) { Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPSigningCertNotFound) $CertificateString = ($sp.SPSSODescriptor.KeyDescriptor | ? use -ne "encryption" | select -ExpandProperty KeyInfo).X509Data.X509Certificate #or shoud 'use' not be present? } if ($CertificateString -ne $null) { #foreach insted create $SigningCertificates array try { $rpParams.RequestSigningCertificate = @() $CertificateString | % { Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPConvertingSigningCert) $CertificateBytes = [system.Text.Encoding]::UTF8.GetBytes($_) $SigningCertificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $SigningCertificate.Import($CertificateBytes) $rpParams.RequestSigningCertificate += $SigningCertificate #if ($SigningCertificate.SignatureAlgorithm.Value -eq '1.2.840.113549.1.1.11') #Check if Signature Algorithm is SHA256 #{ # $rpParams.SignatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" #} } Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPConvertionSigningCertDone) } catch { Write-ADFSTkLog (Get-ADFSTkLanguageText addRPCouldNotImportSigningCert) -EntryType Error -EventID 22 $Continue = $false } } #endregion #region Get SamlEndpoints Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPGetSamlEndpoints) $rpParams.SamlEndpoint = @() $rpParams.SamlEndpoint += $sp.SPSSODescriptor.AssertionConsumerService | % { if ($_.Binding -eq "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST") { Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPHTTPPostFound) New-ADFSSamlEndpoint -Binding POST -Protocol SAMLAssertionConsumer -Uri $_.Location -Index $_.index } elseif ($_.Binding -eq "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact") { Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPHTTPArtifactFound) New-ADFSSamlEndpoint -Binding Artifact -Protocol SAMLAssertionConsumer -Uri $_.Location -Index $_.index } elseif ($_.Binding -eq "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect") { Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPHTTPRedirectFound) New-ADFSSamlEndpoint -Binding Redirect -Protocol SAMLAssertionConsumer -Uri $_.Location -Index $_.index } else { Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPUnhandledEndpointFound -f $_.Binding, $entityID) } } if ($rpParams.SamlEndpoint.Count -eq 0) { Write-ADFSTkLog (Get-ADFSTkLanguageText addRPNoSamlEndpointsFound) -EntryType Error -EventID 23 $Continue = $false } #endregion #region Get LogoutEndpoints Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPGetLogoutEndpoints) $rpParams.SamlEndpoint += $sp.SPSSODescriptor.SingleLogoutService | % { if ($_.Binding -eq "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST") { Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPLogoutPostFound) New-ADFSSamlEndpoint -Binding POST -Protocol SAMLLogout -ResponseUri $_.Location -Uri ("https://{0}/adfs/ls/?wa=wsignout1.0" -f $Settings.configuration.staticValues.ADFSExternalDNS) } elseif ($_.Binding -eq "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect") { Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPLogoutRedirectFound) New-ADFSSamlEndpoint -Binding Redirect -Protocol SAMLLogout -ResponseUri $_.Location -Uri ("https://{0}/adfs/ls/?wa=wsignout1.0" -f $Settings.configuration.staticValues.ADFSExternalDNS) } } #endregion #region Get Issuance Transform Rules from Entity Categories Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPGetEntityCategories) $EntityCategories = @() $EntityCategories += $sp.Extensions.EntityAttributes.Attribute | ? Name -eq "http://macedir.org/entity-category" | select -ExpandProperty AttributeValue | % { if ($_ -is [string]) { $_ } elseif ($_ -is [System.Xml.XmlElement]) { $_."#text" } } Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPFollowingECFound -f ($EntityCategories -join ',')) if ($ForcedEntityCategories) { $EntityCategories += $ForcedEntityCategories Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPAddedForcedEC -f ($ForcedEntityCategories -join ',')) } $rpParams.IssuanceTransformRules = Get-ADFSTkIssuanceTransformRules $EntityCategories -EntityId $entityID ` -RequestedAttribute $sp.SPSSODescriptor.AttributeConsumingService.RequestedAttribute ` -RegistrationAuthority $sp.Extensions.RegistrationInfo.registrationAuthority ` -NameIdFormat $sp.SPSSODescriptor.NameIDFormat #endregion #region Add MFA Access Policy and extra rules if needed $mfaRules = Get-ADFSTkMFAConfiguration -EntityId $entityID if ([string]::IsNullOrEmpty($mfaRules)) { $rpParams.IssuanceAuthorizationRules = Get-ADFSTkIssuanceAuthorizationRules -EntityId $entityID } else { $rpParams.AccessControlPolicyName = 'ADFSTk:Permit everyone and force MFA' $rpParams.IssuanceTransformRules += $mfaRules } #endregion if ((Get-ADFSRelyingPartyTrust -Identifier $entityID) -eq $null) { $NamePrefix = $Settings.configuration.MetadataPrefix $Sep = $Settings.configuration.MetadataPrefixSeparator $NameWithPrefix = "$NamePrefix$Sep$Name" if ((Get-ADFSRelyingPartyTrust -Name $NameWithPrefix) -ne $null) { $n = 1 Do { $n++ $NameWithPrefix = "$NamePrefix$Sep$Name ($n)" } Until ((Get-ADFSRelyingPartyTrust -Name $NameWithPrefix) -eq $null) Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPRPAlreadyExistsChangingNameTo -f $NameWithPrefix) } $rpParams.Name = $NameWithPrefix if ($Continue) { try { Write-ADFSTkVerboseLog (Get-ADFSTkLanguageText addRPAddingRP -f $entityID) # Invoking the following command leverages 'splatting' for passing the switches for commands # for details, see: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_splatting?view=powershell-6 # (that's what it's @rpParams and not $rpParams) Add-ADFSRelyingPartyTrust @rpParams Write-ADFSTkLog (Get-ADFSTkLanguageText addRPSuccefullyAddedRP -f $entityId) -EntryType Information -EventID 42 Add-ADFSTkEntityHash -EntityID $entityId } catch { Write-ADFSTkLog (Get-ADFSTkLanguageText addRPCouldNotAddRP -f $entityId, $_) -EntryType Error -EventID 24 Add-ADFSTkEntityHash -EntityID $entityId } } else { #There were some error with certificate or endpoints with this SP. Let's only try again if it changes... Add-ADFSTkEntityHash -EntityID $entityId } } else { Write-ADFSTkLog (Get-ADFSTkLanguageText addRPRPAlreadyExists -f $entityId) -EntryType Warning -EventID 25 } } # SIG # Begin signature block # MIId/gYJKoZIhvcNAQcCoIId7zCCHesCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCD2Cb79qcxZMrUi # lQf/yEzVZsS1IVtbbVZFAaYJxjVkZKCCGKwwggR9MIIDZaADAgECAgMb5xUwDQYJ # KoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRk # eSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3MgMiBDZXJ0aWZp # Y2F0aW9uIEF1dGhvcml0eTAeFw0xNDAxMDEwNzAwMDBaFw0zMTA1MzAwNzAwMDBa # MIGDMQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2Nv # dHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5jb20sIEluYy4xMTAvBgNVBAMTKEdv # IERhZGR5IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqG # SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/cWII8fpZNPcbyRij94BJWOkigxOmxSBD # ATuE8eaFSZ8n6vaEG06gtNtwmMcyAbEFPgdO7vT6Ty9ZMCLnqxlWa+KAB/zzFnWA # OVF75fk1tnROqY2CE+S2P6kDg/qivooVan/eC8O2GRQFyurDqASUO0Z8Mg3zAGYi # yI1pbTaMERi307IcYLQ4+gKMztPdRgfeCj7rXXzIfPuwK1OkkmJpUSUFYRpEgYws # qUOWI9+sOoGaDinFHKnpXR62np4wCjnO8YiA+0tdzDLshWJDJTQCVicBkbQ7cCo/ # brHonIgBfZ/U+dtTbWCdvyznWKu4X0b8zsQbAzwJ60kxXGlGs+BHAgMBAAGjggEX # MIIBEzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU # OpqFBxBnKLbv9r0FQW4gwZTaD94wHwYDVR0jBBgwFoAU0sSw0pHUTBFxs2HLPaH+ # 3ahq1OMwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5n # b2RhZGR5LmNvbS8wMgYDVR0fBCswKTAnoCWgI4YhaHR0cDovL2NybC5nb2RhZGR5 # LmNvbS9nZHJvb3QuY3JsMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEGCCsGAQUFBwIB # FiVodHRwczovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMA0GCSqGSIb3 # DQEBCwUAA4IBAQBZC1O9koYRpyR77Vsxzx0fbHDFuG6+Trv2vpdQ4TB/uihcYpTC # 434z9/tCdoXblRyMIlh1CQyIZWc5ChYJxaA4l6TFI5M/tBimAQZEkeOnaSe0WiV/ # Orcyzd2E/yo4KTOk3Weyhf6hiCAcUInI3Cr2QgM3TOaI39WvJPKxw9/MtezgmV63 # SVQgPJQYDMccUhhJpG3hs1gLydjs2a4cMo4ocA3i/qYXnoQPvVdws1rpH6CGU7vv # fP9pC+BIw7eTC8gKVMSsXRRnN2zKpS8xCDeqbm+MvJviV10kga+Xl5yErWysN0xm # 82GRESDkvjCfeqQpCbDhNF9kdxhAUd+MMKavMIIE0DCCA7igAwIBAgIBBzANBgkq # hkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzAR # BgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTEw # LwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcy # MB4XDTExMDUwMzA3MDAwMFoXDTMxMDUwMzA3MDAwMFowgbQxCzAJBgNVBAYTAlVT # MRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQK # ExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UECxMkaHR0cDovL2NlcnRzLmdvZGFk # ZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQDEypHbyBEYWRkeSBTZWN1cmUgQ2Vy # dGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw # ggEKAoIBAQC54MsQ1K92vdSTYuswZLiBCGzDBNliF44v/z5lz4/OYuY8UhzaFkVL # Vat4a2ODYpDOD2lsmcgaFItMzEUz6ojcnqOvK/6AYZ15V8TPLvQ/MDxdR/yaFrzD # N5ZBUY4RS1T4KL7QjL7wMDge87Am+GZHY23ecSZHjzhHU9FGHbTj3ADqRay9vHHZ # qm8A29vNMDp5T19MR/gd71vCxJ1gO7GyQ5HYpDNO6rPWJ0+tJYqlxvTV0KaudAVk # V4i1RFXULSo6Pvi4vekyCgKUZMQWOlDxSq7neTOvDCAHf+jfBDnCaQJsY1L6d8Eb # yHSHyLmTGFBUNUtpTrw700kuH9zB0lL7AgMBAAGjggEaMIIBFjAPBgNVHRMBAf8E # BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUQMK9J47MNIMwojPX+2yz # 8LQsgM4wHwYDVR0jBBgwFoAUOpqFBxBnKLbv9r0FQW4gwZTaD94wNAYIKwYBBQUH # AQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5nb2RhZGR5LmNvbS8wNQYD # VR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5nb2RhZGR5LmNvbS9nZHJvb3QtZzIu # Y3JsMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEGCCsGAQUFBwIBFiVodHRwczovL2Nl # cnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMA0GCSqGSIb3DQEBCwUAA4IBAQAI # fmyTEMg4uJapkEv/oV9PBO9sPpyIBslQj6Zz91cxG7685C/b+LrTW+C05+Z5Yg4M # otdqY3MxtfWoSKQ7CC2iXZDXtHwlTxFWMMS2RJ17LJ3lXubvDGGqv+QqG+6EnriD # fcFDzkSnE3ANkR/0yBOtg2DZ2HKocyQetawiDsoXiWJYRBuriSUBAA/NxBti21G0 # 0w9RKpv0vHP8ds42pM3Z2Czqrpv1KrKQ0U11GIo/ikGQI31bS/6kA1ibRrLDYGCD # +H1QQc7CoZDDu+8CL9IVVO5EFdkKrqeKM+2xLXY2JtwE65/3YR8V3Idv7kaWKK2h # Jn0KCacuBKONvPi8BDABMIIE/jCCA+agAwIBAgIQDUJK4L46iP9gQCHOFADw3TAN # BgkqhkiG9w0BAQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQg # SW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2Vy # dCBTSEEyIEFzc3VyZWQgSUQgVGltZXN0YW1waW5nIENBMB4XDTIxMDEwMTAwMDAw # MFoXDTMxMDEwNjAwMDAwMFowSDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lD # ZXJ0LCBJbmMuMSAwHgYDVQQDExdEaWdpQ2VydCBUaW1lc3RhbXAgMjAyMTCCASIw # DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMLmYYRnxYr1DQikRcpja1HXOhFC # vQp1dU2UtAxQtSYQ/h3Ib5FrDJbnGlxI70Tlv5thzRWRYlq4/2cLnGP9NmqB+in4 # 3Stwhd4CGPN4bbx9+cdtCT2+anaH6Yq9+IRdHnbJ5MZ2djpT0dHTWjaPxqPhLxs6 # t2HWc+xObTOKfF1FLUuxUOZBOjdWhtyTI433UCXoZObd048vV7WHIOsOjizVI9r0 # TXhG4wODMSlKXAwxikqMiMX3MFr5FK8VX2xDSQn9JiNT9o1j6BqrW7EdMMKbaYK0 # 2/xWVLwfoYervnpbCiAvSwnJlaeNsvrWY4tOpXIc7p96AXP4Gdb+DUmEvQECAwEA # AaOCAbgwggG0MA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB # /wQMMAoGCCsGAQUFBwMIMEEGA1UdIAQ6MDgwNgYJYIZIAYb9bAcBMCkwJwYIKwYB # BQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAfBgNVHSMEGDAWgBT0 # tuEgHf4prtLkYaWyoiWyyBc1bjAdBgNVHQ4EFgQUNkSGjqS6sGa+vCgtHUQ23eNq # erwwcQYDVR0fBGowaDAyoDCgLoYsaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3No # YTItYXNzdXJlZC10cy5jcmwwMqAwoC6GLGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNv # bS9zaGEyLWFzc3VyZWQtdHMuY3JsMIGFBggrBgEFBQcBAQR5MHcwJAYIKwYBBQUH # MAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBPBggrBgEFBQcwAoZDaHR0cDov # L2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRFRpbWVz # dGFtcGluZ0NBLmNydDANBgkqhkiG9w0BAQsFAAOCAQEASBzctemaI7znGucgDo5n # Rv1CclF0CiNHo6uS0iXEcFm+FKDlJ4GlTRQVGQd58NEEw4bZO73+RAJmTe1ppA/2 # uHDPYuj1UUp4eTZ6J7fz51Kfk6ftQ55757TdQSKJ+4eiRgNO/PT+t2R3Y18jUmmD # gvoaU+2QzI2hF3MN9PNlOXBL85zWenvaDLw9MtAby/Vh/HUIAHa8gQ74wOFcz8QR # cucbZEnYIpp1FUL1LTI4gdr0YKK6tFL7XOBhJCVPst/JKahzQ1HavWPWH1ub9y4b # TxMd90oNcX6Xt/Q/hOvB46NJofrOp79Wz7pZdmGJX36ntI5nePk2mOHLKNpbh6aK # LzCCBRwwggQEoAMCAQICCGXB0JJJvDvXMA0GCSqGSIb3DQEBCwUAMIG0MQswCQYD # VQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEa # MBgGA1UEChMRR29EYWRkeS5jb20sIEluYy4xLTArBgNVBAsTJGh0dHA6Ly9jZXJ0 # cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzEzMDEGA1UEAxMqR28gRGFkZHkgU2Vj # dXJlIENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTIxMDExOTE4MzczNloX # DTIyMDMwODE4NTgwMFowXjELMAkGA1UEBhMCQ0ExEDAOBgNVBAgTB09udGFyaW8x # DzANBgNVBAcTBk90dGF3YTEVMBMGA1UEChMMQ0FOQVJJRSBJbmMuMRUwEwYDVQQD # EwxDQU5BUklFIEluYy4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ # hfCjFqiTmN1uLoySixnwaOjf/ZAL9P6SvjlCaBA2mutoorEgnzUP8HnOIcvMRgEM # PmpaZ8egM93Bmx9d41xoarsQpCN3DhYOo+b3fWnPucVtpxbul2OFePv63mw/uvr+ # dqkv4b/f3Tg+ilQbpsNonbvh9MKEFv8Pn9koj0ySV+qxz34PxTVAe6g//pel3/3i # 9fqilCnIEcx4zg/+NKBeOWROSs4oXo3IvBjVrunmz+YuieSr78TqIE6hD8JF2q1w # KwfMB3+x7dEXZAus9WtIU/qITATtEfO9QAgrrYL4F1MLN+osSp8my5eCOjnLTQc4 # 7q574V3zQhsIHW7yBXLdAgMBAAGjggGFMIIBgTAMBgNVHRMBAf8EAjAAMBMGA1Ud # JQQMMAoGCCsGAQUFBwMDMA4GA1UdDwEB/wQEAwIHgDA1BgNVHR8ELjAsMCqgKKAm # hiRodHRwOi8vY3JsLmdvZGFkZHkuY29tL2dkaWcyczUtNi5jcmwwXQYDVR0gBFYw # VDBIBgtghkgBhv1tAQcXAjA5MDcGCCsGAQUFBwIBFitodHRwOi8vY2VydGlmaWNh # dGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMAgGBmeBDAEEATB2BggrBgEFBQcB # AQRqMGgwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmdvZGFkZHkuY29tLzBABggr # BgEFBQcwAoY0aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0 # b3J5L2dkaWcyLmNydDAfBgNVHSMEGDAWgBRAwr0njsw0gzCiM9f7bLPwtCyAzjAd # BgNVHQ4EFgQUUPnMg2nmYS8l7rmax3weVkrgz5AwDQYJKoZIhvcNAQELBQADggEB # AGabJLu09gdYHt7ZMbpJ4048ZIiXwVLE/HNcnApTghNaHnSSiMI2xTsmbrM/lYsm # pwFuws1c2fMBvyDRgkzR/4+RIjoQJpLrHy1QABYlWAIKMqdFmfqty0QApgIkGN2+ # scMxKMWJGND8qp3KM+5C8TNTsO0gPVfdaarX2TmLM6yIQcgxD8YZMd0mqdR7rcCe # bgMeAdHLYPQu/HM0Cj3qtzFx/CZzz93CAlh8Dx5woqeNJixQMLK28MhU8y6NSN5o # KnD/8EESudRzXyoowZ2N4YJzyye5UL9pxhniDKs444w1r5XcjQYDo11G8Y4up4XW # 1cFtLNulHYcKhAnQ7XHswxMwggUxMIIEGaADAgECAhAKoSXW1jIbfkHkBdo2l8IV # MA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy # dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lD # ZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0xNjAxMDcxMjAwMDBaFw0zMTAxMDcx # MjAwMDBaMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIg # QXNzdXJlZCBJRCBUaW1lc3RhbXBpbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB # DwAwggEKAoIBAQC90DLuS82Pf92puoKZxTlUKFe2I0rEDgdFM1EQfdD5fU1ofue2 # oPSNs4jkl79jIZCYvxO8V9PD4X4I1moUADj3Lh477sym9jJZ/l9lP+Cb6+NGRwYa # VX4LJ37AovWg4N4iPw7/fpX786O6Ij4YrBHk8JkDbTuFfAnT7l3ImgtU46gJcWvg # zyIQD3XPcXJOCq3fQDpct1HhoXkUxk0kIzBdvOw8YGqsLwfM/fDqR9mIUF79Zm5W # YScpiYRR5oLnRlD9lCosp+R1PrqYD4R/nzEU1q3V8mTLex4F0IQZchfxFwbvPc3W # Te8GQv2iUypPhR3EHTyvz9qsEPXdrKzpVv+TAgMBAAGjggHOMIIByjAdBgNVHQ4E # FgQU9LbhIB3+Ka7S5GGlsqIlssgXNW4wHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL # p6chnfNtyA8wEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwEwYD # VR0lBAwwCgYIKwYBBQUHAwgweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhho # dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNl # cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEG # A1UdHwR6MHgwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2Vy # dEFzc3VyZWRJRFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0 # LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwUAYDVR0gBEkwRzA4Bgpg # hkgBhv1sAAIEMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv # bS9DUFMwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4IBAQBxlRLpUYdWac3v # 3dp8qmN6s3jPBjdAhO9LhL/KzwMC/cWnww4gQiyvd/MrHwwhWiq3BTQdaq6Z+Cei # Zr8JqmDfdqQ6kw/4stHYfBli6F6CJR7Euhx7LCHi1lssFDVDBGiy23UC4HLHmNY8 # ZOUfSBAYX4k4YU1iRiSHY4yRUiyvKYnleB/WCxSlgNcSR3CzddWThZN+tpJn+1Nh # iaj1a5bA9FhpDXzIAbG5KHW3mWOFIoxhynmUfln8jA/jb7UBJrZspe6HUSHkWGCb # ugwtK22ixH67xCUrRwIIfEmuE7bhfEJCKMYYVs9BNLZmXbZ0e/VWMyIvIjayS6JK # ldj1po5SMYIEqDCCBKQCAQEwgcEwgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdB # cml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNv # bSwgSW5jLjEtMCsGA1UECxMkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9z # aXRvcnkvMTMwMQYDVQQDEypHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0 # aG9yaXR5IC0gRzICCGXB0JJJvDvXMA0GCWCGSAFlAwQCAQUAoIGEMBgGCisGAQQB # gjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYK # KwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEICXcVdfA # Oa9ogtyILutPyj1rs7xxV3IVvQoGZq98rqH5MA0GCSqGSIb3DQEBAQUABIIBAJjP # pyXd0cLBqIyiWqgjoOU9yQyNrtynPWSF0rLF3WehqBUxWnWNOH8bJ2iV6aQMUKsm # cVMEzS6PHU5UjG9+RYeqwOgwK65iEjWchbY1+hHlS/trWFmmo0/jWEDuhnw7w9JH # 0dEdfi5g/ijnJglX57Ys/mrKc8yBbc2+P2IdTjItioBXGtuqc5HsXyDWoByVb6LS # MJHK7tJyy0yFFXciZY0IhrkLTZq94ebVHwqphQU7xXJ43ABPafsro2MGZAvrkH4+ # FqocbhUXEwi9a7SkazcfVCwUDJ/BL3odgKunq2O89372ADXtbMC+RA35/lzgd8WZ # ThsoZWiRxHd7FsTM/Q2hggIwMIICLAYJKoZIhvcNAQkGMYICHTCCAhkCAQEwgYYw # cjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ # d3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVk # IElEIFRpbWVzdGFtcGluZyBDQQIQDUJK4L46iP9gQCHOFADw3TANBglghkgBZQME # AgEFAKBpMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8X # DTIyMDIwMTIyMTEwMVowLwYJKoZIhvcNAQkEMSIEIKrSbBohiK0mTwy5sIz3JQ3K # +5FDSPMoO+szpTLJtsj7MA0GCSqGSIb3DQEBAQUABIIBAFupoM7CgnidGnHKoVTY # 48gCORpNhh/2s4/tIe/g8gPG4EMwLRFYrGYxnxFpxxTkGvnmWp27iMz9VFNE1UiE # KqDWxJK/Wbg3xl3QB2PUpXkUQG7iGT1ndvFS+BN9mMKFyCslxwreI9Cho9w/rGvl # NWb01tWAmkewuhA8DapMWPt2+thxn3KG/VA/SBuWSNaRnQNgmwAu+GjTtZu5SOx/ # oslyZ+w+rUlWjljuljETC4Wu8rPcRDEZnBC3XFugTbhGslmJKOZQlKH/ZVNOdPFC # lIBdrihqtVbtT0oMU1rxAyFHssdznhjZ+90Bl8soW+8iTWJFnIvtmilP3pBWFJq9 # byA= # SIG # End signature block |