TMG HTTPS inspection is failing if the target Web site is using a CNG certificate
If you have configured HTTPS Inspection on TMG you may not be able to access some sites such as Twitter and Dropbox.
In this scenario clients will get a blank page and in the TMG logs you will see the error 0x8009000a
This happens when:
Web site that are using certificate with suite-B algorithm
TMG certificate used by HTTPS inspection feature to sign the certificate that will be sent to client is not compatible with suite-B certificate.
To resolve the problem you need to install a CNG certificate for the HTTPS Inspection feature
This certificate can be issued by your internal CA or it can be a self-signed certificate that you can generate with a script (see below).
This certificate must have the “Certificate signing” key usage
You can read more about CNG certificates in this article: http://msdn.microsoft.com/en-us/library/windows/desktop/bb931380(v=vs.85).aspx
As example here is a PowerShell script that create a self-signed CNG certificate:
#SCRIPT - Generate Self-signed CNG Certificates for Certificate signing purpose, This will be used by TMG Https Inpection
#AUTHOR - Franck Heilmann - Microsoft Corporation
#VERSION - 1.1
#$ErrorActionPreference = "Stop"
Write-Host "`n WARNING: This script sample is provided AS-IS with no warranties and confers no rights." -ForegroundColor red
Write-Host "`n This script sample will generate self-signed CNG Authority certificate to be used by TMG HTTPS Inspection feature"
Write-Host " in the Local Computer Personal certificate store.`n Private is can be exported. As well the .cer and .pfx files will be save ini the provided directory`n`n"
$outputDir = Read-Host "`nEnter directory path where certificate will be saved"
$Subject = Read-Host "`nEnter the Subject for certificate "
$password = Read-Host -assecurestring "`nPfx password"
$ValidateDays = Read-Host "`nCertificate Validity days: (please enter number of days)"
#Generate cert in local computer My store
$name = new-object -com "X509Enrollment.CX500DistinguishedName.1"
$name.Encode("CN=$Subject", 0)
# The Key
$key = new-object -com "X509Enrollment.CX509PrivateKey.1"
$key.ProviderName = "Microsoft Software Key Storage Provider" # CNG is Software Key Storage "Microsoft RSA SChannel Cryptographic Provider"
$key.KeySpec = 0 # was 1 but 0 looks needed for CNG http://msdn.microsoft.com/en-us/library/aa379409(VS.85).aspx
$key.keyUsage =0xfffff # Set the key usage to all usage http://msdn.microsoft.com/en-us/library/windows/desktop/aa379410(v=vs.85).aspx
$key.Length = 2048
$key.SecurityDescriptor = "D:PAI(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)(A;;0x80120089;;;NS)" # Allow Write NT AUTHORITY\SYSTEM Allow Write BUILTIN\Administrators Allow Write NT AUTHORITY\NETWORK SERVICE
$key.MachineContext = 1
$key.ExportPolicy = 1 # Allow private key to be exported XCN_NCRYPT_ALLOW_EXPORT_FLAG 0x00000001 http://msdn.microsoft.com/en-us/library/windows/desktop/aa379002(v=vs.85).aspx
$key.Create()
Write-Host "`nPrivate Key created ......"
#The certificate itself
$cert = new-object -com "X509Enrollment.CX509CertificateRequestCertificate.1" # Interface for self signed cert request http://msdn.microsoft.com/en-us/library/windows/desktop/aa377124(v=vs.85).aspx
$cert.InitializeFromPrivateKey(2, $key, "")
$cert.Subject = $name
$cert.Issuer = $cert.Subject
$today =get-date
$cert.NotBefore = $today.AddDays(-1) # yesterday
$cert.NotAfter = $cert.NotBefore.AddDays($ValidateDays)
# Add Key usage to the certificate, this is needed as TMG chek this during certificate import
$KeyUsage = new-object -com "X509Enrollment.CX509ExtensionKeyUsage.1"
$Keyusage.InitializeEncode(0x4) #0x4 XCN_CERT_KEY_CERT_SIGN_KEY_USAGE http://msdn.microsoft.com/en-us/library/windows/desktop/aa379410(v=vs.85).aspx
$cert.X509Extensions.Add($keyusage)
$BasicConstraints = new-object -com "X509Enrollment.CX509ExtensionBasicConstraints.1"
$BasicConstraints.InitializeEncode(1,0) #set isCA to true, max path of 0 means it can't create subordinate CAs, only endpoint certs
$cert.X509Extensions.Add($BasicConstraints)
$cert.Encode()
Write-Host "`nCertificate created ......"
$enrollment = new-object -com "X509Enrollment.CX509Enrollment.1"
$enrollment.InitializeFromRequest($cert)
$certdata = $enrollment.CreateRequest(0)
$enrollment.InstallResponse(2, $certdata, 0, "")
Write-Host "`nCNG self signed installed in the Computer certificate local store"
#Create the ".pfx" and ".cer" version by exporting the just inserted certificate
$store = new-object System.Security.Cryptography.X509Certificates.X509Store "My","LocalMachine"
$store.Open("ReadOnly")
$certs = $store.Certificates
$cerPath = $outputDir+ "\"+ $Subject+ ".cer"
$pfxPath = $outputDir + "\" + $Subject + ".pfx"
foreach ($cert in $certs)
{
# write-host $cert.Subject
if($cert.Subject -like ("CN="+ $Subject))
{
$ExportCert = $cert.Export(1) #http://msdn.microsoft.com/fr-fr/library/system.security.cryptography.x509certificates.x509certificate2.aspx 1=.cer 3=.fx
[System.IO.File]::WriteAllBytes(($cerPath), $ExportCert)
Write-Host "`nCertificate .cer exported to: " $cerPath
$PFXStrData =$cert.Export(3,$password)
[System.IO.File]::WriteAllBytes($pfxPath, $PFXStrData)
Write-Host "`nCertificate with private Key .pfx exported to: " $pfxPath
}
}
$store.close()
#now Import it to Local computer Root store
$RootCert = new-object System.Security.Cryptography.X509Certificates.X509Certificate2 $cerPath
$RootStore = new-object System.Security.Cryptography.X509Certificates.X509Store "Root","LocalMachine"
$RootStore.Open("ReadWrite")
$RootStore.Add($RootCert)
Write-Host "`nCertificate installed in Local computer - Trusted root"
$RootStore.close()
Write-Host "`nDone ... `n" -ForegroundColor Green
You will have to copy the above lines into a new file and then save it into a file name with .ps1 extension, such as CNG-HTTPSi.ps1 on a computer running Windows 2008 R2 SP1 or later.
Then follow these steps:
Open a PowerShell window as administrator
Ensure local scripts can be executed by running the command:
Set-ExecutionPolicy Set-ExecutionPolicy RemoteSigned
Find more information about execution policy in this article: http://technet.microsoft.com/en-us/library/ee176949.aspxExecute the script with the command ./CNG-HTTPSi.ps1
Enter the path where the certificates will be saved
Enter the subject, such as ”CNG HTTPS Inspection”
Enter the pfx password
Enter the validity of the certificate in days, for example 730 for two years
In the specified folder you will find a .cer and a .pfx files
Deploy the cer file in the Trusted Root container to all clients and the TMG servers, you can deploy the certificate manually or using Active directory
Find more information in this article: http://technet.microsoft.com/en-us/library/dd441069Once the certificate is deployed you can reconfigure HTTP Inspection on TMG importing the pfx certificate generated by the script
Save and apply the configuration then you will be able to reach the site
Author:
Gianni Bragante
Support Engineer – Microsoft Forefront Edge Security Team
Reviewer:
Franck Heilmann
Sr. Escalation Engineer - Microsoft Forefront Edge Security Team
Philipp Sand
Sr. Support Escalation Engineer – Microsoft Forefront Edge Security Team