Andy Johnson

With IE7, I've noticed the original ActiveX method of generating a client certificate request and installing the signed certificate no longer work (xenroll.dll calling CreatePKCS10() and acceptPKCS7()).

How do you do this now with IE7. Vista customers with IE7 don't even have access to xenroll.dll. I have been unable to find much documentation on this change, only that the old way was replaced with "something new", but no details on what the something new is called.

Any help would be greatly appreciated!

Thanks,
Andy



Re: Internet Explorer Web Development IE7 Certificate Request/Enrollment

wonder_waif

XEnroll has been deprecated in Vista. It has been replaced by CertEnroll. The CertEnroll API is available on MSDN http://msdn2.microsoft.com/en-us/library/aa374850.aspx.

In my experience, the API is a PAIN.




Re: Internet Explorer Web Development IE7 Certificate Request/Enrollment

hfml

Hi,

I¡¯am having the same problem and the documentation that i found is not very friendly.

I have an old version of Netscape Certificate Server with Enrollment pages that use the CreatePLKCS10() and acceptPKCS7() method¡¯s in VBScript.

Did you solve the problem

Thanks for any help.





Re: Internet Explorer Web Development IE7 Certificate Request/Enrollment

cuijianming

Hey,

According the document, many objects ,such as X509CertificateRequestPkcs10, can created by calling CreateObject () upon X509EnrollmentWebClassFactory. You can try it to see if it works.





Re: Internet Explorer Web Development IE7 Certificate Request/Enrollment

sophy jue

It can even work without quoting the webfactory object.

codes like:

Set enroll = CreateObject("X509Enrollment.CX509Enrollment")
Set privatekey = CreateObject("X509Enrollment.CX509PrivateKey")

can work.

And the API doc has something difficult for the readers regarding optional parameters and return value.





Re: Internet Explorer Web Development IE7 Certificate Request/Enrollment

cuijianming

Hi,

If you test the object you created by using IsObject function, You may find that the result is false.





Re: Internet Explorer Web Development IE7 Certificate Request/Enrollment

sophy jue

I tried with the following code in installing certificate test, and it turns out to be an object.

<html>

<SCRIPT language="vbscript">

Dim enroll1

Set enroll1 = CreateObject("X509Enrollment.CX509Enrollment")

If IsObject(enroll1) Then msgbox("Is an Object") end if

enroll1.Initialize(1)

Set fso = CreateObject("Scripting.FileSystemObject")

Set ts = fso.OpenTextFile("c:\test\zz.response")

strResponse = ts.ReadAll

ts.Close

MsgBox (strResponse)

on error resume next

a = enroll1.InstallResponse(0, strResponse, 1, "")

if err.number<>0 then msgbox(err.Description) end if

</script>

</html>





Re: Internet Explorer Web Development IE7 Certificate Request/Enrollment

hfml

Hi,

I tried something like and it turns an object to.

But i have a permissions problem. When i call the Initialize on object x509PKCS10 i get a "Access Denied". If i put it on a Vbs file works fine. This must be an IE permission, did you know which one

Thanks

<html>

<SCRIPT LANGUAGE=VBS>

const ContextUser = 1

Dim CertEnroll

Set x509PKCS10 = CreateObject( "X509Enrollment.CX509CertificateRequestPkcs10" )
x509PKCS10.Initialize(ContextUser)


Set CertEnroll = CreateObject( "X509Enrollment.CX509Enrollment" )
Dim RequestStr, CertRequest, Disposition, ID

CertEnroll.InitializeFromRequest(x509PKCS10)

szCertReq = CertEnroll.createRequest(1)

MsgBox(Err.Description)
theError = Err.Number

MsgBox(szCertReq)

MsgBox(Err.Description)
</SCRIPT>

</html>





Re: Internet Explorer Web Development IE7 Certificate Request/Enrollment

sophy jue

The code doesn't work in webpage, because X509CertificateRequestPkcs10.Initialize(Context) is not Webenabled. In webpage, some methods and properties that marked WebEnabled can work well.

If we want to do a simple certficate request demo, then we can use enroll.Initialize(Context) and then enroll.Create(encodeType).

If we want to specify some attributes of the certificate request, then we can set attributes to the privatekey and initialize the requestpkcs10 from the privatekey, and then initialize the enroll from the request.





Re: Internet Explorer Web Development IE7 Certificate Request/Enrollment

Garrett Wollman

I have run into this issue as well. I am not primarily a Windows user or developer; I am a CA administrator/developer, and the documentation that I have found is completely unhelpful. My CA currently uses the following Javascript to handle clients with IE:

// $Id: msenroll.js,v 1.2 2005/12/16 22:42:39 wollman Exp $
function install() {
var pkcs7data = document.getElementById("pkcs7data").firstChild.data;
enroll.acceptPKCS7(pkcs7data);
}
function genkey() {
// var keylen = parseInt(document.getElementById("keysize").value);
enroll.GenKeyFlags = (2048 * 65536) | 1;
document.getElementById("csr").value = enroll.createPKCS10("", "");
document.getElementById("submit").disabled = false;
document.getElementById("generate").disabled = true;
}

(The variable "enroll" is instantiated by an OBJECT element in the document which references this code.) What I need is an example to follow that does the same thing for Vista clients (preferably in a way that also works on XP/Server 2003 clients). Has anyone done this

While debugging this, I also noticed that the line numbers in the IE7 script error alert do not seem to bear much relationship to reality.




Re: Internet Explorer Web Development IE7 Certificate Request/Enrollment

suryaprakash

Because Widnows vista Microsoft is not supporting Xenroll.

For certificate enrollment the windows server uses xenroll active x control. But windows vista uses dula interface COM object known as CertEnroll.






Re: Internet Explorer Web Development IE7 Certificate Request/Enrollment

suryaprakash

<Script Language="VBSCRIPT">
Const ContextUser = 1
Const ContextMachine = 2
Const XCN_NCRYPT_ALLOW_EXPORT_FLAG = 1
Const XCN_NCRYPT_UI_NO_PROTECTION_FLAG = 0
Const XCN_NCRYPT_UI_PROTECT_KEY_FLAG = 1
</Script>
<Script Language="JavaScript">
function XEp_SetGenKeyFlags(objPrivateKey, nGenKeyFlags)
{

// some constants defined in wincrypt.h:
var CRYPT_EXPORTABLE=1;
var CRYPT_USER_PROTECTED=2;

objPrivateKey.KeyProtection = (0 != (CRYPT_USER_PROTECTED & nGenKeyFlags)) XCN_NCRYPT_UI_PROTECT_KEY_FLAG : XCN_NCRYPT_UI_NO_PROTECTION_FLAG;
objPrivateKey.ExportPolicy = (0 != (CRYPT_EXPORTABLE & nGenKeyFlags)) XCN_NCRYPT_ALLOW_EXPORT_FLAG : 0;
objPrivateKey.Length = nGenKeyFlags >> 16;



}

</Script>
<Script Language="VBSCRIPT">
Function CreateRequest(lFlags, ssDistinguishedName, sCertUsage)
On Error Resume Next
document.form1.CertRequest.value= _
XE_Enroll_CreateRequest(g_objEnroll, lFlags, ssDistinguishedName, sCertUsage)
CreateRequest=Err.Number
End Function

Function XE_Enroll_CreateRequest(objEnroll, lFlags, ssDistinguishedName, sCertUsage)
XE_Enroll_CreateRequest = objEnroll.CreateRequest(CRYPT_STRING_BASE64)
End Function

Function XE_Request_InitializeCspInformation( _
objRequest, objPrivateKey,bMachine,nKeySpec, nGenKeyFlags, _
sProviderName, nProviderType, sContainerName, bReuseKey )

Dim nContext
objPrivateKey.ProviderName = "Microsoft Enhanced RSA and AES Cryptographic Provider"
objPrivateKey.ProviderType = "24"
objPrivateKey.KeySpec = "1"
Call XEp_SetGenKeyFlags(objPrivateKey, nGenKeyFlags)
nContext = ContextUser
objPrivateKey.MachineContext = bMachine
On Error Resume Next
Call objRequest.InitializeFromPrivateKey(nContext, objPrivateKey, "")
' True=bLH
If 0<>Err.Number Then
XE_Request_InitializeCspInformation = Err.Number
Exit Function
Else
XE_Request_InitializeCspInformation = 0
End If
End Function


Function XE_InitializeCmcObject()
g_objRequestCmc.InitializeFromInnerRequest(g_objRequest)
End Function
Function XE_InitializeEnrollObject(objRequest)
g_objEnroll.InitializeFromRequest(objRequest)
End Function


Function XE_Request_AddDistinguishedName(objRequest, sDN)
Const XCN_CERT_NAME_STR_NONE = 0
Dim X500DistinguishedName
Set X500DistinguishedName = g_objClassFactory.CreateObject("X509Enrollment.CX500DistinguishedName")
Call X500DistinguishedName.Encode(sDN, XCN_CERT_NAME_STR_NONE)
objRequest.Subject = X500DistinguishedName
End Function

</Script>
<Script Language="JavaScript">
//----------------------------------------------------------------
// convert a (signed) number into a (unsigned) hex string
function toHex(number) {
var sRight=(number&0x0FFFFFFF).toString(16).toUpperCase();
sRight="0000000".substring(0, 7-sRight.length)+sRight;
return ((number>>28)&0x0000000F).toString(16).toUpperCase()+sRight;
}
</Script>
<Script Language="VBScript">

<% If Session("Vista") = "vista" Then %>
Dim g_objClassFactory
Dim g_objEnroll
Dim g_objPrivateKey
Dim g_objRequest
Dim g_objRequestCMC

Set g_objClassFactory = CreateObject("X509Enrollment.CX509EnrollmentWebClassFactory")
Set g_objEnroll = g_objClassFactory.CreateObject("X509Enrollment.CX509Enrollment")
Set g_objPrivateKey = g_objClassFactory.CreateObject("X509Enrollment.CX509PrivateKey")
Set g_objRequest = g_objClassFactory.CreateObject("X509Enrollment.CX509CertificateRequestPkcs10")
Set g_objRequestCMC = g_objClassFactory.CreateObject("X509Enrollment.CX509CertificateRequestCmc")
<%end if%>

</Script>
<script language="javascript" src="/CertRequest/BrowserCompatible.js"></script>
<Script Language="VBSCRIPT">
'-----------------------------------------------------------------
' IE SPECIFIC:
' call XEnroll to create a request, since javascript has no error handling
Function CreateRequest(lFlags, sDistinguishedName, sCertUsage)
On Error Resume Next
Call XE_ReuseHardwareKeyIfUnableToGenNew(False)
document.CertificateForm.CertRequest.value= _
XE_Enroll_CreateRequest(g_objEnroll, lFlags, sDistinguishedName, sCertUsage)
CreateRequest=Err.Number
End Function
</Script>

<script language="javascript">

var sDistinguishedName=""
+ "CN=\""+document.CertificateForm.txtName.value.replace(/"/g, "\"\"") +"\";"
+ "C=\""+document.CertificateForm.ddlCountry.value.replace(/"/g, "\"\"") +"\";"
+ "S=\""+document.CertificateForm.txtState.value.replace(/"/g, "\"\"") +"\";"
+ "L=\""+document.CertificateForm.txtCity.value.replace(/"/g, "\"\"") +"\";"
+ "OU=\""+document.CertificateForm.txtcompanyname.value.replace(/"/g, "\"\"") +"\";"
+ "E=\""+document.CertificateForm.txtEmail.value.replace(/"/g, "\"\"")+"\";";


//---Windows Vista.
var XECR_CMC=3;
var nResult;
var sCertUsage="1.3.6.1.5.5.7.3.2";

document.getElementById("CertAttrib").value ="UserAgent:<%=Request.ServerVariables("HTTP_USER_AGENT")%>\r\n"// navigator.userAgent.toLowerCase();
nResult = XE_Request_InitializeCspInformation(g_objRequest,g_objPrivateKey, false, "1", "0", "Microsoft Enhanced RSA and AES Cryptographic Provider", "24", "", false);
XE_Request_AddDistinguishedName(g_objRequest, sDistinguishedName);
XE_InitializeCmcObject();
bCmcInitialized = true;
XE_InitializeEnrollObject(g_objRequestCmc)
lRequestFlag=XECR_CMC;
nResult=CreateRequest(lRequestFlag, sDistinguishedName, sCertUsage);
</Script>






Re: Internet Explorer Web Development IE7 Certificate Request/Enrollment

cuijianming

The function which replaces the Xenroll::acceptPKCS7() seems to be CertEnroll::X509Enrollment::InstallResponse()



Re: Internet Explorer Web Development IE7 Certificate Request/Enrollment

Yishkim

When I create the request the way you have described I get the 80070005 error later on when I try to install it:

Sub Install_OnClick

Dim enroll

Dim result, Message

Set enroll = CreateObject("X509Enrollment.CX509Enrollment")

enroll.Initialize(1)

on error resume next

pkcs7 = Document.TheForm.pkcs7.Value

MsgBox(pkcs7)

a = enroll.InstallResponse(1, pkcs7, 1, "")

If ( err.Number = 0 ) Then

Message = "Your new certificate has been successfully installed!"

result = MsgBox (Message, 64, "Certificate Installation")

Else

Message = "Unable to install the certificate." & vbcrlf & vbcrlf

Message = Message & "Error code: " & Hex(err)

End If

End Sub

Any ideas why it happens





Re: Internet Explorer Web Development IE7 Certificate Request/Enrollment

cuijianming

If IE7 is running on Window Vista, You can set it to "run as administrator" by right click IE icon and select "run as administrator";

Or you can check the option box for "Run this program as an administrator" on Comatibility tab of IE property, since on Window vista IE is running as user mode even if you login as administrator