(C) Ondrej Sevecek, 2019 - www.sevecek.com, ondrej@sevecek.com
#$global:outClass = 'main' $libDir = Split-Path -parent $MyInvocation.MyCommand.Definition & "$libDir\lib-common.ps1" -defaultConfig -rootDir $libDir -outFile cawebLib & "$libDir\lib-modifyActions.ps1" & "$libDir\lib-buildup.ps1" $vmName = $args[0] DBG ('CA web services installation library.') Redirect-TempToOutput Load-VMConfig Find-MarkedVolumes $instanceName = $args[1] DBG ('CA web instance to be installed: {0}' -f $instanceName) $appTag = 'caweb' $appConfig = $vmConfig.SelectSingleNode(('./{0}[@instance="{1}"]' -f $appTag, $instanceName)) $firstAppHost = Get-FirstAppHostInInstance $appTag $appConfig.instance 'waitParams' $firstAppHostInInstance = Check-FirstAppHostInInstance $appTag $appConfig.instance #==================== #==================== DBGIF $MyInvocation.MyCommand.Name { $global:thisOSVersionNumber -lt 6.2 } if ($global:thisOSVersionNumber -lt 6.2) { DBG ('Incompatible OS version, exiting') exit } $websvcKind = $appConfig.kind $websvcCACN = $appConfig.cn DBG ('CA web service kind requested: {0} | ca = {1}' -f $websvcKind, $websvcCACN) DBGIF $MyInvocation.MyCommand.Name { Is-EmptyString $websvcKind } [string] $caFQDN = Get-FirstAppHostInInstance 'ca' $websvcCACN 'fqdn' [System.Xml.XmlElement] $caNode = (Get-FirstAppHostInInstance 'ca' $websvcCACN 'vmConfig').ca [string] $caReference = '{0}\{1}' -f $caFQDN, $websvcCACN [System.Collections.ArrayList] $deList = @() $rootDSE = Get-DE 'RootDSE' ([ref] $deList) $configDN = GDES $rootDSE configurationNamingContext $caEnrollmentDN = 'CN={0},CN=Enrollment Services,CN=Public Key Services,CN=Services,{1}' -f $websvcCACN, $configDN DBG ('Will use CA reference: {0}' -f $caReference) DBG ('CA configuration DN: {0}' -f $caEnrollmentDN) Assert-Assembly 'System.Web' if ($websvcKind -eq 'CWE') { DBG ('Going to provision Certificate Web Enrollment (CWE)') Install-WindowsFeaturesUniversal @('ADCS-Web-Enrollment', 'Web-Mgmt-Console', 'Web-Basic-Auth') $false $installMediaVolume $global:installISOVolume $webCert = Enroll-AppCertificate $appConfig.SelectSingleNode('./cert[@appTag="web"]/one') -reuseExisting $true $isCALocal = Contains-Safe $global:thisComputerLocalMachineNames $caFQDN DBG ('Going to configure the web service kind: {0} | {1} | local = {2}' -f $websvcKind, $caReference, $isCALocal) DBGSTART if ($isCALocal) { $installRes = Install-AdcsWebEnrollment -Force -Verbose } else { $installRes = Install-AdcsWebEnrollment -CAConfig $caReference -Force -Verbos } DBGER $MyInvocation.MyCommand.Name $error DBGIF ('Invalid CWE configuration result: {0}' -f $installRes.ErrorId) { $installRes.ErrorId -ne 0 } Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe 'set config "Default Web Site/certsrv" -section:system.webServer/security/authentication/basicAuthentication /enabled:"true" /commit:appHost' Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe 'set config "Default Web Site/certsrv" -section:system.webServer/security/authentication/basicAuthentication /logonMethod:"ClearText" /commit:appHost' Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe 'set config "Default Web Site/certsrv" -section:system.webServer/security/authentication/windowsAuthentication /enabled:"false" /commit:appHost' DBG ('Must bind the SSL certificate manually: {0}' -f $webCert) Ensure-HttpsCertificateBound -ip '0.0.0.0' -port 443 -webCert $webCert } if ($websvcKind -eq 'CEWS') { DBG ('Going to provision Certificate Enrollment Web Service (CEWS)') Install-WindowsFeaturesUniversal @('ADCS-Enroll-Web-Svc', 'Web-Mgmt-Console') $false $installMediaVolume $global:installISOVolume $webCert = Enroll-AppCertificate $appConfig.SelectSingleNode('./cert[@appTag="web"]/one') -reuseExisting $true DBG ('Going to configure the web service kind: {0}' -f $websvcKind) DBGSTART $installRes = Install-AdcsEnrollmentWebService -ApplicationPoolIdentity -CAConfig $caReference -SSLCertThumbprint $webCert -AuthenticationType UserName -Force -Verbose DBGER $MyInvocation.MyCommand.Name $error DBGIF ('Invalid CEWS configuration result: {0}' -f $installRes.ErrorString) { Is-ValidString $installRes.ErrorString } $siteName = '{0}_CES_UsernamePassword' -f $websvcCACN $publicFQDN = $appConfig.publicFQDN $urlMuster = 'https://{0}/{1}/service.svc/CES' $oldUrl = $urlMuster -f $global:thisComputerFQDN, ([Uri]::EscapeDataString($siteName)) $newUrl = $urlMuster -f $publicFQDN, ([Uri]::EscapeDataString($siteName)) DBG ('Some parameters determined: site = {0} | publicFQDN = {1} | old = {2} | new = {3}' -f $siteName, $publicFQDN, $oldUrl, $newUrl) $installDir = Join-Path $env:WINDIR ('SystemData\CES\{0}' -f $siteName) $webConfig = Join-Path $installDir 'web.config' DBGIF ('Installation directory does not exist: {0} | {1}' -f $websvcKind, $installDir) { -not (Test-Path $installDir) } DBGIF ('Web.config does not exist: {0} | {1}' -f $websvcKind, $webConfig) { -not (Test-Path $webConfig) } DBG ('Going to reconfigure CEWS web.config file URI: {0}' -f $newUrl) Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe ('set config "Default Web Site/{0}" -section:appSettings "/-[key=''URI'']"' -f $siteName) Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe ('set config "Default Web Site/{0}" -section:appSettings "/+[key=''URI'',value=''{1}'']"' -f $siteName, $newUrl) DBG ('Going to correct the AD URL value: {0}' -f $caEnrollmentDN) $caEnrollmentDE = Get-DE $caEnrollmentDN ([ref] $deList) [string[]] $existingReferences = $caEnrollmentDE.Properties['msPKI-Enrollment-Servers'].Value DBG ('Existing URL references for the CA CEWS: #{0} | {1}' -f $existingReferences.Length, ($existingReferences -join ' ; ')) DBGIF $MyInvocation.MyCommand.Name { $existingReferences.Length -lt 1 } # Note: the msPKI-Enrollment-Servers format is actually priority-authentication-renewal-URL-unknown [string] $newUrlMuster = "1`n4`n0`n{0}`n0" [Collections.ArrayList] $newReferences = @() [void] $newReferences.Add(($newUrlMuster -f $newUrl)) if ($existingReferences.Length -ge 1) { [bool] $oldUrlHit = $false [string] $oldUrlEntryToCheck = $newUrlMuster -f $oldUrl foreach ($oneExistingReference in $existingReferences) { DBG ('Checking one existing URL CEWS reference: {0} | {1}' -f $oneExistingReference, $oldUrlEntryToCheck) if (($oneExistingReference -eq $oldUrlEntryToCheck) -or (([Uri]::UnescapeDataString($oneExistingReference)) -eq $oldUrlEntryToCheck) -or ($oneExistingReference -eq ([Uri]::UnescapeDataString($oldUrlEntryToCheck)))) { DBG ('This one is the original URL CEWS reference: {0}' -f $oneExistingReference) DBGIF $MyInvocation.MyCommand.Name { $oldUrlHit } $oldUrlHit = $true } else { if ($newReferences -notcontains $oneExistingReference) { [void] $newReferences.Add($oneExistingReference) } } } DBGIF ('The current URL is not present in the CEWS reference list: {0} | seeked = {1}' -f $oldUrl, $oldUrlEntryToCheck) { -not $oldUrlHit } } DBG ('Put the CEWS reference list back into the AD: #{0} | {1}' -f $newReferences.Count, ($newReferences -join ' ; ')) DBGSTART $caEnrollmentDE.PutEx($global:PutExUpdate, 'msPKI-Enrollment-Servers', @($newReferences)) $caEnrollmentDE.SetInfo() DBGER $MyInvocation.MyCommand.Name $error DBGEND } if ($websvcKind -eq 'CEPWS') { DBG ('Going to provision Certificate Enrollment Policy Web Service (CEPWS)') Install-WindowsFeaturesUniversal @('ADCS-Enroll-Web-Pol', 'Web-Mgmt-Console') $false $installMediaVolume $global:installISOVolume $webCert = Enroll-AppCertificate $appConfig.SelectSingleNode('./cert[@appTag="web"]/one') -reuseExisting $true DBG ('CEPWS authentication URL token: {0}' -f $appConfig.auth) DBGIF $MyInvocation.MyCommand.Name { Is-EmptyString $appConfig.auth } switch ($appConfig.auth) { 'UsernamePassword' { $authType = 'Username' } default { $authType = 'Username'; DBGIF ('Weird authentication type specified: {0}' -f $appConfig.auth) { $true } } } DBG ('Going to configure the web service kind: {0} | auth = {1}/{2}' -f $websvcKind, $appConfig.auth, $authType) DBGSTART $installRes = Install-AdcsEnrollmentPolicyWebService -AuthenticationType $authType -SSLCertThumbprint $webCert -Confirm:$false -Force -Verbose DBGER $MyInvocation.MyCommand.Name $error DBGIF ('Invalid CEPWS configuration result: {0}' -f $installRes.ErrorString) { Is-ValidString $installRes.ErrorString } $siteName = 'ADPolicyProvider_CEP_{0}' -f $appConfig.auth $publicFQDN = $appConfig.publicFQDN $urlMuster = 'https://{0}/{1}/service.svc/CEP' $oldUrl = $urlMuster -f $global:thisComputerFQDN, $siteName #([Uri]::EscapeDataString($siteName)) $newUrl = $urlMuster -f $publicFQDN, $siteName #([Uri]::EscapeDataString($siteName)) DBG ('Some parameters determined: site = {0} | publicFQDN = {1} | old = {2} | new = {3}' -f $siteName, $publicFQDN, $oldUrl, $newUrl) $installDir = Join-Path $env:WINDIR ('SystemData\CEP\{0}' -f $siteName) $webConfig = Join-Path $installDir 'web.config' DBGIF ('Installation directory does not exist: {0} | {1}' -f $websvcKind, $installDir) { -not (Test-Path $installDir) } DBGIF ('Web.config does not exist: {0} | {1}' -f $websvcKind, $webConfig) { -not (Test-Path $webConfig) } DBG ('Going to reconfigure CEPWS web.config file URI: {0}' -f $newUrl) Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe ('set config "Default Web Site/{0}" -section:appSettings "/-[key=''URI'']"' -f $siteName) Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe ('set config "Default Web Site/{0}" -section:appSettings "/+[key=''URI'',value=''{1}'']"' -f $siteName, $newUrl) if (Is-EmptyString $appConfig.guid) { $cepwsGuid = ([guid]::NewGuid()).ToString('B') } else { DBG ('Will use the configured GUID for the CEPWS application: {0}' -f $appConfig.guid) DBGSTART $cepwsGuid = ([guid]::Parse($appConfig.guid)).ToString('B') DBGER $MyInvocation.MyCommand.Name $error DBGEND } DBG ('Going to reconfigure CEPWS web.config file ID: {0}' -f $cepwsGuid) Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe ('set config "Default Web Site/{0}" -section:appSettings "/-[key=''ID'']"' -f $siteName) Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe ('set config "Default Web Site/{0}" -section:appSettings "/+[key=''ID'',value=''{1}'']"' -f $siteName, $cepwsGuid) DBG ('Going to reconfigure CEPWS web.config file FriendlyName: {0}' -f $appConfig.display) Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe ('set config "Default Web Site/{0}" -section:appSettings "/-[key=''FriendlyName'']"' -f $siteName) Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe ('set config "Default Web Site/{0}" -section:appSettings "/+[key=''FriendlyName'',value=''{1}'']"' -f $siteName, $appConfig.display) } if ($websvcKind -eq 'NDES') { DBG ('Going to provision Network Device Enrollment Service (NDES)') Install-WindowsFeaturesUniversal @('ADCS-Device-Enrollment', 'Web-Mgmt-Console') $false $installMediaVolume $global:installISOVolume # # DBG ('Going to configure the web service kind: {0}' -f $websvcKind) # # $webCert = Enroll-AppCertificate $appConfig.SelectSingleNode('./cert[@appTag="web"]/one') -reuseExisting $true $raSubject = $appConfig.SelectSingleNode('./cert/one[@appTag="scepEnc"]').subject DBG ('RA certificate subject: {0}' -f $raSubject) DBGIF $MyInvocation.MyCommand.Name { Is-EmptyString $raSubject } $raSubjectElements = Split-Dn $raSubject $raSubjectName = $raSubjectElements | ? { $_.prefix -eq 'CN' } | select -First 1 | select -Expand value DBG ('RA subject name extracted: {0}' -f $raSubjectName) DBGIF $MyInvocation.MyCommand.Name { Is-EmptyString $raSubjectName } # # DBG ('First obtain the list of cert templates that the CA already publishes: {0}' -f $caEnrollmentDN) $caEnrollmentDE = Get-DE $caEnrollmentDN ([ref] $deList) [string[]] $originalCertTemplates = $caEnrollmentDE.Properties['certificateTemplates'].Value DBG ('The CA currenlty publishes certificate templates: #{0} | {1}' -f $originalCertTemplates.Count, ($originalCertTemplates -join ',')) # # [hashtable] $raSubjectParameters = @{ RAName = $raSubjectName } [string] $raSubjectEmail = $raSubjectElements | ? { $_.prefix -eq 'E' } | select -First 1 | select -Expand value [string] $raSubjectCompany = $raSubjectElements | ? { $_.prefix -eq 'O' } | select -First 1 | select -Expand value [string] $raSubjectDepartment = $raSubjectElements | ? { $_.prefix -eq 'OU' } | select -First 1 | select -Expand value [string] $raSubjectCity = $raSubjectElements | ? { $_.prefix -eq 'L' } | select -First 1 | select -Expand value [string] $raSubjectState = $raSubjectElements | ? { $_.prefix -eq 'S' } | select -First 1 | select -Expand value [string] $raSubjectCountry = $raSubjectElements | ? { $_.prefix -eq 'C' } | select -First 1 | select -Expand value if (Is-ValidString $raSubjectEmail) { [void] $raSubjectParameters.Add('RAEmail', $raSubjectEmail) } if (Is-ValidString $raSubjectCompany) { [void] $raSubjectParameters.Add('RACompany', $raSubjectCompany) } if (Is-ValidString $raSubjectDepartment) { [void] $raSubjectParameters.Add('RADepartment', $raSubjectDepartment) } if (Is-ValidString $raSubjectCity) { [void] $raSubjectParameters.Add('RACity', $raSubjectCity) } if (Is-ValidString $raSubjectState) { [void] $raSubjectParameters.Add('RAState', $raSubjectState) } if (Is-ValidString $raSubjectCountry) { [void] $raSubjectParameters.Add('RACountry', $raSubjectCountry) } [hashtable] $svcLogin = @{ } if (Is-EmptyString $appConfig.svc.login) { [void] $svcLogin.Add('ApplicationPoolIdentity', $true) } else { [void] $svcLogin.Add('ServiceAccountName', (Get-SAMLogin $appConfig.svc.login $appConfig.svc.domain)) [void] $svcLogin.Add('ServiceAccountPassword', (ConvertTo-SecureString $appConfig.svc.pwd -AsPlainText -Force)) DBG ('Make the account member of local IIS_IUSRS group as required though unnecessarily') Add-MemberLocalGroup -localGroup IIS_IUSRS -memberLogin $appConfig.svc.login -memberDomain $appConfig.svc.domain } $isCALocal = Contains-Safe $global:thisComputerLocalMachineNames $caFQDN DBG ('The CA is local: {0}' -f $isCALocal) if (-not $isCALocal) { $caReferenceOrNothing = @{ CAConfig = $caReference } } else { $caReferenceOrNothing = @{} } DBG ("Do the actual NDES service configuration: ca = {0} | local = {1} | raName = {2}`r`n{3}`r`n{4}" -f $caReference, $isCALocal, $raSubjectName, ($raSubjectParameters | Out-String), ($svcLogin | Out-String)) DBGSTART $installRes = Install-AdcsNetworkDeviceEnrollmentService -EncryptionProviderName 'Microsoft Enhanced RSA and AES Cryptographic Provider' -EncryptionKeyLength 2048 -SigningProviderName 'Microsoft Enhanced RSA and AES Cryptographic Provider' -SigningKeyLength 2048 -Confirm:$false -Force -Verbose @raSubjectParameters @svcLogin @caReferenceOrNothing DBGER $MyInvocation.MyCommand.Name $error DBGIF ('Invalid NDES configuration result: {0} | {1}' -f $installRes.ErrorId, $installRes.ErrorString) { ($installRes.ErrorId -ne 0) -or (Is-ValidString $installRes.ErrorString) } # # DBG ('Remove the automatically enrolled certificates before replacing them') [object[]] $autoEnrolledCerts = dir Cert:\LocalMachine\My | ? { $_.Subject -eq (($raSubjectElements | select -Expand rdn) -join ', ') } DBG ('Found autoenrolled certificates: #{0} | {1}' -f (Get-CountSafe $autoEnrolledCerts), (($autoEnrolledCerts | select -Expand Thumbprint) -join ', ')) DBGIF $MyInvocation.MyCommand.Name { (Get-CountSafe $autoEnrolledCerts) -ne 2 } foreach ($oneAutoEnrolledCert in $autoEnrolledCerts) { [string] $oneKeyContainer = $oneAutoEnrolledCert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName DBG ('One autoenrolled certificate key container: {0}' -f $oneKeyContainer) DBGIF $MyInvocation.MyCommand.Name { Is-EmptyString $oneKeyContainer } DBG ('Deleting the one autoenrolled certificate: {0} | {1}' -f $oneAutoEnrolledCert.Thumbprint, $oneKeyContainer) Run-Process certutil ('-delkey {0}' -f $oneKeyContainer) Run-Process certutil ('-delstore my {0}' -f $oneAutoEnrolledCert.Thumbprint) } # # $raEncryptionCert = Enroll-AppCertificate $appConfig.SelectSingleNode('./cert/one[@appTag="scepEnc"]') $raSigningCert = Enroll-AppCertificate $appConfig.SelectSingleNode('./cert/one[@appTag="scepSig"]') DBG ('RA encryption certificate enrolled: {0}' -f $raEncryptionCert) DBG ('RA signature certificate enrolled: {0}' -f $raSigningCert) DBGIF $MyInvocation.MyCommand.Name { Is-EmptyString $raEncryptionCert } DBGIF $MyInvocation.MyCommand.Name { Is-EmptyString $raSigningCert } DBG ('Get the IIS APPPOOL\SCEP SID') DBGSTART $iisPoolScepSID = (New-Object Security.Principal.NTAccount 'IIS APPPOOL\SCEP').Translate([Security.Principal.SecurityIdentifier]).Value DBGER $MyInvocation.MyCommand.Name $error DBGEND DBG ('Update the RA encryption certificate permissions for IIS APPPOOL\SCEP: {0}' -f $iisPoolScepSID) DBGIF $MyInvocation.MyCommand.Name { (Is-EmptyString $iisPoolScepSID) -or ($iisPoolScepSID -ne 'S-1-5-82-298598261-2050821656-3206418497-3728514927-3871840613') } Set-CertificatePrivateKeyPermissions -storePath Cert:\LocalMachine\My -thumbprint $raEncryptionCert -who 'IIS APPPOOL\SCEP' -access 'GR' Set-CertificatePrivateKeyPermissions -storePath Cert:\LocalMachine\My -thumbprint $raSigningCert -who 'IIS APPPOOL\SCEP' -access 'GR' # # DBG ('Verify the list of cert templates that the CA publishes after NDES configuration: {0}' -f $caEnrollmentDN) $caEnrollmentDE = Get-DE $caEnrollmentDN ([ref] $deList) [string[]] $afterNdesCertTemplates = $caEnrollmentDE.Properties['certificateTemplates'].Value DBG ('After NDES installation the CA publishes certificate templates: #{0} | {1}' -f $afterNdesCertTemplates.Count, ($afterNdesCertTemplates -join ',')) DBGIF $MyInvocation.MyCommand.Name { (-not (Contains-Safe $afterNdesCertTemplates CEPEncryption)) -or (-not (Contains-Safe $afterNdesCertTemplates EnrollmentAgentOffline)) -or (-not (Contains-Safe $afterNdesCertTemplates IPSecIntermediateOffline)) } DBG ('Return the CA configuration of the original certificate template list') DBGSTART $caEnrollmentDE.PutEx($global:PutExUpdate, 'certificateTemplates', @($originalCertTemplates)) $caEnrollmentDE.SetInfo() DBGER $MyInvocation.MyCommand.Name $error DBGEND # # DBG ('Verify existance of the template regitry values first') DBGSTART [string] $assertSigTemplate = (Get-ItemProperty -Path HKLM:\Software\Microsoft\Cryptography\MSCEP -Name SignatureTemplate).SignatureTemplate [string] $assertEncTemplate = (Get-ItemProperty -Path HKLM:\Software\Microsoft\Cryptography\MSCEP -Name EncryptionTemplate).EncryptionTemplate [string] $assertBothTemplate = (Get-ItemProperty -Path HKLM:\Software\Microsoft\Cryptography\MSCEP -Name GeneralPurposeTemplate).GeneralPurposeTemplate DBGER $MyInvocation.MyCommand.Name $error DBGEND DBGIF $MyInvocation.MyCommand.Name { $assertSigTemplate -ne 'IPSECIntermediateOffline' } DBGIF $MyInvocation.MyCommand.Name { $assertEncTemplate -ne 'IPSECIntermediateOffline' } DBGIF $MyInvocation.MyCommand.Name { $assertBothTemplate -ne 'IPSECIntermediateOffline' } DBG ('Template name prefix of the CA: prefix = {0}' -f $caNode.templateNamePrefix) [string] $templateSig = $appConfig.SelectSingleNode('./cert[@appTag="sig"]').template.Replace('$namePrefix$', $caNode.templateNamePrefix) [string] $templateEnc = $appConfig.SelectSingleNode('./cert[@appTag="enc"]').template.Replace('$namePrefix$', $caNode.templateNamePrefix) [string] $templateBoth = $appConfig.SelectSingleNode('./cert[@appTag="both"]').template.Replace('$namePrefix$', $caNode.templateNamePrefix) DBG ('Certificate templates required: sig = {0} | enc = {1} | both = {2}' -f $templateSig, $templateEnc, $templateBoth) DBGIF $MyInvocation.MyCommand.Name { Is-EmptyString $templateSig } DBGIF $MyInvocation.MyCommand.Name { Is-EmptyString $templateEnc } DBGIF $MyInvocation.MyCommand.Name { Is-EmptyString $templateBoth } if ((Is-ValidString $templateSig) -and (Is-ValidString $templateEnc) -and (Is-ValidString $templateBoth)) { DBG ('Configure the templates') DBGSTART Set-ItemProperty -Path HKLM:\Software\Microsoft\Cryptography\MSCEP -Name SignatureTemplate -Value $templateSig Set-ItemProperty -Path HKLM:\Software\Microsoft\Cryptography\MSCEP -Name EncryptionTemplate -Value $templateEnc Set-ItemProperty -Path HKLM:\Software\Microsoft\Cryptography\MSCEP -Name GeneralPurposeTemplate -Value $templateBoth DBGER $MyInvocation.MyCommand.Name $error DBGEND } # # DBG ('Fix some reasons why the NDES Admin does not have sufficient permissions and other issues') Set-RegPermissions 'SOFTWARE\Microsoft\Cryptography\CertificateTemplateCache' 'IIS APPPOOL\SCEP' #Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe 'set config "Default Web Site/certsrv/mscep_admin" -section:system.webServer/security/authentication/basicAuthentication /enabled:"true" /commit:appHost' #Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe 'set config "Default Web Site/certsrv/mscep_admin" -section:system.webServer/security/authentication/basicAuthentication /logonMethod:"ClearText" /commit:appHost' #Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe 'set config "Default Web Site/certsrv/mscep" -section:system.webServer/security/authentication/basicAuthentication /enabled:"true" /commit:appHost' #Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe 'set config "Default Web Site/certsrv/mscep" -section:system.webServer/security/authentication/basicAuthentication /logonMethod:"ClearText" /commit:appHost' #Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe 'set config "Default Web Site/certsrv/mscep" -section:system.webServer/security/authentication/windowsAuthentication /enabled:"false" /commit:appHost' # Note: the CERTREQ tool requires Windows Authentication or NTLM to connect to the mscep_admin site # because it maintains the authenticated state on a TCP connection while with the Basic authentication it # succeeds in authenticating once, but after a simple redirect to /mscep_admin/ it cannot authenticate again and # returns 401 unauthorized # Moreover the CERTREQ tool cannot generate requests over anything else than clean HTTP, you cannot provide it with https:// URI with -new parameter Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe 'set config "Default Web Site/certsrv/mscep_admin" -section:system.webServer/security/authentication/windowsAuthentication /~providers /commit:appHost' Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe 'set config "Default Web Site/certsrv/mscep_admin" -section:system.webServer/security/authentication/windowsAuthentication "/+providers.[value=''NTLM'']" /commit:appHost' # Note: /mscep does not need any authentication Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe 'set config "Default Web Site/certsrv/mscep" -section:system.webServer/security/authentication/windowsAuthentication /enabled:"false" /commit:appHost' # Note: this one is needed in order to work with a single admin password which gets encrypted with DPAPI into registry Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe 'set apppool SCEP /processModel.loadUserProfile:"true"' # # Run-Process $env:WINDIR\system32\inetsrv\appcmd.exe 'set config "Default Web Site/certsrv/mscep" /section:system.webServer/security/requestFiltering /requestLimits.maxUrl:65534 /requestLimits.maxQueryString:65534 /commit:appHost' DBG ('Verify HTTP.SYS registry limits') DBGSTART [int] $httpsMaxField = 0 $httpsMaxField = (Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\HTTP\Parameters -Name MaxFieldLength).MaxFieldLength [int] $httpsMaxRequest = 0 $httpsMaxRequest = (Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\HTTP\Parameters -Name MaxRequestBytes).MaxRequestBytes #DBGER $MyInvocation.MyCommand.Name $error DBGEND DBGIF ('Non-default HTTP.SYS registry limits: maxField = {0} | maxRequest = {1}' -f $httpsMaxField, $httpsMaxRequest) { ($httpsMaxField -ne 0) -or ($httpsMaxRequest -ne 0) } DBG ('Set the new HTTP.SYS limits') DBGSTART Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\HTTP\Parameters -Name MaxFieldLength -Value 65534 Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\HTTP\Parameters -Name MaxRequestBytes -Value 65534 DBGER $MyInvocation.MyCommand.Name $error DBGEND DBG ('Must bind the SSL certificate manually: {0}' -f $webCert) Ensure-HttpsCertificateBound -ip '0.0.0.0' -port 443 -webCert $webCert } Dispose-List ([ref] $deList) DBG ('Throw up any remaining errors') DBGSTART; DBGEND # SIG # Begin signature block # MIIc/QYJKoZIhvcNAQcCoIIc7jCCHOoCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBiewu8xUqtYnXz # uZxxY8pHN9ExGfftVGz0zd51yjnbbKCCGAQwggTlMIIDzaADAgECAhA5vUKe0oFu # utW8yQO0umXnMA0GCSqGSIb3DQEBCwUAMHUxCzAJBgNVBAYTAklMMRYwFAYDVQQK # Ew1TdGFydENvbSBMdGQuMSkwJwYDVQQLEyBTdGFydENvbSBDZXJ0aWZpY2F0aW9u # IEF1dGhvcml0eTEjMCEGA1UEAxMaU3RhcnRDb20gQ2xhc3MgMiBPYmplY3QgQ0Ew # HhcNMTYxMjAxMTU1MTEzWhcNMTgxMjAxMTU1MTEzWjBRMQswCQYDVQQGEwJDWjEa # MBgGA1UECAwRSmlob21vcmF2c2t5IEtyYWoxDTALBgNVBAcMBEJybm8xFzAVBgNV # BAMMDk9uZHJlaiBTZXZlY2VrMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC # AQEAr9E9hNj06bash9JX97kpsqK9Z/ciOBC6trI4nvlW9CPwhKBTb5wArhxLYZBG # 9jWPWrdy1nL/cm5qMqBb/mogYwMwvEYWMvsIOOVn6HD9lVhNAovD6PHz0ziBBKIs # zXTjyUPQaoIlIELovz967m78HJdUZJGxqhluAsS9o9/fEzA7XXUhUuqRKsetuZV/ # Asfh5sOveeoRsbeW4daTWvtz3TJuULL0w43LNVYJkd6LL8cegvLPVZUe1N7skvid # EvntdlowQsJlqFdrH3SGKIPKA6ObcY8SZWkEQSbVBF8Kum1UT+jN0gm+84FwOg5W # qKx+VvTK2ljVWnPrCD0Zzu2oIQIDAQABo4IBkzCCAY8wDgYDVR0PAQH/BAQDAgeA # MBMGA1UdJQQMMAoGCCsGAQUFBwMDMAkGA1UdEwQCMAAwHQYDVR0OBBYEFG2vSo3N # hQWILeUs0oN9XzHTejcfMB8GA1UdIwQYMBaAFD5ik5rXxxnuPo9JEIVVFSDjlIQc # MG0GCCsGAQUFBwEBBGEwXzAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Auc3RhcnRz # c2wuY29tMDcGCCsGAQUFBzAChitodHRwOi8vYWlhLnN0YXJ0c3NsLmNvbS9jZXJ0 # cy9zY2EuY29kZTIuY3J0MDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwuc3Rh # cnRzc2wuY29tL3NjYS1jb2RlMi5jcmwwIwYDVR0SBBwwGoYYaHR0cDovL3d3dy5z # dGFydHNzbC5jb20vMFEGA1UdIARKMEgwCAYGZ4EMAQQBMDwGCysGAQQBgbU3AQIF # MC0wKwYIKwYBBQUHAgEWH2h0dHBzOi8vd3d3LnN0YXJ0c3NsLmNvbS9wb2xpY3kw # DQYJKoZIhvcNAQELBQADggEBAJuRiEvHtIYSpsmMkPhTz4QOOShN3p5KWdf8vm71 # A33CR9fds10d8D2B2aE+vjmHJ69GY0bbfg5oZY2Lsq2euL7Da5/hS8+6T3MEtD4h # njfHV7mxmoSfFuy/KDipoV6uwhI+ksqchXYdUH+5uCQO0MOO8ITjAgzUQsnZ4UIB # HBGeP+e+3ljxSYSXWdPIrgxdR971P/HhWSVfKNlmBgEKMQM5Jy0aAd4jxSl/AzdY # t0+6pliFJ1peGhdFni2Fm8fu5oN68aTIrNtc5WY7Lzgf+sRTVeWORWS37+1zAD0m # jzd8gyfBLxRuaRSfjYxny0rLXelAwfiA3ze2DU2Bfg9/rfcwggXYMIIDwKADAgEC # AhBsO9J+3TyUnpWOKKmzx1egMA0GCSqGSIb3DQEBCwUAMH0xCzAJBgNVBAYTAklM # MRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSswKQYDVQQLEyJTZWN1cmUgRGlnaXRh # bCBDZXJ0aWZpY2F0ZSBTaWduaW5nMSkwJwYDVQQDEyBTdGFydENvbSBDZXJ0aWZp # Y2F0aW9uIEF1dGhvcml0eTAeFw0xNTEyMTYwMTAwMDVaFw0zMDEyMTYwMTAwMDVa # MHUxCzAJBgNVBAYTAklMMRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSkwJwYDVQQL # EyBTdGFydENvbSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEjMCEGA1UEAxMaU3Rh # cnRDb20gQ2xhc3MgMiBPYmplY3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw # ggEKAoIBAQC5FARY97LFhiwIMmCtCCbAgXe5aBnZFSsdGGnk2hqWBZcuZHkaqT1R # M1rQd2r0ApNBw466cBur2Ht0b5jo17mpPmh2pImgIqwX1in4u7hhn9IH0GYOMEcg # K3ACHv5zCRxxNLXifqmsqKfxjjpABnaSyvd4bO9YBXN9f4NQ6aJVAuMArpanxsJk # e+P4WECVLk17v92CAN5JVaczI+baT/lgo5NVcTEkloCViSbIfU6ILeyhOSQZvpom # MYk8eJqI0nimOTJJfmXangNDsrX8np+3lXD0+6rCZisXRWIaeffyTMHZ31Qj1D50 # WYdRtX5yev4WgaXoKJQN3lkgXUcytvyHAgMBAAGjggFaMIIBVjAOBgNVHQ8BAf8E # BAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAy # BgNVHR8EKzApMCegJaAjhiFodHRwOi8vY3JsLnN0YXJ0c3NsLmNvbS9zZnNjYS5j # cmwwZgYIKwYBBQUHAQEEWjBYMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5zdGFy # dHNzbC5jb20wMAYIKwYBBQUHMAKGJGh0dHA6Ly9haWEuc3RhcnRzc2wuY29tL2Nl # cnRzL2NhLmNydDAdBgNVHQ4EFgQUPmKTmtfHGe4+j0kQhVUVIOOUhBwwHwYDVR0j # BBgwFoAUTgvvGqRAW6UXaYcwyjRoQ9BBrvIwPwYDVR0gBDgwNjA0BgRVHSAAMCww # KgYIKwYBBQUHAgEWHmh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeTANBgkq # hkiG9w0BAQsFAAOCAgEAY6U81bNtJyjY67pTrzAL6kpdEtX5mspw+kxjjNdNVH5G # 6lLnhaEkIxqdpvY/Wdw+UdNtExs+N8efKPSwh2m/BxXj2fSeLMwXcwHFookScEER # 8ez0quCNzioqNHac7LCXPEnQzbtG2FHlePKNDWh8eU6KxiAzNzIrIxPthinHGgLT # BOACHQM2YTlD8YoU5oN3dLmBOqtH0BDMZoLcjEIoEW1zC+TnVb3yU1G0xub6gnN7 # lP50vbAiHJYrnywQiXaloBV8B9YYfe6ZgvjqxwufwFcMVyE3UmCuDTsOpjqDEKpJ # 25s+FUdkie5VqCS1aaudLo31X+9UvP45pfgyRqzyfUnVEhH4ZXxlBWZMzj2Xov5+ # m/+H3kxYuFA5xdqdshj/Zx00S7PkCSF+8M1NCcvFgQwjIw61bZAjDBl3P3a8xNTX # sb2CjFdiNKbT3LD6IGeIf0b/EbPf0FXdvBrxm0ofMOhnngdPolPYCtoOGtZPAVe/ # xeu+/ZyKv6TSHlshaUO0iYfsmbXnZ51vvt/kkjwms9/qPFxSuE0fjEfF7aQazwRE # Df2hiVPR0pAhvShtM3oU4XreEFEUWEYHs25fYV4WMmxkUKSgmSmwRq45tvtGH4LT # b5+cd+iLqK8rBQL0E6xaUjjGfsYx7bueIvqTvCkrQvoxMbn/qDHCiypowDVq6TAw # ggZqMIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIx # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 # dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0Et # MTAeFw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVT # MREwDwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1w # IFJlc3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8 # s+CCNeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7d # y4XpX6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGf # rvP9Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5 # uHzu5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYu # RhDIjegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJC # kawCwO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMB # Af8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIw # ggGhBglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdp # Y2VydC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBl # ACAAbwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBu # AHMAdABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0 # AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0 # AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBl # AG4AdAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5 # ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABl # AHIAZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwD # FTAfBgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpN # JLZJMp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMu # ZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0 # dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3Js # MHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNl # cnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20v # RGlnaUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+ # GzNNsiaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94G # AYw3+puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFB # pr1i2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dx # nSHdFMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bI # o4sKHOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQK # Ohvjjz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJ # KoZIhvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IElu # YzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQg # QXNzdXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAw # MFowYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UE # CxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJ # RCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKV # pYBzQHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqv # y15r7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/ # 2DDD/6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE # 7h6z8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKv # mPv2zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIU # YJX9BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIG # CCsGAQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcD # CDCCAdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUH # AgEWLmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5o # dG0wggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0 # AGgAaQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1 # AHQAZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABp # AGcAaQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBl # AGwAeQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBo # AGkAYwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAg # AGEAcgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAg # AGIAeQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB # /wQIMAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8v # b2NzcC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRp # Z2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6 # MHgwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3Vy # ZWRJRFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9E # aWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e # 36K+Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqG # SIb3DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90 # OPKyXGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann # 4+erYs37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qq # q8+cdkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD # 7eeSDY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38 # KiGtSTGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIETzCCBEsCAQEwgYkwdTEL # MAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKTAnBgNVBAsTIFN0 # YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSMwIQYDVQQDExpTdGFydENv # bSBDbGFzcyAyIE9iamVjdCBDQQIQOb1CntKBbrrVvMkDtLpl5zANBglghkgBZQME # AgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEM # BgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqG # SIb3DQEJBDEiBCCaO+YtILOD7tGKGOmR4dCfSl+t/ijihj7bfCFDROkxUTANBgkq # hkiG9w0BAQEFAASCAQCD209FqxxRjovuEpVgDgyKH7bXkHSgB02g6abS7WPMYIHf # 4w26WJyGrxezCEcwSOohX/WWvoFciMBNWZFxtMcQIZouXygN/YOH3i9EUxmLl3hU # uoGcNwrzwvHOYIAFIHkBtP8KseokcftVXmu28zXsov4LaaAOj0BbbesRGm6Wq37q # oscrfmerxmlt0hsklyphQrC89Nc8lLGydPu69Q+vE/UpbtuwhEbrJSAXfJkWAOKb # C5whfp4heZtmWRJvrnvcWoBiwBoqtIqcBwRHoKTRtuXblQ9/wCAVtHZrPRSg4pR6 # 3JgencXcXfnD4w57ftwJWep7wfRCMy4uqcke+rbcoYICDzCCAgsGCSqGSIb3DQEJ # BjGCAfwwggH4AgEBMHYwYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0 # IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNl # cnQgQXNzdXJlZCBJRCBDQS0xAhADAZoCOv9YsWvW1ermF/BmMAkGBSsOAwIaBQCg # XTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xODA4 # MjMwNTQ2MzNaMCMGCSqGSIb3DQEJBDEWBBR7Vmqxo32Q3JdYvJ+JmQSnqQ1j9zAN # BgkqhkiG9w0BAQEFAASCAQAwMqvx6HHhzsE0/sBnKlRfuTgBceyI5O6DmyZvjGfe # 1MmnQJgJkjGWvIBK9ZFpIBpnfWVAJckcXDpn8XUHXuwK4FC/rB6J9J2uG3Tuj5YH # Syp4jonOcmPygNEHuuQZ1QL7QRGlZfeEzfCB4Fega49GyYoC2FhNgiXYxrQTlRwz # k/2zRqMTRYTO5yFESHuXFSRq2uwhKEuibsHgzbO7ll/omPW5b27og6OYi066gg4y # VeS5+EvCOliAXmw8wLie074C8NnT8tavW1UTeNw0fmk0iwr0bybulvwJsPv1B5Ho # L9yufs2eyOeM3sBa6yah++7+YeH/PjagVX0BuFqvy38J # SIG # End signature block