javascript - The template parameter in InitializeFromPrivateKey() on CX509CertificateRequestPkcs10 object causes exception when

I am having an issue with specifying the template parameter in InitializeFromPrivateKey() on the X509En

I am having an issue with specifying the template parameter in InitializeFromPrivateKey() on the X509Enrollment.CX509CertificateRequestPkcs10 object. Anything other than a template of "User" is resulting in the following exception:-

CertEnroll::CX509CertificateRequestPkcs10::InitializeFromPrivateKey: The requested certificate template is not supported by this CA. 0x80094800 (-2146875392)

There is a specific Certificate template that I need to be used, and when I try it then the code throws the exception. The template exists on the CA, and on the client machine which is running the following code.

Javascript code as follows:

 <script type="text/javascript">

     var sCertificate = null;
     var sDistinguishedName = "C=\"\";S=\"\";L=\"\";O=\"XXXXX\";OU=\"XXXXXXX\";E=\"[email protected]\";CN=\"xxxxxxx\";";
     var template = "RegistrationCert"; //Anything Other than "User" fails, have tried template Oid too.

     var classFactory = new ActiveXObject("X509Enrollment.CX509EnrollmentWebClassFactory");
     var objEnroll = classFactory.CreateObject("X509Enrollment.CX509Enrollment");
     var objPrivateKey = classFactory.CreateObject("X509Enrollment.CX509PrivateKey");
     var objRequest = classFactory.CreateObject("X509Enrollment.CX509CertificateRequestPkcs10");
     var objDN = classFactory.CreateObject("X509Enrollment.CX500DistinguishedName");

     objPrivateKey.ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0";
     objPrivateKey.KeySpec = "1";
     objPrivateKey.ProviderType = "1";

    try 
    {
            objRequest.InitializeFromPrivateKey(1, objPrivateKey, template);
            objDN.Encode(sDistinguishedName, 0);
            objRequest.Subject = objDN;
            objEnroll.InitializeFromRequest(objRequest);
            sCertificate = objEnroll.CreateRequest(1);
            document.writeln(sCertificate);
    }
    catch (ex)
    {
             document.writeln(ex.description);
    }
 </script>

Couple of other questions
- I assume that the template should exist on the Client Machine? Otherwise how does it know the location of the CA to query for templates?
- Does CertEnroll on a Client even work against a Windows 2003 CA server??

If you can help me that it would be much appreciated!!!

Additional Info
- Client is Windows 7, with MS IE9 Client running as Administrator.
- Web App which hosts the above page is accessed over HTTPs.
- Web App is hosted on a Win2003 CA Server.

Before posting I have looked at...
- Stackoverflow threads regarding CertEnroll + InitializeFromPrivateKey
- Blogs about using Template OID not Template name
- MSDN / alejacma's Site
- CertEnroll API on MSDN

I am having an issue with specifying the template parameter in InitializeFromPrivateKey() on the X509Enrollment.CX509CertificateRequestPkcs10 object. Anything other than a template of "User" is resulting in the following exception:-

CertEnroll::CX509CertificateRequestPkcs10::InitializeFromPrivateKey: The requested certificate template is not supported by this CA. 0x80094800 (-2146875392)

There is a specific Certificate template that I need to be used, and when I try it then the code throws the exception. The template exists on the CA, and on the client machine which is running the following code.

Javascript code as follows:

 <script type="text/javascript">

     var sCertificate = null;
     var sDistinguishedName = "C=\"\";S=\"\";L=\"\";O=\"XXXXX\";OU=\"XXXXXXX\";E=\"[email protected]\";CN=\"xxxxxxx\";";
     var template = "RegistrationCert"; //Anything Other than "User" fails, have tried template Oid too.

     var classFactory = new ActiveXObject("X509Enrollment.CX509EnrollmentWebClassFactory");
     var objEnroll = classFactory.CreateObject("X509Enrollment.CX509Enrollment");
     var objPrivateKey = classFactory.CreateObject("X509Enrollment.CX509PrivateKey");
     var objRequest = classFactory.CreateObject("X509Enrollment.CX509CertificateRequestPkcs10");
     var objDN = classFactory.CreateObject("X509Enrollment.CX500DistinguishedName");

     objPrivateKey.ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0";
     objPrivateKey.KeySpec = "1";
     objPrivateKey.ProviderType = "1";

    try 
    {
            objRequest.InitializeFromPrivateKey(1, objPrivateKey, template);
            objDN.Encode(sDistinguishedName, 0);
            objRequest.Subject = objDN;
            objEnroll.InitializeFromRequest(objRequest);
            sCertificate = objEnroll.CreateRequest(1);
            document.writeln(sCertificate);
    }
    catch (ex)
    {
             document.writeln(ex.description);
    }
 </script>

Couple of other questions
- I assume that the template should exist on the Client Machine? Otherwise how does it know the location of the CA to query for templates?
- Does CertEnroll on a Client even work against a Windows 2003 CA server??

If you can help me that it would be much appreciated!!!

Additional Info
- Client is Windows 7, with MS IE9 Client running as Administrator.
- Web App which hosts the above page is accessed over HTTPs.
- Web App is hosted on a Win2003 CA Server.

Before posting I have looked at...
- Stackoverflow threads regarding CertEnroll + InitializeFromPrivateKey
- Blogs about using Template OID not Template name
- MSDN / alejacma's Site
- CertEnroll API on MSDN

Share Improve this question edited Aug 6, 2011 at 7:49 Donal Fellows 138k19 gold badges160 silver badges221 bronze badges asked Aug 5, 2011 at 15:55 PaulwinPaulwin 931 silver badge10 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

Ok, so figured it..typical.

  • Use CX509ExtensionTemplateName, and call InitializeEncode with the OID template value
  • Don't specify a template param in InitializeFromPrivateKey.

i.e:

var objExtensionTemplate = classFactory.CreateObject("X509Enrollment.CX509ExtensionTemplateName")


objRequest.InitializeFromPrivateKey(1, objPrivateKey, ""); //empty string, don't specify template here
objExtensionTemplate.InitializeEncode(template); //Specify Template as OID value!
objRequest.X509Extensions.Add(objExtensionTemplate);

Have verified on the CA that the request is for the template type I specified, and does indeed only create a cert for that type.

Hope this helps somebody one day.

See also this code, where I'm using a newer DLL that doesn't include the methods you're using. I also am not using the "interop types" which cause issues when deploying or building the code.

 CObjectId EkuOid = new CObjectId();
        EkuOid.InitializeFromValue("1.3.6.1.4.1.311.21.8.4946465.16405226.12930948.10533807.2139545.33.5005369.11644649");
        CObjectIds EkuOids = new CObjectIds();
        EkuOids.Add(EkuOid);
        CX509ExtensionEnhancedKeyUsage eku = new CX509ExtensionEnhancedKeyUsage();
        eku.InitializeEncode(EkuOids);
        eku.Critical = false;
        objPkcs10.X509Extensions.Add((CX509Extension)eku);

The OID can be obtained using this method on serverfault

Alternate implementations of this code (VBS, C#, etc) is located here.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745365125a4624541.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信