Unable to Install Certificate on Windows 7 using CertEnroll

13.3k views Asked by At

We have an existing certificate issuing application (C#, ASP.NET, JavaScript) that issues certificates to Windows XP users using XenRoll in IE. I need to extend this to support Windows Vista and Windows 7 users, also using IE.

For Vista and 7, Microsoft replaced the XenRoll ActiveX controll with the new CertEnroll control. I've got this working in Vista SP2, but in 7 I get this error at the installation step:

CertEnroll::CX509Enrollment::InstallResponse: A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider. 0x800b0109 (-2146762487)

Here's a snippet of the relevant HTML & JavaScript:

<object id="classFactoryObj" classid="clsid:884e2049-217d-11da-b2a4-000e7bbb2b09"></object>

<script type="text/javascript">
    function InstallCert() 
    {  
        try
        {
            var classFactory = document.getElementById("classFactoryObj");
            var objEnroll = classFactory.CreateObject("X509Enrollment.CX509Enrollment");

            var signedCert = '-----BEGIN CERTIFICATE-----' + 
                'REMOVED FOR BREVITY' + 
                '-----END CERTIFICATE-----';

            objEnroll.Initialize(1); // User context
            objEnroll.InstallResponse(4, signedCert, 6, ""); // AllowUntrustedRoot = 4

            alert('Certificate installed');
        }
        catch (ex)
        {
            alert('Unable to install certificate: ' + ex.description);
        }
     }

    InstallCert();
</script>

Now, it's true that the root certificate is not trusted, but I'm calling InstallResponse with the first parameter set to 4, which is supposed to allow installation even if the root certificate is not trusted. This works as advertised in Vista, but doesn't seem to in Windows 7.

I tested, and it does work if the root certificate is trusted. I'm sure some one will say it, so I'll pre-empt it - having the clients trust the root certificate is not really an option for us (we want to distribute client authentication certificates to customers, as a part of authenticating them on our network).

Am I doing something wrong here? Has anyone else got this working in Windows 7?

2

There are 2 answers

0
Cocowalla On BEST ANSWER

The solution was to install hotfix KB 2078942.

Note that this hotfix does not claim to fix this issue, but it does! Rather annonying, or I would have come across it much earlier :-/

I believe this is a regression bug from Vista, as there was a hotfix for Vista to fix the exact problem I was experiencing.

A thankyou and upvote goes out to Bruno for spending time yesterday trying to help me resolve this.

13
Bruno On

I wrote this script a while ago for a demo (in conjunction with this page). It supports <keygen/> and replaces it with XEnroll or CertEnroll calls on Internet Explorer. The project has evolved a bit since, but I've just tested this branch with IE8 on Windows 7 and it worked. The CA certificate wasn't on the client machine at all. I had to lower the security settings to 'low' for it to run the ActiveX (otherwise, it wouldn't even submit the request, so even less install the certificate in the response).

If that helps, I do this:

try {
    enrollObj.InstallResponse(4, xmlHttpRequest.responseText,
            0, "");
    window.alert("A certificate has been installed.");
} catch (e1) {
    try {
        enrollObj.InstallResponse(0,
                xmlHttpRequest.responseText, 0, "");
        window.alert("A certificate has been installed.");
    } catch (e2) {
        window
                .alert("You're probably using Vista without SP1 or above, in which case you need to add the certificate of this authority as a trusted root certificate.");
    }
}

I must admit I didn't test which of these two cases was used (as it's the same alert message).