Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Applies To: Windows Server 2008
The following code snippet samples show how to add various extensions to a request including Key Usage, Extended/Enhanced Key Usage, Template Name, Version 2 Template, Alternative Name, Basic Constraints, Certificate Policies, Subject Key Identifier, and Secure/Multipurpose Internet Mail Extensions (S/MIME) capabilities.
Key Usage
By default, when the KeyUsage extension is added to the request, it is marked as critical because the Key Usage OID (2.5.25.19") is included in the list of CriticalExtensions collection in the request. Extensions can be removed from the CriticalExtensions collection by calling the Remove method as follows.
C#:
// Remove Key Usage from Critical Extensions collection
for (int i = 0; i < request.CriticalExtensions.Count; i++)
{
if (request.CriticalExtensions[i].Value == "2.5.29.15")
{
request.CriticalExtensions.Remove(i);
break;
}
}
CX509ExtensionKeyUsageClass ku = new CX509ExtensionKeyUsageClass();
ku.InitializeEncode( CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE );
ku.Critical = true;
request.X509Extensions.Add((CX509Extension)ku);
VBScript:
' Remove Key Usage from Critical Extensions collection
Dim i
For i = 0 To request.CriticalExtensions.Count
If request.CriticalExtensions(i).Value = "2.5.29.15" Then
request.CriticalExtensions.Remove(i)
Exit For
End If
Next
Set ku = CreateObject( "X509Enrollment.CX509ExtensionKeyUsage" )
ku.InitializeEncode XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE
ku.Critical = False
request.X509Extensions.Add ku
VB.NET:
' Remove Key Usage from Critical Extensions collection
Dim I As Integer
For i = 0 To request.CriticalExtensions.Count
If request.CriticalExtensions(i).Value = "2.5.29.15" Then
request.CriticalExtensions.Remove(i)
Exit For
End If
Next
Dim ku As New CX509ExtensionKeyUsageClass
ku.InitializeEncode( CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE)
ku.Critical = False
request.X509Extensions.Add(DirectCast(ku, CX509Extension))
Extended/Enhanced Key Usage
C#:
CObjectIdClass EkuOid = new CObjectIdClass();
EkuOid.InitializeFromValue( "1.2.3.4.5.6.7.8.9" );
CObjectIdsClass EkuOids = new CObjectIdsClass();
EkuOids.Add(EkuOid);
CX509ExtensionEnhancedKeyUsageClass eku = new CX509ExtensionEnhancedKeyUsageClass();
eku.InitializeEncode( EkuOids );
eku.Critical = false;
request.X509Extensions.Add((CX509Extension)eku);
VBScript:
Set EkuOid = CreateObject( "X509Enrollment.CObjectId" )
EkuOid.InitializeFromValue "1.2.3.4.5.6.7.8.9"
Set EkuOids = CreateObject( "X509Enrollment.CObjectIds" )
EkuOids.Add EkuOid
Set eku = CreateObject("X509Enrollment.CX509ExtensionEnhancedKeyUsage")
eku.InitializeEncode EkuOids
eku.Critical = False
request.X509Extensions.Add eku
VB.NET:
Dim EkuOid As New CObjectIdClass
EkuOid.InitializeFromValue("1.2.3.4.5.6.7.8.9")
Dim EkuOids As New CObjectIdsClass
EkuOids.Add(EkuOid)
Dim eku As New CX509ExtensionEnhancedKeyUsageClass
eku.InitializeEncode(EkuOids)
eku.Critical = False
request.X509Extensions.Add(DirectCast(eku, CX509Extension))
Version 2 Template
C#:
CObjectIdClass V2TemplateOid = new CObjectIdClass();
V2TemplateOid.InitializeFromValue( "1.3.6.1.4.1.311.21.8.12345.67890.12345.6789012345.67890");
CX509ExtensionTemplateClass V2Template = new CX509ExtensionTemplateClass();
V2Template.InitializeEncode(V2TemplateOid, 101, 0);
request.X509Extensions.Add((CX509Extension)V2Template);
VBScript:
Set V2TemplateOid = CreateObject( "X509Enrollment.CObjectId" )
V2TemplateOid.InitializeFromValue "1.3.6.1.4.1.311.21.8.12345.67890.12345.6789012345.67890"
Set V2Template = CreateObject( "X509Enrollment.CX509ExtensionTemplate")
V2Template.InitializeEncode V2TemplateOid, 101, 0
request.X509Extensions.Add V2Template
VB.NET:
Dim V2TemplateOid As New CObjectIdClass
V2TemplateOid.InitializeFromValue( "1.3.6.1.4.1.311.21.8.12345.67890.12345.6789012345.67890")
Dim V2Template As New CX509ExtensionTemplateClass
V2Template.InitializeEncode(V2TemplateOid, &H65, 0)
request.X509Extensions.Add(DirectCast(V2Template, CX509Extension))
Alternative Name – User Principal Name (UPN)
C#:
CAlternativeNameClass altname = new CAlternativeNameClass();
altname.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_USER_PRINCIPLE_NAME, "upn@domain.com" );
CAlternativeNamesClass altnames = new CAlternativeNamesClass();
altnames.Add(altname);
CX509ExtensionAlternativeNamesClass altnameext = new CX509ExtensionAlternativeNamesClass();
altnameext.InitializeEncode(altnames);
request.X509Extensions.Add((CX509Extension)altnameext);
VBScript:
Set altname = CreateObject( "X509Enrollment.CAlternativeName" )
altname.InitializeFromString XCN_CERT_ALT_NAME_USER_PRINCIPLE_NAME, "upn@domain.com"
Set altnames = CreateObject( "X509Enrollment.CAlternativeNames" )
altnames.Add altname
Set altnameext = CreateObject( "X509Enrollment.CX509ExtensionAlternativeNames" )
altnameext.InitializeEncode altnames
request.X509Extensions.Add altnameext
VB.NET::
Dim altname As New CAlternativeNameClass
altname.InitializeFromString( AlternativeNameType.XCN_CERT_ALT_NAME_USER_PRINCIPLE_NAME, "upn@domain.com")
Dim altnames As New CAlternativeNamesClass
altnames.Add(altname)
Dim altnameext As New CX509ExtensionAlternativeNamesClass
altnameext.InitializeEncode(altnames)
request.X509Extensions.Add(DirectCast(altnameext, CX509Extension))
Certificate Policies
C#:
CObjectIdClass cpOid = new CObjectIdClass();
cpOid.InitializeFromValue( "2.3.4.5.6.7.8.9.0" );
CCertificatePolicyClass cp = new CCertificatePolicyClass();
CPolicyQualifierClass Qualifier = new CPolicyQualifierClass();
Qualifier.InitializeEncode( "Policy Notice", PolicyQualifierType.PolicyQualifierTypeUserNotice );
cp.Initialize( cpOid );
cp.PolicyQualifiers.Add( Qualifier );
CCertificatePoliciesClass cps = new CCertificatePoliciesClass();
cps.Add( cp );
CX509ExtensionCertificatePoliciesClass cpExt = new CX509ExtensionCertificatePoliciesClass();
cpExt.InitializeEncode( cps );
request.X509Extensions.Add((CX509Extension)cpExt);
VBScript:
Set cpOid = CreateObject( "X509Enrollment.CObjectId" )
cpOid.InitializeFromValue "2.3.4.5.6.7.8.9.0"
Set cp = CreateObject( "X509Enrollment.CCertificatePolicy" )
Set Qualifier = CreateObject( "X509Enrollment.CPolicyQualifier" )
Qualifier.InitializeEncode "Policy Notice", PolicyQualifierTypeUserNotice
cp.Initialize cpOid
cp.PolicyQualifiers.Add Qualifier
Set cps = CreateObject( "X509Enrollment.CCertificatePolicies" )
cps.Add cp
Set cpExt = CreateObject( "X509Enrollment.CX509ExtensionCertificatePolicies" )
cpExt.InitializeEncode cps
request.X509Extensions.Add cpExt
VB.NET:
Dim cpOid As New CObjectIdClass
cpOid.InitializeFromValue("2.3.4.5.6.7.8.9.0")
Dim cp As New CCertificatePolicyClass
Dim Qualifier As New CPolicyQualifierClass
Qualifier.InitializeEncode("Policy Notice", PolicyQualifierType.PolicyQualifierTypeUserNotice)
cp.Initialize(cpOid)
cp.PolicyQualifiers.Add(Qualifier)
Dim cps As New CCertificatePoliciesClass
cps.Add(cp)
Dim cpExt As New CX509ExtensionCertificatePoliciesClass
cpExt.InitializeEncode(cps)
request.X509Extensions.Add(DirectCast(cpExt, CX509Extension))
Subject Key ID
C#:
// Subject Key ID - Create the key pair before doing this as the SKI is derived from the public key.
request.PrivateKey.Create();
CX509ExtensionSubjectKeyIdentifierClass ski = new CX509ExtensionSubjectKeyIdentifierClass();
ski.InitializeEncode(EncodingType.XCN_CRYPT_STRING_BINARY, request.PublicKey.ComputeKeyIdentifier(KeyIdentifierHashAlgorithm.SKIHashSha1, EncodingType.XCN_CRYPT_STRING_BINARY));
request.X509Extensions.Add((CX509Extension)ski);
VBScript:
request.PrivateKey.Create
Dim ski
Set ski = CreateObject( "X509Enrollment.CX509ExtensionSubjectKeyIdentifier" )
ski.InitializeEncode XCN_CRYPT_STRING_BINARY, request.PublicKey.ComputeKeyIdentifier(SKIHashSha1)
request.X509Extensions.Add ski
VB.NET:
request.PrivateKey.Create()
Dim ski As New CX509ExtensionSubjectKeyIdentifierClass
ski.InitializeEncode(EncodingType.XCN_CRYPT_STRING_BINARY, request.PublicKey.ComputeKeyIdentifier(KeyIdentifierHashAlgorithm.SKIHashSha1))
request.X509Extensions.Add(DirectCast(ski, CX509Extension))
S/MIME Capabilities
C#:
// SMIME Capabilities - add all supported by the default RSA cryptographic provider
CSmimeCapabilitiesClass smimes = new CSmimeCapabilitiesClass();
smimes.AddAvailableSmimeCapabilities(false);
CX509ExtensionSmimeCapabilitiesClass smimeExt = new CX509ExtensionSmimeCapabilitiesClass();
smimeExt.InitializeEncode(smimes);
request.X509Extensions.Add((CX509Extension)smimeExt);
VBScript:
Dim smimes
Set smimes = CreateObject( "X509Enrollment.CSmimeCapabilities" )
smimes.AddAvailableSmimeCapabilities( False )
Dim smimeExt
Set smimeExt = CreateObject( "X509Enrollment.CX509ExtensionSmimeCapabilities" )
smimeExt.InitializeEncode smimes
request.X509Extensions.Add smimeExt
VB.NET:
' SMIME Capabilities - add all supported by the default RSA cryptographic provider
Dim smimes As New CSmimeCapabilitiesClass
smimes.AddAvailableSmimeCapabilities(False)
Dim smimeExt As New CX509ExtensionSmimeCapabilitiesClass
smimeExt.InitializeEncode(smimes)
request.X509Extensions.Add(DirectCast(smimeExt, CX509Extension))
Other Attributes
C#:
CX509AttributeOSVersionClass os = new CX509AttributeOSVersionClass();
os.InitializeEncode("9.8.7.6");
CX509AttributesClass attribs = new CX509AttributesClass();
attribs.Add((CX509Attribute)os);
CCryptAttributeClass atty = new CCryptAttributeClass();
atty.InitializeFromValues( attribs );
request.CryptAttributes.Add((CCryptAttribute)atty);
VBScript:
Set os = CreateObject( "X509Enrollment.CX509AttributeOSVersion" )
os.InitializeEncode "9.8.7.6"
Set attribs = CreateObject( "X509Enrollment.CX509Attributes" )
attribs.Add os
Set atty = CreateObject( "X509Enrollment.CCryptAttribute" )
atty.InitializeFromValues attribs
request.CryptAttributes.Add atty
VB.NET:
Dim os As New CX509AttributeOSVersionClass
os.InitializeEncode("9.8.7.6")
Dim attribs As New CX509AttributesClass
attribs.Add(DirectCast(os, CX509Attribute))
Dim atty As New CCryptAttributeClass
atty.InitializeFromValues(attribs)
request.CryptAttributes.Add(atty)
The previous code adds the following extensions to the request:
Certificate Extensions: 8
2.5.29.15: Flags = 1(Critical), Length = 4
Key Usage
Digital Signature (80)
2.5.29.37: Flags = 0, Length = c
Enhanced Key Usage
Unknown Key Usage (1.2.3.4.5.6.7.8.9)
1.3.6.1.4.1.311.20.2: Flags = 0, Length = a
Certificate Template Name (Certificate Type)
User
2.5.29.17: Flags = 0, Length = 22
Subject Alternative Name
Other Name:
Principal Name=upn@domain.com
2.5.29.19: Flags = 1(Critical), Length = 8
Basic Constraints
Subject Type=CA
Path Length Constraint=0
2.5.29.32: Flags = 0, Length = 3a
Certificate Policies
[1]Certificate Policy:
Policy Identifier=2.3.4.5.6.7.8.9.0
[1,1]Policy Qualifier Info:
Policy Qualifier Id=User Notice
Qualifier:
Notice Text=Policy Notice
2.5.29.14: Flags = 0, Length = 16
Subject Key Identifier
05 ed d3 b6 7c 84 f1 62 43 01 17 0c 04 e8 d8 61 f4 62 c9 8f
1.2.840.113549.1.9.15: Flags = 0, Length = 37
SMIME Capabilities
[1]SMIME Capability
Object ID=1.2.840.113549.3.2
Parameters=02 02 00 80
[2]SMIME Capability
Object ID=1.2.840.113549.3.4
Parameters=02 02 00 80
[3]SMIME Capability
Object ID=1.3.14.3.2.7
[4]SMIME Capability
Object ID=1.2.840.113549.3.7
Submitting a Request to an Online Enterprise CA
Figure 4 Advanced Enrollment Process
The following code shows how to submit a request to an Enterprise CA. Depending on the configuration of the requested template, the certificate may be issued immediately or the certificate may require later approval. In cases where a request is not immediately issued, the request identifier should be stored, and then, periodic polling should be used to detect when the request has been issued (or denied). Two functions are defined—the first function is SubmitRequest, which submits the request to a CA and the second function is used to poll for the status when a certificate has not been immediately issued.
C#:
static int SubmitRequest( IX509CertificateRequest req, string CANameStr )
{
CX509EnrollmentClass enroll = new CX509EnrollmentClass();
enroll.InitializeFromRequest( req );
string RequestStr = enroll.CreateRequest( EncodingType.XCN_CRYPT_STRING_BASE64);
CCertRequestClass CertRequest = new CCertRequestClass();
int Disposition = CertRequest.Submit( CR_IN_BASE64, RequestStr, "", CANameStr);
string StatusStr = "";
string DispStr = CertRequest.GetDispositionMessage();
if (Disposition != CR_DISP_ISSUED )
{
StatusStr = CertRequest.GetErrorMessageText( CertRequest.GetLastStatus(), 0) + " : " + DispStr;
}
switch (Disposition)
{
case CR_DISP_DENIED:
Console.WriteLine("Submit returned CR_DISP_DENIED - status " + StatusStr);
return -1;
case CR_DISP_ERROR:
Console.WriteLine("Submit returned CR_DISP_ERROR - status " + StatusStr);
return -1;
case CR_DISP_INCOMPLETE:
Console.WriteLine("Submit returned CR_DISP_INCOMPLETE - status " + StatusStr);
return -1;
case CR_DISP_ISSUED:
string Cert = CertRequest.GetFullResponseProperty( FR_PROP_FULLRESPONSE, 0, PROPTYPE_BINARY, CR_OUT_BASE64 ).ToString();
enroll.InstallResponse( InstallResponseRestrictionFlags.AllowNone, Cert, EncodingType.XCN_CRYPT_STRING_BASE64, "" );
return 0;
case CR_DISP_ISSUED_OUT_OF_BAND:
Console.WriteLine("Submit returned CR_DISP_ISSUED_OUT_OF_BAND - status " + StatusStr);
return -1;
case CR_DISP_UNDER_SUBMISSION:
return CertRequest.GetRequestId();
default:
Console.WriteLine("Submit returned " + Disposition + " - status " + StatusStr);
return -1;
}
}
static int GetResponse(string CANameStr, int ID, X509CertificateEnrollmentContext context)
{
CCertRequestClass CertRequest = new CCertRequestClass();
int Disposition = CertRequest.RetrievePending(ID, CANameStr);
if (Disposition == CR_DISP_ISSUED)
{
CX509EnrollmentClass enroll = new CX509EnrollmentClass();
string Cert = CertRequest.GetFullResponseProperty(FR_PROP_FULLRESPONSE, 0, PROPTYPE_BINARY, CR_OUT_BASE64).ToString();
enroll.Initialize(context);
enroll.InstallResponse(InstallResponseRestrictionFlags.AllowNone, Cert, EncodingType.XCN_CRYPT_STRING_BASE64, "");
}
return Disposition;
}
static void SubmitAndPollRequest(IX509CertificateRequest req, string CANameStr)
{
int ID = SubmitRequest(req, CANameStr);
// If the ID is > 0 then the request has not yet been issued - poll for the result.
while (ID > 0)
{
// Wait for a second and then poll to see if the certificate has been issued.
System.Threading.Thread.Sleep(1000);
int disp = GetResponse(CANameStr, ID, X509CertificateEnrollmentContext.ContextUser);
// Sometimes we get a denied during the time when the certificate is being issued.
if (disp == CR_DISP_DENIED)
{
// Wait for a couple of seconds and then poll to see if the certificate has been issued.
System.Threading.Thread.Sleep(2000);
disp = GetResponse(CANameStr, ID, X509CertificateEnrollmentContext.ContextUser);
}
if (disp == CR_DISP_ISSUED)
{
// The certificate was issued.
break;
}
// If the request has really been denied then bail out.
if (disp == CR_DISP_DENIED)
{
//Console.WriteLine("Request Denied");
break;
}
}
}
C++:
long SubmitRequest(IX509CertificateRequest* req, _TCHAR* CANameStr )
{
IX509Enrollment*enroll = NULL;
ICertRequest2*CertRequest = NULL;
BSTRRequestStr = NULL;
BSTRDispStr = NULL;
LONGRequestStatus = 0;
BSTRStatusStr = NULL;
HRESULThr = S_OK;
longID = 0;
VARIANTCert;
Cert.vt = VT_EMPTY;
hr = CoCreateInstance(
__uuidof(CX509Enrollment),
NULL, // pUnkOuter
CLSCTX_INPROC_SERVER,
__uuidof(IX509Enrollment),
(void **) &enroll);
_JumpIfError(hr, error, _T("CoCreateInstance CX509Enrollment"));
hr = enroll->InitializeFromRequest( req );
_JumpIfError(hr, error, _T("enroll->InitializeFromRequest"));
hr = enroll->CreateRequest( XCN_CRYPT_STRING_BASE64, &RequestStr );
_JumpIfError(hr, error, _T("enroll->CreateRequest"));
hr = CoCreateInstance(CLSID_CCertRequest,
NULL,
CLSCTX_INPROC_SERVER,
IID_ICertRequest2,
(void **)&CertRequest);
_JumpIfError(hr, error, _T("CoCreateInstance CCertRequest"));
long Disposition = 0;
hr = CertRequest->Submit( CR_IN_BASE64, RequestStr, _T(""), CANameStr, &Disposition );
_JumpIfError(hr, error, _T("CertRequest->Submit"));
hr = CertRequest->GetDispositionMessage( &DispStr );
_JumpIfError(hr, error, _T("CertRequest->GetDispositionMessage"));
if (Disposition != CR_DISP_ISSUED )
{
hr = CertRequest->GetLastStatus( &RequestStatus );
_JumpIfError(hr, error, _T("CertRequest->GetLastStatus"));
hr = CertRequest->GetErrorMessageText( RequestStatus, 0, &StatusStr );
_JumpIfError(hr, error, _T("CertRequest->GetErrorMessageText"));
}
if (Disposition == CR_DISP_ISSUED )
{
hr = CertRequest->GetFullResponseProperty( FR_PROP_FULLRESPONSE, 0, PROPTYPE_BINARY, CR_OUT_BASE64, &Cert );
_JumpIfError(hr, error, _T("CertRequest->GetFullResponseProperty"));
hr = enroll->InstallResponse(AllowNone, Cert.bstrVal, XCN_CRYPT_STRING_ANY, _T(""));
_JumpIfError(hr, error, _T("enroll->InstallResponse"));
}
else
{
if ( Disposition == CR_DISP_UNDER_SUBMISSION )
{
hr = CertRequest->GetRequestId( &ID );
_JumpIfError(hr, error, _T("CertRequest->GetRequestId"));
wprintf( L"Under Submission ID %d\n", ID );
}
else
{
wprintf( L"CertRequest Submit Failed, Disposition = %d, %s, %s\n", Disposition, DispStr, StatusStr );
ID = -1;
}
}
error:
SysFreeString(RequestStr);
SysFreeString(DispStr);
SysFreeString(StatusStr);
if ( NULL != enroll ) enroll->Release();
if ( NULL != CertRequest ) CertRequest->Release();
if ( VT_BSTR == Cert.vt ) SysFreeString( Cert.bstrVal );
return ID;
}
long GetResponse(_TCHAR* CANameStr, long ID, X509CertificateEnrollmentContext context )
{
IX509Enrollment*enroll = NULL;
ICertRequest2*CertRequest = NULL;
HRESULT hr = S_OK;
hr = CoCreateInstance(CLSID_CCertRequest,
NULL,
CLSCTX_INPROC_SERVER,
IID_ICertRequest2,
(void **)&CertRequest);
_JumpIfError(hr, error, _T("CoCreateInstance CCertRequest"));
long Disposition;
hr = CertRequest->RetrievePending( ID, CANameStr, &Disposition );
_JumpIfError(hr, error, _T("CertRequest->RetrievePending"));
if (Disposition == CR_DISP_ISSUED)
{
hr = CoCreateInstance(
__uuidof(CX509Enrollment),
NULL, // pUnkOuter
CLSCTX_INPROC_SERVER,
__uuidof(IX509Enrollment),
(void **) &enroll);
_JumpIfError(hr, error, _T("CoCreateInstance CX509Enrollment"));
VARIANT Cert;
hr = CertRequest->GetFullResponseProperty( FR_PROP_FULLRESPONSE, 0, PROPTYPE_BINARY, CR_OUT_BASE64, &Cert );
_JumpIfError(hr, error, _T("CertRequest->GetFullResponseProperty"));
hr = enroll->Initialize( context );
_JumpIfError(hr, error, _T("enroll->Initialize"));
hr = enroll->InstallResponse(AllowNone, Cert.bstrVal, XCN_CRYPT_STRING_ANY, _T(""));
_JumpIfError(hr, error, _T("enroll->InstallResponse"));
}
error:
if ( NULL != enroll ) enroll->Release();
if ( NULL != CertRequest ) CertRequest->Release();
return Disposition;
}
void SubmitAndPollRequest(IX509CertificateRequest* req, _TCHAR* CANameStr, X509CertificateEnrollmentContext context )
{
int ID = SubmitRequest(req, CANameStr );
// If the ID is > 0 then the request has not yet been issued - poll for the result.
while (ID > 0)
{
// Wait for a second and then poll to see if the certificate has been issued.
Sleep(1000);
int disp = GetResponse( CANameStr, ID, context );
printf( "disp = %d\n", disp );
// Sometimes we get a denied during the time when the certificate is being issued.
if (disp == CR_DISP_DENIED)
{
// Wait for a couple of seconds and then poll to see if the certificate has been issued.
Sleep(2000);
disp = GetResponse(CANameStr, ID, context );
}
if (disp == CR_DISP_ISSUED)
{
// The certificate was issued.
break;
}
// If the request has really been denied then bail out.
if (disp == CR_DISP_DENIED)
{
break;
}
}
}
VBScript:
Sub SubmitAndPollRequest(req, CANameStr, context )
Dim ID
Dim disp
ID = SubmitRequest(CANameStr, req )
While ID > 0
WScript.Sleep 1000
disp = GetResponse(CANameStr, ID, context )
If (disp = CR_DISP_DENIED) Then
WScript.Sleep 2000
disp = GetResponse(CANameStr, ID, context )
End If
If Disp = CR_DISP_ISSUED Or Disp = CR_DISP_DENIED Then
Exit Sub
End If
Wend
End Sub
Function SubmitRequest( CANameStr, Req )
Dim enrollment
Set enrollment = CreateObject( "X509Enrollment.CX509Enrollment" )
enrollment.InitializeFromRequest Req
Dim RequestStr
RequestStr = enrollment.CreateRequest( XCN_CRYPT_STRING_BASE64 )
Dim CertRequest
Set CertRequest = CreateObject( "CertificateAuthority.Request" )
Dim Disposition
Disposition = CertRequest.Submit( CR_IN_ENCODEANY Or CR_IN_FORMATANY, RequestStr, "", CANameStr )
Dim DispStr
DispStr = CertRequest.GetDispositionMessage()
Dim StatusStr
StatusStr = ""
If Disposition <> CR_DISP_ISSUED Then
StatusStr = CertRequest.GetErrorMessageText(CertRequest.GetLastStatus(), 0) & " : " & DispStr
End If
If Disposition = CR_DISP_ISSUED Then
Dim Cert
Cert = CertRequest.GetFullResponseProperty( FR_PROP_FULLRESPONSE, 0, PROPTYPE_BINARY, CR_OUT_BASE64 )
Call enrollment.InstallResponse( AllowNone, Cert, XCN_CRYPT_STRING_ANY, "" )
SubmitRequest = 0
Else
If Disposition = CR_DISP_UNDER_SUBMISSION Then
SubmitRequest = CertRequest.GetRequestId
Else
SubmitRequest = -1
WScript.echo "Submit failed - Disposition = " & Disposition & " Status " & StatusStr
End If
End If
End Function
Function GetResponse( CANameStr, ID, context )
Dim CertRequest
Set CertRequest = CreateObject( "CertificateAuthority.Request" )
Dim Disposition
Disposition = CertRequest.RetrievePending( ID, CANameStr )
If Disposition = CR_DISP_ISSUED Then
Dim enrollment
Set enrollment = CreateObject( "X509Enrollment.CX509Enrollment" )
Dim Cert
Cert = CertRequest.GetFullResponseProperty( FR_PROP_FULLRESPONSE, 0, PROPTYPE_BINARY, CR_OUT_BASE64 )
enrollment.Initialize context
enrollment.InstallResponse AllowNone, Cert, XCN_CRYPT_STRING_ANY, ""
End If
GetResponse = Disposition
End Function
VB.NET:
Private Shared Function SubmitRequest(ByVal req As IX509CertificateRequest, ByVal CANameStr As String) As Integer
Dim enroll As New CX509EnrollmentClass
enroll.InitializeFromRequest(req)
Dim RequestStr As String = enroll.CreateRequest(EncodingType.XCN_CRYPT_STRING_BASE64)
Dim CertRequest As New CCertRequestClass
Dim Disposition As Integer = CertRequest.Submit(CR_IN_BASE64, RequestStr, "", CANameStr)
Dim StatusStr As String = ""
Dim DispStr As String = CertRequest.GetDispositionMessage()
If Disposition <> CR_DISP_ISSUED Then
StatusStr = CertRequest.GetErrorMessageText(CertRequest.GetLastStatus(), 0) & " : " & DispStr
End If
Select Case Disposition
Case CR_DISP_ISSUED
Dim Cert As String = CertRequest.GetFullResponseProperty(FR_PROP_FULLRESPONSE, 0, PROPTYPE_BINARY, CR_OUT_BASE64).ToString
enroll.InstallResponse(InstallResponseRestrictionFlags.AllowNone, Cert, EncodingType.XCN_CRYPT_STRING_BASE64, "")
Return 0
Case CR_DISP_UNDER_SUBMISSION
Return CertRequest.GetRequestId
Case CR_DISP_DENIED
Console.WriteLine("Submit CR_DISP_DENIED " & StatusStr)
Case CR_DISP_ERROR
Console.WriteLine("Submit CR_DISP_DENIED " & StatusStr)
Case CR_DISP_INCOMPLETE
Console.WriteLine("Submit CR_DISP_DENIED " & StatusStr)
Case CR_DISP_ISSUED_OUT_OF_BAND
Console.WriteLine("Submit CR_DISP_DENIED " & StatusStr)
Case Else
Console.WriteLine("Submit Error " & Disposition & " : " & StatusStr)
End Select
Return -1
End Function
Private Shared Function GetResponse(ByVal CANameStr As String, ByVal ID As Integer, ByVal context As X509CertificateEnrollmentContext) As Integer
Dim CertRequest As New CCertRequestClass
Dim Disposition As Integer = CertRequest.RetrievePending(ID, CANameStr)
If (Disposition = CR_DISP_ISSUED) Then
Dim enroll As New CX509EnrollmentClass
Dim Cert As String = CertRequest.GetFullResponseProperty(FR_PROP_FULLRESPONSE, 0, PROPTYPE_BINARY, CR_OUT_BASE64).ToString
enroll.Initialize(context)
enroll.InstallResponse(InstallResponseRestrictionFlags.AllowNone, Cert, EncodingType.XCN_CRYPT_STRING_BASE64, "")
End If
Return Disposition
End Function
Private Shared Sub SubmitAndPollRequest(ByVal req As IX509CertificateRequest, ByVal CANameStr As String, ByVal context As X509CertificateEnrollmentContext)
Dim ID As Integer
Dim disp As Integer
ID = SubmitRequest(req, CANameStr)
' If the ID is > 0 then the request has not yet been issued - poll for the result.
While ID > 0
System.Threading.Thread.Sleep(1000)
disp = GetResponse(CANameStr, ID, X509CertificateEnrollmentContext.ContextUser)
' Sometimes we get a denied during the time when the certificate is being issued.
If (disp = CR_DISP_DENIED) Then
' Wait for a couple of seconds and then poll to see if the certificate has been issued.
System.Threading.Thread.Sleep(2000)
disp = GetResponse(CANameStr, ID, X509CertificateEnrollmentContext.ContextUser)
End If
If disp = CR_DISP_ISSUED Then
Exit While
End If
If disp = CR_DISP_DENIED Then
Exit While
End If
End While
End Sub