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

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 https://msdn.microsoft.com/en-us/library/aa379409(VS.85).aspx  
$key.keyUsage =0xfffff # Set the key usage to all usage https://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 https://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 https://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 https://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) #https://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: https://technet.microsoft.com/en-us/library/ee176949.aspx

  • Execute 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: https://technet.microsoft.com/en-us/library/dd441069

  • Once 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