证书吊销列表
[与此页面关联的功能(DirectShow)是一项旧功能。 它已被 MediaPlayer、IMFMediaEngine取代,并在媒体基金会 音频/视频捕获。 这些功能已针对 Windows 10 和 Windows 11 进行了优化。 Microsoft强烈建议新代码尽可能使用 MediaPlayer、IMFMediaEngine 和 Media Foundation 中的音频/视频捕获,而不是 DirectShow。 Microsoft建议重写使用旧 API 的现有代码,以尽可能使用新 API。]
本主题介绍如何在使用认证输出保护协议(COPP)时检查吊销驱动程序的证书吊销列表(CRL)。
CRL 包含已吊销证书的摘要,只能由Microsoft提供和签名。 CRL 通过数字权限管理(DRM)许可证分发。 CRL 可以撤销驱动程序证书链中的任何证书。 如果链中的任何证书被吊销,则该证书及其下的所有证书也会在链中吊销。
若要获取 CRL,应用程序必须使用 Windows 媒体格式 SDK 版本 9 或更高版本,并执行以下步骤:
- 调用 WMCreateReader 以创建 Windows 媒体格式 SDK 读取器对象。
- 查询 IWMDRMReader 接口的读取器对象。
- 调用 IWMDRMReader::GetDRMProperty,其值为 g_wszWMDRMNet_Revocation 以获取 CRL。 必须调用此方法两次:一次以获取要分配的缓冲区大小,一次用于填充缓冲区。 第二个调用返回包含 CRL 的字符串。 整个字符串是 base-64 编码的。
- 解码 base-64 编码字符串。 可以使用 CryptStringToBinary 函数执行此作。 此函数是 CryptoAPI 的一部分。
注意
若要使用 IWMDRMReader 接口,必须从Microsoft获取静态 DRM 库并将应用程序链接到此库文件。 有关详细信息,请参阅 Windows 媒体格式 SDK 文档中的主题“获取所需的 DRM 库”。
如果用户计算机上不存在 CRL,则 getDRMProperty 方法 返回NS_E_DRM_UNSUPPORTED_PROPERTY。 目前,获取 CRL 的唯一方法是获取 DRM 许可证。
以下代码显示了返回 CRL 的函数:
////////////////////////////////////////////////////////////////////////
// Name: GetCRL
// Description: Gets the certificate revocation list (CRL).
//
// ppBuffer: Receives a pointer to the buffer that contains the CRL.
// pcbBuffer: Receives the size of the buffer returned in ppBuffer.
//
// The caller must free the returned buffer by calling CoTaskMemFree.
////////////////////////////////////////////////////////////////////////
HRESULT GetCRL(BYTE **ppBuffer, DWORD *pcbBuffer)
{
IWMReader *pReader = NULL;
IWMDRMReader *pDrmReader = NULL;
HRESULT hr = S_OK;
// DRM attribute data.
WORD cbAttributeLength = 0;
BYTE *pDataBase64 = NULL;
WMT_ATTR_DATATYPE type;
// Buffer for base-64 decoded CRL.
BYTE *pCRL = NULL;
DWORD cbCRL = 0;
// Create the WMReader object.
hr = WMCreateReader(NULL, 0, &pReader);
// Query for the IWMDRMReader interface.
if (SUCCEEDED(hr))
{
hr = pReader->QueryInterface(
IID_IWMDRMReader, (void**)&pDrmReader);
}
// Call GetDRMProperty once to find the size of the buffer.
if (SUCCEEDED(hr))
{
hr = pDrmReader->GetDRMProperty(
g_wszWMDRMNET_Revocation,
&type,
NULL,
&cbAttributeLength
);
}
// Allocate a buffer.
if (SUCCEEDED(hr))
{
pDataBase64 = (BYTE*)CoTaskMemAlloc(cbAttributeLength);
if (pDataBase64 == NULL)
{
hr = E_OUTOFMEMORY;
}
}
// Call GetDRMProperty again to get the property.
if (SUCCEEDED(hr))
{
hr = pDrmReader->GetDRMProperty(
g_wszWMDRMNET_Revocation,
&type,
pDataBase64,
&cbAttributeLength
);
}
// Find the size of the buffer for the base-64 decoding.
if (SUCCEEDED(hr))
{
BOOL bResult = CryptStringToBinary(
(WCHAR*)pDataBase64, // Base-64 encoded string.
0, // Null-terminated.
CRYPT_STRING_BASE64,
NULL, // Buffer (NULL).
&cbCRL, // Receives the size of the buffer.
NULL, NULL // Optional.
);
if (!bResult)
{
hr = __HRESULT_FROM_WIN32(GetLastError());
}
}
// Allocate a buffer for the CRL.
if (SUCCEEDED(hr))
{
pCRL = (BYTE*)CoTaskMemAlloc(cbCRL);
if (pCRL == NULL)
{
hr = E_OUTOFMEMORY;
}
}
// Base-64 decode to get the CRL.
if (SUCCEEDED(hr))
{
BOOL bResult = CryptStringToBinary(
(WCHAR*)pDataBase64, // Base-64 encoded string.
0, // Null-terminated.
CRYPT_STRING_BASE64,
pCRL, // Buffer.
&cbCRL, // Receives the size of the buffer.
NULL, NULL // Optional.
);
if (!bResult)
{
hr = __HRESULT_FROM_WIN32(GetLastError());
}
}
// Return the buffer to the caller. Caller must free the buffer.
if (SUCCEEDED(hr))
{
*ppBuffer = pCRL;
*pcbBuffer = cbCRL;
}
else
{
CoTaskMemFree(pCRL);
}
CoTaskMemFree(pDataBase64);
SAFE_RELEASE(pReader);
SAFE_RELEASE(pDrmReader);
return hr;
}
接下来,应用程序必须验证 CRL 是否有效。 为此,请验证 CRL 证书(属于 CRL 的一部分)是否由Microsoft根证书直接签名,并将 SignCRL 元素值设置为 1。 此外,请验证 CRL 的签名。
验证 CRL 后,应用程序可以存储它。 在存储之前,还应检查 CRL 版本号,以便应用程序始终存储最新版本。
CRL 具有以下格式。
部分 | 内容 |
---|---|
页眉 | 32 位 CRL 版本 32 位条目数 |
吊销条目 | 多个 160 位吊销条目 |
证书 | 32 位证书 lengthVariable-length 证书 |
签名 | 8 位签名类型 16 位签名长度Variable-length 签名 |
注意
所有整数值都是无符号的,以 big-endian(网络字节顺序)表示法表示。
CRL 节说明
-
标头
-
标头包含 CRL 的版本号和 CRL 中的吊销条目数。 CRL 可以包含零个或多个条目。
-
吊销条目
-
每个吊销条目都是已吊销证书的 160 位摘要。 将此摘要与证书中的 DigestValue 元素进行比较。
-
证书
-
证书部分包含一个 32 位值,该值指示 XML 证书及其证书链的长度(以字节为单位),以及包含证书颁发机构(CA)的 XML 证书的字节数组,以及Microsoft为根的证书链。 证书必须由有权颁发 CRL 的 CA 签名。
注意
证书不得以 null 结尾。
-
签名
-
签名部分包含签名类型和长度,以及数字签名本身。 8 位类型设置为 2,以指示它使用 SHA-1 和 1024 位 RSA 加密。 长度是包含数字签名长度(以字节为单位)的 16 位值。 数字签名是在 CRL 的所有前几节上计算的。
签名是使用 PKCS #1(版本 2.1)中定义的 RSASSA-PSS 数字签名方案计算的。 哈希函数是 SHA-1,该函数在联邦信息处理标准(FIPS)180-2 中定义,掩码生成函数是 MGF1,该函数在 PKCS #1 的第 B.2.1 节(版本 2.1)中定义。 RSASP1 和 RSAVP1作使用具有 1024 位模数的 RSA,验证指数为 65537。
相关主题