IIS 8.5 certificate chain error results in 403.16 error

Posted on 2014-08-06
Last Modified: 2014-08-13

In IIS I am requiring certificates for a directory that authorized users will access with their smartcard that has both an ID and Email/Signing certs. Many-to-one certificate mapping has been set up and one rule enabled to match the cert subject OU field which is consistent across all certificates.

In a browser, I go to the site and click into the directory. I get asked which certificate to use as ActivClient makes them available to Windows. I select one of them (both should work) and then enter and submit my PIN so the smartcard's private key can be accessed to complete the request. The server response is 403.16. Looking at the failed request trace:

ModuleName IIS Web Core
Notification BEGIN_REQUEST
HttpStatus 403
HttpReason Forbidden
HttpSubStatus 16
ErrorCode A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider. (0x800b0109)

Opening up the mmc certificate snap-in shows that the local computer certificate store has the certificates installed where expected. The CA Root certificate is in the (local machine)/Trust Root Certification Authorities and the intermediate CA certificates (corresponding to the ID and Signing certs) are installed to (local machine)/Intermediate Trusted Root Certification Authorities.

I also ran SSLDiag.exe which reported "Certificate verified." for the SSL certificate. This comes from Network Solutions and has its own root and intermediate certs installed to the same (local machine) trusted and intermediate cert locations. Other SSL enabled pages display fine so no problem there.  

How can I trace this further to find what the underlying problem is? Or believing in the error message, how do I tell the trust provider that the Root CA should be trusted?

Question by:James Clark

    Author Comment

    by:James Clark
    Some additional info on this is that none of the certificates have expired. Also for test purposes, I've set up a directory with a static html file that I'm trying to access. Within IIS manager, the .NET Trust Level feature remains set to the default 'Full (internal)'.
    LVL 60

    Expert Comment

    The problem's symptoms may vary depending on the configuration and use of a Certificate Trust List (CTL) on the IIS server.

    For your error case, if IIS is not configured to use a CTL, SSL client certificate authentication will fail with the 403.16 error condition. This error occurs because SChannel.dll wrongly considers the client certificate to be untrusted. (NOTE: Having no CTL in use is the default configuration of IIS 8.0. This is configured by having no SendTrustedIssuerList present or by setting SendTrustedIssuerList=0).

    In this scenario, the IIS log typically shows a value of 2148204809 in the sc-win32-status field. This translates to error code 0x800b0109, which is defined as CERT_E_UNTRUSTEDROOT.

    To workaround these issues, uninstall the non-self-signed certificate from the Local Computer --> Trusted root Certification authorities certificate store on the IIS server. You may consider using the powershell script provided in the article to detect the non-self-signed certificates installed in the Trusted Root Certification Authorities certificate store.

    You can use a Windows PowerShell command to find certificates that are put in the Trusted Root Certification Authorities store incorrectly on the local computer. The following command compares the "Issuer" property and the "Subject" property of each certificate in the store, and then outputs details of certificates that do not meet the criteria of a self-signed certificate:
    Get-Childitem cert:\LocalMachine\root -Recurse | Where-Object {$_.Issuer -ne $_.Subject} | Format-List * | Out-File "c:\computer_filtered.txt"

    Author Comment

    by:James Clark
    Thanks for pointing me to Powershell. I ran the command and the CA Root certificate wasn't listed so as a sanity check, I reversed the condition so that {$_.Issuer -eq $_.Subject}  and it was in the list with lots of interesting info so it does appear to be installed correctly. I also verified the intermediate CA certs as well. Lot's to love about Powershell and the certificate provider! For anyone else interested in this, check out these links:

    Back to the problem though, I'll add that the client certificate is accepted by IIS at least to the extent that I can see it in the log files. I added a custom log field for the server variable {CERT_SUBJECT} and my client cert is listed on all the failed 403.16 requests.

    To debug, I also created a new site in IIS from scratch. Same setup with a basic SSL encrypted static .html home page with a link to the 'cert required' sub directory that has only a one static html file. I setup many to one mapping again and reset and re-entered the user account password that the mapping uses. Even with the most simple setup, I get the same result with SSL working on the home page and 403.16 on the directory page.

    I guess I'll delete all the certs, reboot, and try again.
    LVL 60

    Expert Comment

    I do highly suspect is the client cert and most of the time 403.16 is a problem with the client cert. The highest hint is that client certificate was created by a certification authority that the IIS computer does not trust. Possible error revolve such as below
    HTTP 403.16 Forbidden: Client certificate untrusted or invalid.
    HTTP 403.16 Forbidden: Client certificate is ill-formed or is not trusted by the web server.

    The new server certificate was located only in the Personal store for the Computer account and not on the Trusted Root Certificates Authorities store of the same account.

    More on setting up SSL here

    Using SSL in kernel mode requires storing SSL binding information in two places. First, the binding is stored in %windir%\System32\inetsrv\config\applicationHost.config for your site. When the site starts, IIS sends the binding to HTTP.sys, and HTTP.sys starts listening for requests on the specified IP:Port (this works for all bindings). Second, the SSL configuration associated with the binding is stored in the HTTP.sys configuration. Use the netsh command at a command prompt to view SSL binding configuration stored in HTTP.sys as in the following example:

    netsh http show sslcert

    When a client connects and initiates an SSL negotiation, HTTP.sys looks in its SSL configuration for the IP:Port pair to which the client connected. The HTTP.sys SSL configuration must include a certificate hash and the name of the certificate store before the SSL negotiation will succeed.

    Troubleshooting Tip: If you're having trouble with an SSL binding, verify that the binding is configured in ApplicationHost.config, and that the HTTP.sys store contains a valid certificate hash and store name for the binding.

     Another minor pt is Crypto API (used by IIS for cert verification) rejects certificates if the root certification authority certificates are not installed in the local computer Trusted Root Certification Authorities certificate store.

     There is a possibility some failure is due to a group policy that forces the IIS computer to "Trust Only Enterprise Root Stores." If this policy is in enabled, the authentication will still fail, even if the CA is a Trusted Root Store. To work around this issue, remove the Group Policy Trust only Enterprise Root stores option for the domain. To do this, perform the following steps:
    Start the Default Domain Policy Group Policy Editor.
    Select Computer Settings, choose Computer Configuration, and then select Windows Settings.
    Choose Security Settings, select Public Key Policies and then choose Trusted Root Certification Authorities.
    Right-click Trusted Root CA node, and then select Properties.
    Disable the Trust only Enterprise Root stores option.

    Author Comment

    by:James Clark
    A quick update in that I can 100% guarantee that there is no problem with the client certs or CA certs either. The Root CA literally supports millions of smart cards so there is no doubt about the technical integrity of the client certs. Plus I use the smart card daily for other purposes without error.

    I think you are on to something regarding the CTL. SendTrustedIssuerList is not set and the netsh command shows the CTL Identifier and Store Name are both Null. The problem is I don't have a running Windows 2003 or 2008 server anymore to create a CTL using the old IIS GUI. I've hit this issue a couple of times recently and found little help on the web to show how to create a CTL on either 2008R2 or 2012R2 servers which I do have access to.

    If I can't figure this out tonight, I'll probably just get an Amazon EC2 spot instance tomorrow of a 2003 server to work on and create a CTL. I can't believe Microsoft has made it this hard recently to do what appears to be a fairly simple task!
    LVL 60

    Accepted Solution

    The CTL issue is more the issue if you see IIS log shows a value of 2148204809 in the sc-win32-status field. This translates to error code 0x800b0109, which is defined as CERT_E_UNTRUSTEDROOT. You can catch the workaround which is the uninstalled which you did as well and the mention of "SendTrustedIssureList")

    But there is other sharing that root cause is during the handshake protocol for client certificate authorization, the server sends a list of Trusted Root Certification Authorities to the client.  The client will in this case only provide Client Certificates, issued by one of these Trusted Root Certification Authorities.  The problem was that the Trusted Root Certification Authorities list was too long on that particular server, so it was truncated before sent to the client.  Unluckily, Root Certificate Authority was truncated from the list, so the handshake failed. The suggested two solutions to solve are:
    The first solution is to clean up the Trusted Root Certification Authorities store (Local Machine) and remove all unnecessary certificates. Be aware that you don’t remove certificates that are required by Windows.
    A second solution is to configure Schannel to no longer send the list of trusted root certification authorities during the TLS/SSL handshake process.  This can be done by adding this registry entry on the web server:
            Value name: SendTrustedIssuerList
            Value type: REG_DWORD
            Value data: 0 (False)
    Similar context, this also suggested 3 method for considerations pertaining to CTL related issue and Method 3 touch on the registry key again.
    Method 1: Remove some trusted root certificates
    Method 2: Configure Group Policy to ignore the list of trusted certification authorities on the computer that hosts the UC client
    Method 3: Configure Schannel to no longer send the list of trusted root certification authorities during the TLS/SSL handshake process
    Can be very taxing to troubleshoot the certificate if fresh installation doesn't work, not any easier though to get through

    Author Comment

    by:James Clark
    The best solution appears to be to use a CTL (instead of trying not to) so that's the path I'm on.

    Thanks to Amazon EC2, I launched a free tier Windows 2003 server and created a CTL to file using my existing root cert. The CTL file was then moved to and imported into my 2012 server. So far so good and in MMC I see the CTL under the local machine\Intermediate Certification Authorities\Certificate Trust List. All the CTL properties match the expected values and looks like it is ready for use except for the message "This certificate trust list is not digitally signed and cannot be verified."

    So to create a signing certificate I follow the advice at and use makecert to create a new self signed CA root cert and a code-signing (SPC) certificate and then use pvk2pfx to create a pfx for each cert that combines public/private keys for import. The new CA root cert goes into the local machine trusted root store and I let the wizard pick where the SPC cert goes but I placed it in both personal and Trusted People stores during testing. The SPC cert shows an OK certification path back to the new root CA.

    The issue now is that when I edit the CTL which runs the Certificate Trust List wizard to sign my CTL, the only option is "Select from Store..." and clicking on the button brings up a dialog "No certificate available - No certificates meet the application criteria".  Is there a particular -eku value I should be using with makecert to ensure my CA / SPC certs are created as Windows needs them to be? I looked at the wincrypt.h file from the SDK which didn't clarify anything!

    This needs to be resolved since netsh won't create a binding with the CTL as it is currently configured.

    Thanks again!
    LVL 60

    Expert Comment

    CTL  is a list of self-signed certificates for the CAs whose certificates are to be trusted by your organization.. Whenever you create a certificate trust list, you need to authorize it by signing the certificate trust list with a certificate issued by an already trusted certification authority. Hence, due to the certificate Usages as specified in Enhanced Key Usage as shared, I do suspect it validates the specified certificate in the following ways:

    Verifies the presence of the Basic Constraints extension and its value, which must be either Subject Type=End Entity or unspecified.
    Verifies the value of the Enhanced Key Usage property, which must contain Code Signing and may also contain Lifetime Signing. Any other EKUs are prohibited.
    Verifies the value of the KeyUsage (KU) property, which must be either Unset or DigitalSignature.
    Verifies the existence of a private key exists.
    Verifies whether the certificate is active, hasn’t expired, and hasn't been revoked.

    In short, I believe acquiring a certificate that did only have Code Signing as an Enhanced Key Usage may help. This faq has info on the various EKU

    Each root certificate will be associated with a minimum set of EKU Object Identifiers (OIDs) to enable the supported product or business scenario.

    The following is a list of EKUs allowed to CAs.
    Server Authentication =
    Client Authentication =
    Secure E-mail =

    Other EKUs may be granted if the CA is able to provide additional or specific justification:

    Code Signing = (see Explanatory Note for qualifying your root for the code signing EKU)[8]
    Time stamping =
    OCSP =  (see Explanatory Note for qualifying your root for the OCSP EKU)[9]
    Encrypting File System =
    IPsec (Tunnel, User) =,
    Document Signing =

    Author Comment

    by:James Clark
    As it turns out, the CTL does not need to be signed. Of great help was a recent blog post at which basically walked me through exactly what I needed to do.

    I would add a couple of things though to help anyone trying to do the same...

    - for the netsh http add sslcert command, don't forget if using Powershell to quote the appid='{...}' curly braces otherwise it results in "The parameter is incorrect." In retrospect it seems more obvious but this threw me and I mistakenly thought netsh was complaining about the input.

    - if and when netsh does complain about the input, it will probably be a 1312 error. This basically means it can't find the certhash it was given to anything in the user's MY store (a.k.a. Personal \ Certificates in mmc) where it looks by default. Since https.sys will also need to access this same cert and does not want to access it through a user's store, create a duplicate cert in the WebHosting store.

    Thanks for your help!

    Author Closing Comment

    by:James Clark
    Helpful in understanding 403.16 CERT_E_UNTRUSTEDROOT root errors and some of the SCHANNEL options.
    LVL 60

    Expert Comment

    thanks for sharing :)

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How your wiki can always stay up-to-date

    Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
    - Increase transparency
    - Onboard new hires faster
    - Access from mobile/offline

    Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
    Cybersecurity has become the buzzword of recent years and years to come. The inventions of cloud infrastructure and the Internet of Things has made us question our online safety. Let us explore how cloud- enabled cybersecurity can help us with our b…
    This tutorial walks through the best practices in adding a local business to Google Maps including how to properly search for duplicates, marker placement, and inputing business details. Login to your Google Account, then search for "Google Mapmaker…
    The viewer will get a basic understanding of what section 508 compliance can entail, learn about skip navigation links, alt text, transcripts, and font size controls.

    779 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    15 Experts available now in Live!

    Get 1:1 Help Now