ドキュメントに証明書チェーンを埋め込む
このトピックでは、証明書チェーンを構成する証明書を XPS ドキュメントに埋め込む方法について説明します。 証明書チェーンは、ルート証明書を除くすべての証明書で構成され、end certificate によって識別されるサブジェクトを認定するために必要です。
XPS ドキュメントに証明書チェーンを埋め込むには、次のコード例に示すように、まず証明書チェーンを作成します。
コード例の CreateCertificateChain メソッドは、パラメーターとして certificateStore を受け入れます。これは HCERTSTORE 値です。 この値が NULL の場合、証明書はクライアント コンピューターの証明書サーバーから取得されます。 値が証明書ストアへのハンドルである場合、証明書は certificateStore によって参照されるそのストアから、およびクライアント コンピューターの証明書サーバーから取得されます。
HRESULT
CreateCertificateChain (
__in PCCERT_CONTEXT certificate,
__in HCERTSTORE certificateStore,
__out PCCERT_CHAIN_CONTEXT* certificateChain
)
{
HRESULT hr = S_OK;
CERT_CHAIN_PARA certificateChainParameters = {0};
certificateChainParameters.cbSize = sizeof(CERT_CHAIN_PARA);
certificateChainParameters.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND;
// CertGetCertificateChain builds a certificate chain that starts
// from the PCCERT_CONTEXT structure provided by the caller.
// After the certificate chain has been successfully created,
// then the authenticity of the certificate can be determined
// by examining the errors, if any, that occurred while the chain
// was created.
BOOL successCreatingCertChain = CertGetCertificateChain (
NULL,
certificate,
NULL,
certificateStore,
&certificateChainParameters,
CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT,
NULL,
certificateChain);
if (!successCreatingCertChain)
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
return hr;
}
次のコード例では、証明書から証明書チェーンを作成し、これらの証明書を XPS ドキュメントに追加します。 CertGetCertificateChain は、署名証明書が最初で、ルート証明書が最後である証明書チェーンを作成します。 この例では、署名証明書とルート証明書は追加されません。 署名証明書は、ドキュメントで最後に呼び出される署名メソッドである IXpsSignatureManager::Sign メソッドの呼び出しと共に追加されます。 ルート証明書は、署名の検証時にクライアント コンピューターの証明書サーバーによって提供される必要があるため、ドキュメントの署名時には追加されません。
HRESULT
EmbedCertificateChainInXpsPackage (
__in IXpsSigningOptions *signingOptions,
__in PCCERT_CONTEXT signingCertificate
)
{
HRESULT hr = S_OK;
PCCERT_CHAIN_CONTEXT certificateChainContext = NULL;
IOpcCertificateSet *certificateSetToUpdate = NULL;
DWORD certificateChainContextIndex = 0;
// Create the entire certificate chain that originates
// from the certificate that is used to sign the XPS document.
hr = CreateCertificateChain(
signingCertificate,
NULL,
&certificateChainContext);
if (SUCCEEDED(hr))
{
// The signing options of an XPS document contain a pointer to
// an IOpcCertificateSet interface that can be retrieved by
// calling the GetCertificateSet method.
hr = signingOptions->GetCertificateSet(&certificateSetToUpdate);
}
if (SUCCEEDED(hr))
{
// for each certificate chain context in this certificate...
for (certificateChainContextIndex = 0;
certificateChainContextIndex < certificateChainContext->cChain;
certificateChainContextIndex++)
{
// inside a certificate chain context,
DWORD adjustedSimpleChainStartIndex = 0;
DWORD adjustedSimpleChainEndIndex = 0;
DWORD simpleCertChainIndex = 0;
CERT_SIMPLE_CHAIN *simpleCertificateChainWithinContext = NULL;
// get the information about the certificate chain
// set the first item in the certificate chain to load
// Ignore the first PCCERT_CONTEXT in the first CERT_SIMPLE_CHAIN
// because this is the certificate that was used to build
// the chain and is already loaded in the document
if (certificateChainContextIndex == 0)
{
adjustedSimpleChainStartIndex = 1;
}
else
{
adjustedSimpleChainStartIndex = 0;
}
// get the last item in the certificate chain
simpleCertificateChainWithinContext =
certificateChainContext->rgpChain[certificateChainContextIndex];
adjustedSimpleChainEndIndex =
simpleCertificateChainWithinContext->cElement;
// Ignore the last PCCERT_CONTEXT in the last CERT_SIMPLE_CHAIN
// because this is the root certificate that must be retrieved
// from the client computer's certificate server.
if (certificateChainContextIndex == certificateChainContext->cChain - 1)
{
if (adjustedSimpleChainEndIndex != 0)
{
adjustedSimpleChainEndIndex = adjustedSimpleChainEndIndex - 1;
}
}
// for each certificate chain in this context...
for (simpleCertChainIndex = adjustedSimpleChainStartIndex;
simpleCertChainIndex < adjustedSimpleChainEndIndex;
simpleCertChainIndex++)
{
// Add the certificate to the XPS document.
PCCERT_CONTEXT certificateToEmbed =
simpleCertificateChainWithinContext->rgpElement[simpleCertChainIndex]->pCertContext;
if (FAILED(hr = certificateSetToUpdate->Add(certificateToEmbed)))
{
break; // out of for loop with failed hr
}
}
}
}
return hr;
}
関連トピック
-
次のステップ
-
この例で使用
-
詳細情報