Certificate Web Request/Enrollment on Windows Vista/Server 2008

02Jan08

I noticed recently while being part in the development of a web-banking system, that Windows Vista and Windows Server 2008 (Longhorn) are using a different resource DLL when it comes to certificate web enrollment. From a file point of view we have CERTENROLL.DLL on Vista & Longhorn while previous versions of Windows use XENROLL.DLL. The above means that any code previously written that uses XENROLL no longer works on Vista/Longhorn clients.

 

It also means that the Windows 2000/2003 certificate authority web enrollment pages will not allow Vista and Longhorn clients to enroll a certificate. What you will have to do is replace your Windows 2003 CA web certificate pages with the ones from Longhorn. Those can be found in the Longhorn beta VHD provided by Microsoft. More information about this can be found here.

 

Here is a javascript code example on how to use CERTENROLL.

 

 

<%
‘ Certificate Enrollment Example
‘ Dimitris Giakoumakis 2007

‘ Browser detection. Use CertEnroll if Windows Longhorn/Vista
Dim sBrowser

sBrowser = Request.ServerVariables(“HTTP_USER_AGENT”)
If 0 InStr(sBrowser, “Windows NT”) Then
numChar = InStr(Mid(sBrowser, InStr(sBrowser, “Windows NT”)+11), “.”)-1
If CInt(Mid(sBrowser, InStr(sBrowser, “Windows NT”)+11,numChar)) >= 6 Then
bLongHorn = True
End If
End If

If bLongHorn = True Then
%>

// Distinguished name variables
// for more RDN keys refer to http://msdn2.microsoft.com/en-us/library/aa377051.asp
var sCN = “GR”; // Common name
var sO = “Organisation”; // Organisation name
var sOU = “OrganisationUnit”; // Organisational Unit
var sL = “Locality”; // Locality
var sS = “Attika”; // State
var sC = “GR”; // Country
var sCertificate = null;

sDistinguishedName = “c=” + sC + “;o=” + sO + “;ou=” + sOU + “;cn=” + “Dimitris Giakoumakis;”;

// Initialization of the ActiveX component
var classFactory = new ActiveXObject(“X509Enrollment.CX509EnrollmentWebClassFactory”);

// Declaration of the objects
var objEnroll = classFactory.CreateObject(“X509Enrollment.CX509Enrollment”);
var objPrivateKey = classFactory.CreateObject(“X509Enrollment.CX509PrivateKey”);
var objRequest = classFactory.CreateObject(“X509Enrollment.CX509CertificateRequestPkcs10”);
var objDN = classFactory.CreateObject(“X509Enrollment.CX500DistinguishedName”);

// Specify the name of the cryptographic provider.
objPrivateKey.ProviderName = “Microsoft Enhanced RSA and AES Cryptographic Provider”;

// X509PrivateKeyUsageFlags
// Specify a value that identifies the specific purpose for which a private key can be used.
//
// typedef enum {
// XCN_NCRYPT_ALLOW_USAGES_NONE = 0,
// XCN_NCRYPT_ALLOW_DECRYPT_FLAG = 0x1,
// XCN_NCRYPT_ALLOW_SIGNING_FLAG = 0x2,
// XCN_NCRYPT_ALLOW_KEY_AGREEMENT_FLAG = 0x4,
// XCN_NCRYPT_ALLOW_ALL_USAGES = 0xffffff
// } X509PrivateKeyUsageFlags;
objPrivateKey.KeySpec = “1”;

// X509ProviderType
// Specification of the cryptographic standards and algorithms
//
// typedef enum X509ProviderType {
// XCN_PROV_NONE = 0,
// XCN_PROV_RSA_FULL = 1,
// XCN_PROV_RSA_SIG = 2,
// XCN_PROV_DSS = 3,
// XCN_PROV_FORTEZZA = 4,
// XCN_PROV_MS_EXCHANGE = 5,
// XCN_PROV_SSL = 6,
// XCN_PROV_RSA_SCHANNEL = 12,
// XCN_PROV_DSS_DH = 13,
// XCN_PROV_EC_ECDSA_SIG = 14,
// XCN_PROV_EC_ECNRA_SIG = 15,
// XCN_PROV_EC_ECDSA_FULL = 16,
// XCN_PROV_EC_ECNRA_FULL = 17,
// XCN_PROV_DH_SCHANNEL = 18,
// XCN_PROV_SPYRUS_LYNKS = 20,
// XCN_PROV_RNG = 21,
// XCN_PROV_INTEL_SEC = 22,
// XCN_PROV_REPLACE_OWF = 23,
// XCN_PROV_RSA_AES = 24
// } X509ProviderType;
objPrivateKey.ProviderType = “24”;

// Initialization of the certificate request by using an IX509PrivateKey (objPravateKey)
objRequest.InitializeFromPrivateKey(1, objPrivateKey, “”);

// Initializing the X.500 distinguished name
objDN.Encode(sDistinguishedName, 0);

// Specifing the X.500 distinguished name using the Subject property of IX509CertificateRequestPkcs10
objRequest.Subject = objDN;

// Initializing the enrollment object (objEnroll) using the existing certificate request object.
objEnroll.InitializeFromRequest(objRequest);

// Retrieving the encoded certificate request object
sCertificate = objEnroll.CreateRequest(1);

document.write(sCertificate);

For more information refer to the certificate enrollment API at MSDN.

If you have any questions please feel free to post a comment.

AddThis Social Bookmark Button

Advertisements


5 Responses to “Certificate Web Request/Enrollment on Windows Vista/Server 2008”

  1. I was looking for this code and trying to write it for ages. Yours worked first time. Still having problems getting it to install but 99% there. Thanks a million.

  2. 2 M. Smith

    Hi,
    I am a newbie to this. Can you please advice where i put this code snippet? I have some certificates which ran on my 2003 server. I am now upgrading to longhorn. the certificates are not available. so please advice what i need to do.

  3. 3 Max

    Hi,
    We are trying to install a certificate using certenroll.dll on Windows 2008 using Javascript. However we are facing a lot of issues instantiating the same.
    Can you please help us with a code that would install a certificate for us?

  4. 4 dat

    function generateRequest() {

    if (!initOk) {
    return false;
    }
    try
    {
    var g_objPrivateKey = document.g_objClassFactory.CreateObject(“X509Enrollment.CX509PrivateKey”);
    var g_objRequest = document.g_objClassFactory.CreateObject(“X509Enrollment.CX509CertificateRequestPkcs10”);
    var x500DistinguishedName = document.g_objClassFactory.CreateObject(“X509Enrollment.CX500DistinguishedName”);
    var g_objEnroll = document.g_objClassFactory.CreateObject(“X509Enrollment.CX509Enrollment”);
    g_objPrivateKey.ProviderName = document.getElementById(“csps”).options(document.getElementById(“csps”).selectedIndex).text;
    g_objPrivateKey.ProviderType = document.getElementById(“csps”).options(document.getElementById(“csps”).selectedIndex).value;
    g_objPrivateKey.Length = $(‘#lengthKey’).val();
    if (g_objPrivateKey.ProviderType < 2) {
    g_objPrivateKey.KeySpec = 1; // X509KeySpec.XCN_AT_KEYEXCHANGE
    } else {
    g_objPrivateKey.KeySpec = 2; // X509KeySpec.XCN_AT_SIGNATURE
    }
    g_objPrivateKey.MachineContext = false;
    g_objPrivateKey.KeyProtection = 1; //XCN_NCRYPT_UI_PROTECT_KEY_FLAG = 1
    g_objPrivateKey.ExportPolicy = 1; //X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG = 1, 0 to disable
    g_objPrivateKey.Existing = false;
    g_objRequest.InitializeFromPrivateKey(1, g_objPrivateKey, ""); // X509CertificateEnrollmentContext.ContextUser = 1
    x500DistinguishedName.Encode("CN=ignoredNameUsedInRequest", 0); // X500NameFlags.XCN_CERT_NAME_STR_NONE = 0
    g_objRequest.Subject = x500DistinguishedName;
    var cspInformation = g_objCSPInformations.ItemByName(g_objPrivateKey.ProviderName);
    var cspAlgorithms = cspInformation.CspAlgorithms;
    var nBestIndex = -1;
    for (var i = 0;i < cspAlgorithms.Count;i++) {
    if (cspAlgorithms.ItemByIndex(i).Name.indexOf("sha1") != -1) {
    nBestIndex = i;
    } else if (cspAlgorithms.ItemByIndex(i).Name.indexOf("md5") != -1 && nBestIndex == -1) {
    nBestIndex = i;
    }
    }
    var cspAlgorithm = cspAlgorithms.ItemByIndex(nBestIndex);
    if (cspAlgorithm.Type == 2) { // XCN_CRYPT_HASH_INTERFACE = 2
    g_objRequest.HashAlgorithm = cspAlgorithm.GetAlgorithmOid(0, 0); // AlgorithmFlagsNone = 0
    }

    g_objEnroll.InitializeFromRequest(g_objRequest);
    var req = g_objEnroll.CreateRequest(3); // CRYPT_STRING_BASE64REQUESTHEADER = 3
    $('#certificateRequest').val(req);
    document.getElementById('certificateRequestType').value = "0"; // PKCS#10
    return true;
    }
    catch(e)
    {
    if (e.number == -2146762487) {
    // Ignore: The user should follow the instructions shown
    alert("Hãy cài đặt chứng thư Mic vào truststore của hệ điều hành.");
    } else if (e.number == -2146827850){
    document.objXenroll.reset();
    document.objXenroll.HashAlgorithm = "MD5"; // WTF!
    document.objXenroll.ProviderName = document.getElementById("csps").options(document.getElementById("csps").selectedIndex).text;
    document.objXenroll.ProviderType = document.getElementById("csps").options(document.getElementById("csps").selectedIndex).value;
    if (document.objXenroll.ProviderType < 2) {
    document.objXenroll.KeySpec = 1;
    } else {
    document.objXenroll.KeySpec = 2;
    }
    var keySize = $('#lengthKey').val();
    var keyMask = keySize * 65536;
    var exportableKey = 1; // 1=true, 0=false
    document.objXenroll.GenKeyFlags = keyMask | 2 | exportableKey;
    $('#certificateRequest').val(document.objXenroll.createPKCS10("CN=ignoredNameUsedInRequest", ""));
    document.getElementById('certificateRequestType').value = "0"; // PKCS#10
    return true;
    }
    }
    }


  1. 1 IE中自动安装用户数字证书 | 出家如初,成佛有余

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: