Welcome to MSDN Blogs Sign in | Join | Help

Decrypt my World

Cryptography, Security, Debugging and more!

News

  • Any of my posts is supported under any Microsoft standard support program or service. They are provided "AS IS" without warranty of any kind, and confer no rights.

Where are my readers?

Locations of visitors to this page

Favorite Posts

How to create a certificate request with CertEnroll (JavaScript)

Hi all,

The following Javascript sample shows how to use CertEnroll COM component to create a certificate request:

<html>
<head>
    <title>Certificate Request test</title>
</head>
<body> 
  <object id="objCertEnrollClassFactory" classid="clsid:884e2049-217d-11da-b2a4-000e7bbb2b09"></object>    
  <script language="javascript">

    function CreateRequest() 
    {
      document.write("<br>Create Request...");                      

      try {
        // Variables
        var objCSP = objCertEnrollClassFactory.CreateObject("X509Enrollment.CCspInformation");
        var objCSPs = objCertEnrollClassFactory.CreateObject("X509Enrollment.CCspInformations");
        var objPrivateKey = objCertEnrollClassFactory.CreateObject("X509Enrollment.CX509PrivateKey");
        var objRequest = objCertEnrollClassFactory.CreateObject("X509Enrollment.CX509CertificateRequestPkcs10")
        var objObjectIds = objCertEnrollClassFactory.CreateObject("X509Enrollment.CObjectIds");
        var objObjectId = objCertEnrollClassFactory.CreateObject("X509Enrollment.CObjectId");
        var objX509ExtensionEnhancedKeyUsage = objCertEnrollClassFactory.CreateObject("X509Enrollment.CX509ExtensionEnhancedKeyUsage");
        var objExtensionTemplate = objCertEnrollClassFactory.CreateObject("X509Enrollment.CX509ExtensionTemplateName")
        var objDn = objCertEnrollClassFactory.CreateObject("X509Enrollment.CX500DistinguishedName")
        var objEnroll = objCertEnrollClassFactory.CreateObject("X509Enrollment.CX509Enrollment")

        //  Initialize the csp object using the desired Cryptograhic Service Provider (CSP)
        objCSP.InitializeFromName("Microsoft Enhanced Cryptographic Provider v1.0");

        //  Add this CSP object to the CSP collection object
        objCSPs.Add(objCSP);

        //  Provide key container name, key length and key spec to the private key object
        //objPrivateKey.ContainerName = "AlejaCMa";
        objPrivateKey.Length = 1024;
        objPrivateKey.KeySpec = 1; // AT_KEYEXCHANGE = 1

        //  Provide the CSP collection object (in this case containing only 1 CSP object)
        //  to the private key object
        objPrivateKey.CspInformations = objCSPs;

        // Initialize P10 based on private key
        objRequest.InitializeFromPrivateKey(1, objPrivateKey, ""); // context user = 1

        // 1.3.6.1.5.5.7.3.2 Oid - Extension
        objObjectId.InitializeFromValue("1.3.6.1.5.5.7.3.2");
        objObjectIds.Add(objObjectId);
        objX509ExtensionEnhancedKeyUsage.InitializeEncode(objObjectIds);
        objRequest.X509Extensions.Add(objX509ExtensionEnhancedKeyUsage);

        // 1.3.6.1.5.5.7.3.3 Oid - Extension
        //objExtensionTemplate.InitializeEncode("1.3.6.1.5.5.7.3.3");
        //objRequest.X509Extensions.Add(objExtensionTemplate);

        // DN related stuff
        objDn.Encode("CN=alejacma", 0); // XCN_CERT_NAME_STR_NONE = 0
        objRequest.Subject = objDn;

        // Enroll
        objEnroll.InitializeFromRequest(objRequest);
        var pkcs10 = objEnroll.CreateRequest(3); // XCN_CRYPT_STRING_BASE64REQUESTHEADER = 3

        document.write("<br>" + pkcs10);
        document.write("<br>The end!");
      }
      catch (ex) {
        document.write("<br>" + ex.description);
        return false;
      }

      return true;
    }       

    CreateRequest();

  </script>
    
</body>
</html>

And the following Javascript sample shows how to install the response from the CA (Certificate Authority):

<html>
<head>
    <title>Certificate Request test</title>
</head>
<body> 
  <object id="objCertEnrollClassFactory" classid="clsid:884e2049-217d-11da-b2a4-000e7bbb2b09"></object>    
  <script language="javascript">

  function InstallCert() 
  {        
    document.write("<br>Installing certificate...");                      

    try {
    // Variables
    var objEnroll = objCertEnrollClassFactory.CreateObject("X509Enrollment.CX509Enrollment")
    var sPKCS7 = "-----BEGIN CERTIFICATE-----" +
    "MIIKFQYJKoZIhvcNAQcCoIIKBjCCCgICAQExADALBgkqhkiG9w0BBwGgggnqMIIF" +
    "QjCCBCqgAwIBAgIKYbzdPwAAAAAAVzANBgkqhkiG9w0BAQUFADBJMRMwEQYKCZIm" +
...
    "h25CSWewZhpgbZkKPATLzidc0EjrWLl74RU32HEqkl2+R7yAdBQjMQA=" +
    "-----END CERTIFICATE-----"

    objEnroll.Initialize(1); // ContextUser
    objEnroll.InstallResponse(0, sPKCS7, 6, ""); // AllowNone = 0, XCN_CRYPT_STRING_BASE64_ANY = 6
    }
    catch (ex) {
      document.write("<br>" + ex.description);
      return false;
    }

    return true;
  }

  InstallCert(); 
     
  </script>

</body>
</html>

Note: this code must be run in the same machine where we made the request.

Note: these samples just create the request and install the response from the CA. If we need to send the request to the CA and get its response programmatically, the following C# sample may help with the objects and methods we can use to achieve this: How to create a certificate request with CertEnroll and .NET (C#).

I hope this helps.

Regards,

 

Alex (Alejandro Campos Magencio)

Posted: Wednesday, January 28, 2009 11:08 AM by alejacma
Filed under:

Comments

Maxi said:

Hi,

great article, it was really helpful!

I have a small doubt, though: I am creating a request using a Smart Card reader and I have noticed that after invoking CreateRequest() a request is inserted in the card. This was not the case with xenroll under Windows XP.

Is this the expected behavior? Can I prevent CreateRequest() from inserting the request in the card?

Thanks and keed posting!

# March 4, 2009 5:51 AM

erwin said:

Would you be able to help me create a asp script to generate a CSR for a IIS entry.  And another script to install the cert purchased from GeoTrust?  How much would you charge for something like this? Please email me at erwinyu888@hotmail.com

# May 1, 2009 8:02 PM

alejacma said:

People open incidents/cases with MS Technical Support in their respective countries, and if the country is in my area and the question is related to the technologies that my team supports, I may take the case. Otherwise colleagues of mine will take it. I don't support IIS related stuff, for instance. Another team does.

Additionally, I can't tell how much MS charges for these services. Also take into account the following limitations:

1) This kind of "How to" questions are called Advisories, they are not support incidents, and only customers with a Premier contract with Microsoft can open them. They are charged by the hour.

2) We won't create custom code, we will only provide with samples/documentation to assist customers to create their own production code.

If you have any question though, feel free to contact MS Technical Support.

Thx,

Alex

# May 4, 2009 3:21 AM

Rafael said:

That code doesn't work in html frames, I think. In my case appears the message "CertEnroll::CX509EnrollmentWebClassFactory::CreateObject: Unspecified error 0x80004005 (-2147467259)" and Certenroll don't load, If I don't use frames it works great.

# July 9, 2009 8:37 AM

Craig Martin said:

This is a great little article. I appreciate the sample code as I am finding it very hard to find sample code for certenroll.

One question: I have this all working, but when I go to install the certificate I have generated (I work for QuoVadis Limited who is a certificate authority so am using a dev CA to generate the certificate) I get the following error:

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

I have the root and issuing CA certs installed on the PC and I even tried installing a PEM with chain version of the certificate that includes the root and issuing CA certificates, but I am still getting this error. Any idea why this is happening?

Any help with this would be greatly appreciated!

Cheers,

Craig Martin

VP Software Development

QuoVadis Limited

# October 26, 2009 1:00 PM

alejacma said:

I'm not sure without knowing the details of your environment or debugging the code itself, but this could be related:

Error message when a user uses Internet Explorer 7 to open the certificate enrollment Web page to install an end entity certificate on a Windows Vista-based client computer

http://support.microsoft.com/default.aspx?scid=kb;EN-US;945121

If that doesn't help, I suggest you open a case with us, Microsoft Technical Support. If you are in EMEA region, I may assist you personally.

Cheers!

# October 27, 2009 1:10 AM

emre_erkan said:

I copied this code to an aspx file and get

Object doesn't support this property or method

in line

var objCSP = objCertEnrollClassFactory.CreateObject("X509Enrollment.CCspInformation");

with win 7

any idea why ?  

# December 15, 2009 10:22 AM

emre_erkan said:

my mistake. it was IE security. Thanks for the nice article

# December 15, 2009 1:31 PM

jay said:

Hi, I get this error. what could this mean? i've tried IE security to enable all possible tweaks.

Thanks!

--------------------------

Webpage error details

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)

Timestamp: Tue, 22 Dec 2009 06:33:55 UTC

Message: CertEnroll::CX509EnrollmentWebClassFactory::CreateObject: The operation was canceled by the user. 0x800704c7 (WIN32: 1223)

Line: 43

Char: 9

Code: 0

URI: https://intranet/user/mycertrequestIE.php

# December 21, 2009 10:27 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

  
Enter Code Here: Required

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Page view tracker