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

IE7 Certificate Request/Enrollment
Ceres629
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>
gmeadows94410
<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>
Sriman
Hi,
If you test the object you created by using IsObject function, You may find that the result is false.
plaszlo
simon chow
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.
carjo
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>
GrandpaB
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.
invoke
In my experience, the API is a PAIN.
VashTheStampede
// $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.
Drudkh
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
J. Clark
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
Grant Jenkins
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.
Ronaldlee Ejalu
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.
NickNotYet
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.