Create a CMC Request with Key Archival

Applies To: Windows Server 2008

First, create an exportable user private key. Next, create a USER CMC request for this existing key against a version 2 template with key archival turned on. Then, check the enroll status.

C#:
// Create a PKCS 10 inner request.
CX509CertificateRequestPkcs10Class pkcs10_req = new CX509CertificateRequestPkcs10Class();
pkcs10_req.InitializeFromTemplateName(X509CertificateEnrollmentContext.ContextUser,myTemplate);

// Get the CA Key Exchange Certificate
CCertRequestClass certreq = new CCertRequestClass();
string strCAcert = certreq.GetCACertificate(1, CAname, CR_OUT_BASE64);

// Create a CMC outer request and initialize
CX509CertificateRequestCmcClass cmc_req = new CX509CertificateRequestCmcClass();
cmc_req.InitializeFromInnerRequest(pkcs10_req);

// Set the CA Archive Key on the Request
cmc_req.set_KeyArchivalCertificate(EncodingType.XCN_CRYPT_STRING_BASE64, strCAcert);

// encode the request
cmc_req.Encode();

C++:
IX509CertificateRequestPkcs10*pkcs10_req = NULL;
IX509CertificateRequestCmc*cmc_req = NULL;
ICertRequest2*CertRequest = NULL;
BSTRstrCAcert = NULL;
HRESULThr = S_OK;

hr = CoCreateInstance(
        __uuidof(CX509CertificateRequestPkcs10),
        NULL,       // pUnkOuter
        CLSCTX_INPROC_SERVER,
        __uuidof(IX509CertificateRequestPkcs10),
        (void **) &pkcs10_req);
_JumpIfError(hr, error, _T("CoCreateInstance CX509CertificateRequestPkcs10"));

hr = pkcs10_req->InitializeFromTemplateName( ContextUser, myTemplate);
_JumpIfError(hr, error, _T("pkcs10_req->InitializeFromTemplateName"));


// Get the CA Key Exchange Certificate
hr = CoCreateInstance(CLSID_CCertRequest,
                      NULL,
                      CLSCTX_INPROC_SERVER,
                      IID_ICertRequest2,
                      (void **)&CertRequest);
_JumpIfError(hr, error, _T("CoCreateInstance CLSID_CCertRequest"));

hr = CertRequest->GetCACertificate( TRUE, CAName, CR_OUT_BASE64, &strCAcert );
_JumpIfError(hr, error, _T("CertRequest->GetCACertificate"));


// Create a CMC outer request and initialize
hr = CoCreateInstance(
        __uuidof(CX509CertificateRequestCmc),
        NULL,       // pUnkOuter
        CLSCTX_INPROC_SERVER,
        __uuidof(IX509CertificateRequestCmc),
        (void **) &cmc_req);
_JumpIfError(hr, error, _T("CoCreateInstance CX509CertificateRequestCmc"));


hr = cmc_req->InitializeFromInnerRequest(pkcs10_req);
_JumpIfError(hr, error, _T("cmc_req->InitializeFromInnerRequest"));


// Set the CA Archive Key on the Request
hr = cmc_req->put_KeyArchivalCertificate( XCN_CRYPT_STRING_BASE64, strCAcert);
_JumpIfError(hr, error, _T("cmc_req->put_KeyArchivalCertificate"));


hr = cmc_req->Encode();
_JumpIfError(hr, error, _T("cmc_req->Encode"));


goto noerror;

error:
if (NULL != cmc_req ) cmc_req->Release();

noerror:
if ( NULL != pkcs10_req ) pkcs10_req->Release();
if ( NULL != CertRequest ) CertRequest->Release();
if ( NULL != strCAcert ) SysFreeString( strCAcert );

Dim pkcs10_req
Set pkcs10_req = CreateObject( "X509Enrollment.CX509CertificateRequestPkcs10" )
pkcs10_req.InitializeFromTemplateName ContextUser, myTemplate

' Get the CA Key Exchange Certificate
Dim certreq, strCAcert
Set certreq = CreateObject( "CertificateAuthority.Request" )
strCAcert = certreq.GetCACertificate( 1, CAname, CR_OUT_BASE64 )

Dim cmc_req
Set cmc_req = CreateObject( "X509Enrollment.CX509CertificateRequestCmc" )
cmc_req.InitializeFromInnerRequest pkcs10_req

' Set the CA Archive Key on the Request
cmc_req.KeyArchivalCertificate = strCAcert
        
' encode the request
cmc_req.Encode

Dim pkcs10_req As New CX509CertificateRequestPkcs10Class
pkcs10_req.InitializeFromTemplateName( X509CertificateEnrollmentContext.ContextUser, myTemplate)

Dim strCAcert As String = New CCertRequestClass().GetCACertificate(1, CAname, CR_OUT_BASE64)
Dim cmc_req As New CX509CertificateRequestCmcClass
cmc_req.InitializeFromInnerRequest(pkcs10_req)
cmc_req.KeyArchivalCertificate = strCAcert
cmc_req.Encode()