Richiesta di un certificato di archiviazione delle chiavi
Nell'esempio seguente viene illustrata la creazione e l'invio di una richiesta di certificato e la ricezione del certificato di archiviazione della chiave risultante. Affinché questo esempio abbia esito positivo, l'autorità di certificazione (CA) che riceve la richiesta di certificato deve essere configurata per l'archiviazione delle chiavi.
I passaggi seguenti descrivono come creare e inviare una richiesta di certificato.
Per creare e inviare una richiesta di certificato
- Recuperare il certificato di scambio della CA usando il metodo ICertRequest2::GetCACertificate.
- Specificare che il certificato di scambio CA recuperato è il certificato di archiviazione chiavi usando la proprietà ICEnroll4::PrivateKeyArchiveCertificate.
- Creare una richiesta di certificato CMC usando il metodo ICEnroll4::createRequest.
- Inviare la richiesta di certificato a una CA usando il metodo ICertRequest2::Submit. La CA deve essere configurata per supportare l'archiviazione delle chiavi.
I passaggi seguenti descrivono come recuperare il certificato rilasciato a scopo di archiviazione delle chiavi.
Per recuperare il certificato rilasciato a scopo di archiviazione delle chiavi
- Recuperare la risposta completa, incluso il certificato rilasciato, usando il metodo ICertRequest2::GetFullResponseProperty.
- Installare il certificato rilasciato usando il metodo ICEnroll4::acceptResponse.
Nell'esempio seguente viene illustrata la creazione e l'invio di una richiesta di certificato e la ricezione del certificato di archiviazione della chiave risultante.
// Pointer to interface objects.
ICEnroll4 * pEnroll = NULL;
ICertRequest2 * pRequest = NULL;
// BSTR variables.
BSTR bstrCACert = NULL;
BSTR bstrDN = NULL;
BSTR bstrCertAuth = NULL;
BSTR bstrReq = NULL;
BSTR bstrDispMsg = NULL;
BSTR bstrErrorMsg = NULL;
VARIANT varFullResp;
LONG lDisp =0;
LONG lRequestID = 0;
LONG lStatus = 0;
HRESULT hr;
// Initialize COM.
hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
if ( FAILED( hr ) )
{
printf("Failed CoInitializeEx - [%x]\n", hr);
goto error;
}
// Create an instance of the Certificate Enrollment object.
hr = CoCreateInstance( CLSID_CEnroll,
NULL,
CLSCTX_INPROC_SERVER,
IID_ICEnroll4,
(void **)&pEnroll);
if ( FAILED( hr ) )
{
printf("Failed CoCreateInstance - pEnroll [%x]\n", hr);
goto error;
}
// Create an instance of the Certificate Request object.
hr = CoCreateInstance( CLSID_CCertRequest,
NULL,
CLSCTX_INPROC_SERVER,
IID_ICertRequest2,
(void **)&pRequest);
if ( FAILED( hr ) )
{
printf("Failed CoCreateInstance - pRequest [%x]\n", hr);
goto error;
}
// Allocate the BSTR that represents the certification authority.
// Note the use of '\\' to produce a single '\' in C++.
bstrCertAuth = SysAllocString(L"Server\\CertAuth");
if (NULL == bstrCertAuth)
{
printf("Failed SysAllocString\n");
goto error;
}
// Retrieve the CA's exchange certificate.
hr = pRequest->GetCACertificate(TRUE,
bstrCertAuth,
CR_OUT_BASE64HEADER,
&bstrCACert);
if (FAILED(hr))
{
printf("Failed GetCACertificate [%x]\n", hr);
goto error;
}
// Specify the retrieved certificate
// as the key archive certificate.
hr = pEnroll->put_PrivateKeyArchiveCertificate(bstrCACert);
if (FAILED(hr))
{
printf("put_PrivateKeyArchiveCertificate [%x]\n", hr);
goto error;
}
// Create the data for the request.
// A user interface or database retrieval could
// be used instead of this example's hard-coded text.
bstrDN = SysAllocString(L"CN=UserName" // common name
L",OU=UserUnit" // org unit
L",O=UserOrg" // org
L",L=UserCity" // locality
L",S=WA" // state
L",C=US"); // country/region
if (NULL == bstrDN)
{
printf("Failed SysAllocString\n");
goto error;
}
// Create the certificate request.
hr = pEnroll->createRequest( XECR_CMC,
bstrDN,
NULL,
&bstrReq );
if ( FAILED( hr ) )
{
printf("Failed createRequest - [%x]\n", hr);
goto error;
}
// Submit the certificate request.
hr = pRequest->Submit( CR_IN_CMC,
bstrReq,
NULL,
bstrCertAuth,
&lDisp );
if ( FAILED( hr ) )
{
printf("Failed Submit - [%x]\n", hr);
goto error;
}
// Evaluate the disposition of the submitted request.
switch (lDisp)
{
case CR_DISP_ISSUED:
printf("Certificate was issued.\n");
break;
case CR_DISP_ISSUED_OUT_OF_BAND:
case CR_DISP_INCOMPLETE:
case CR_DISP_ERROR:
case CR_DISP_DENIED:
case CR_DISP_UNDER_SUBMISSION:
case CR_DISP_REVOKED:
printf("Certificate was not issued: %d\n", lDisp);
break;
default:
printf("Unexpected disposition: %d\n", lDisp);
goto error;
}
// Retrieve the request ID.
hr = pRequest->GetRequestId(&lRequestID);
if ( FAILED(hr) )
{
printf("Failed GetRequestId - [%x]\n", hr);
goto error;
}
printf("The request ID is %d\n", lRequestID);
if (CR_DISP_ISSUED != lDisp)
{
// Provide information about why a certificate
// was not issued.
// Retrieve the last status.
hr = pRequest->GetLastStatus(&lStatus);
if ( FAILED(hr) )
{
printf("Failed GetLastStatus - [%x]\n", hr);
goto error;
}
// Retrieve the disposition message.
hr = pRequest->GetDispositionMessage(&bstrDispMsg);
if ( FAILED(hr) )
{
printf("Failed GetDispositionMessage - [%x]\n", hr);
goto error;
}
// Retrieve the error message.
hr = pRequest->GetErrorMessageText(lStatus,
CR_GEMT_HRESULT_STRING,
&bstrErrorMsg);
if ( FAILED(hr) )
{
printf("Failed GetErrorMessageText - [%x]\n", hr);
goto error;
}
// Display the information and exit.
printf("Request ID: %d\nDisposition: %S\nError: %S\n",
lRequestID,
bstrDispMsg,
bstrErrorMsg);
goto error;
}
// Retrieve the full response.
VariantInit(&varFullResp);
hr = pRequest->GetFullResponseProperty( FR_PROP_FULLRESPONSE,
0,
PROPTYPE_BINARY,
CR_OUT_BASE64,
&varFullResp );
if ( FAILED( hr ) )
{
printf("Failed GetFullResponseProperty - [%x]\n", hr);
goto error;
}
// Accept the response.
hr = pEnroll->acceptResponse(varFullResp.bstrVal);
if ( FAILED( hr ) )
{
printf("Failed AcceptResponse - [%x]\n", hr);
goto error;
}
else
{
printf("Successfully completed processing\n");
}
error:
// Done processing.
// Clean up object resources.
if ( NULL != pEnroll )
pEnroll->Release();
if ( NULL != pRequest )
pRequest->Release();
// Free BSTR variables.
if ( NULL != bstrCACert )
SysFreeString ( bstrCACert );
if ( NULL != bstrDN )
SysFreeString ( bstrDN );
if ( NULL != bstrCertAuth )
SysFreeString ( bstrCertAuth );
if ( NULL != bstrReq )
SysFreeString ( bstrReq );
if ( NULL != bstrDispMsg )
SysFreeString ( bstrDispMsg );
if ( NULL != bstrErrorMsg )
SysFreeString ( bstrErrorMsg );
// Clear VARIANTS.
VariantClear(&varFullResp);
// Free COM resources.
CoUninitialize();
return hr;