Пример получения доказательств достоверности подписи из удостоверяющей подписи с помощью низкоуровневых функций КриптоПро ЭЦП SDK
C++
HCRYPTMSG hMsg = CryptMsgOpenToDecode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0,0,0,0,0);
if(!hMsg)
{
std::cout << "CryptMsgOpenToDecode() failed" << std::endl;
return;
}
if(!CryptMsgUpdate(hMsg,&message[0],(DWORD)message.size(),TRUE))
{
CryptMsgClose(hMsg);
std::cout << "CryptMsgUpdate() failed" << std::endl;
return;
}
// Получение неподписанных атрибутов. Одним из неподписанных атрибутов
// является удостоверяющая подпись (countersignature).
DWORD size = 0;
if(!CryptMsgGetParam(hMsg,CMSG_SIGNER_UNAUTH_ATTR_PARAM,0,0,&size))
{
CryptMsgClose(hMsg);
std::cout << "CryptMsgGetParam() failed" << std::endl;
return;
}
std::vector<BYTE> paramBlob(size);
if(!CryptMsgGetParam(hMsg,CMSG_SIGNER_UNAUTH_ATTR_PARAM,0,¶mBlob[0],&size))
{
CryptMsgClose(hMsg);
std::cout << "CryptMsgGetParam() failed" << std::endl;
return;
}
paramBlob.resize(size);
PCRYPT_ATTRIBUTES pAttrs = reinterpret_cast<PCRYPT_ATTRIBUTES>(¶mBlob[0]);
// Сообщение больше не понадобится.
if(!CryptMsgClose(hMsg))
{
std::cout << "CryptMsgClose() failed" << std::endl;
return;
}
// Поиск атрибута в котором храниться удостоверяющая подпись. В этом
// примере берётся первая найденная подпись, но в дейтсвительности их
// может быть несколько.
CRYPT_DATA_BLOB countersignatureBlob = {0,0};
for( DWORD i = 0; i < pAttrs->cAttr; ++i)
{
PCRYPT_ATTRIBUTE pAttr = &pAttrs->rgAttr[i];
if( std::string(szOID_RSA_counterSign) == pAttr->pszObjId )
{
if(!pAttr->cValue)
continue;
countersignatureBlob.pbData = pAttr->rgValue[0].pbData;
countersignatureBlob.cbData = pAttr->rgValue[0].cbData;
break;
}
}
if(!countersignatureBlob.cbData)
{
std::cout << "Countersignature not found" << std::endl;
return;
}
// Атрибут удостоверяющей подписи имеет формат CMSG_SIGNER_INFO,
// и его можно раскодировать с помощью CryptDecodeObject().
size = 0;
if(!CryptDecodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
PKCS7_SIGNER_INFO,countersignatureBlob.pbData,
countersignatureBlob.cbData,0,0,&size))
{
std::cout << "CryptDecodeObject() failed" << std::endl;
return;
}
std::vector<BYTE> decodeBlob(size);
if(!CryptDecodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
PKCS7_SIGNER_INFO,countersignatureBlob.pbData,
countersignatureBlob.cbData,0,&decodeBlob[0],&size))
{
std::cout << "CryptDecodeObject() failed" << std::endl;
return;
}
PCMSG_SIGNER_INFO pSignerInfo =
reinterpret_cast<PCMSG_SIGNER_INFO>(&decodeBlob[0]);
ALG_ID hashAlgId = CadesMsgGetSigningCertIdHashAlgEx(pSignerInfo);
if(!hashAlgId)
{
std::cout << "CadesMsgGetSigningCertIdHashAlg() failed" << std::endl;
return;
}
PCADES_BLOB_ARRAY pTimestamps = 0;
if(!CadesMsgGetSignatureTimestampsEx(pSignerInfo, &pTimestamps))
{
std::cout << "CadesGetSignatureTimestamps() failed" << std::endl;
return;
}
if(!CadesFreeBlobArray(pTimestamps))
{
std::cout << "CadesFreeBlobArray() failed" << std::endl;
return;
}
PCADES_BLOB_ARRAY pCerts = 0;
if(!CadesMsgGetCertificateValuesEx(pSignerInfo, &pCerts))
{
std::cout << "CadesGetCertificateValues() failed" << std::endl;
return;
}
if(!CadesFreeBlobArray(pCerts))
{
std::cout << "CadesFreeBlobArray() failed" << std::endl;
return;
}
PCADES_BLOB_ARRAY pCRLs = 0;
PCADES_BLOB_ARRAY pOCSPs = 0;
if(!CadesMsgGetRevocationValuesEx(pSignerInfo, &pCRLs, &pOCSPs))
{
std::cout << "CadesGetRevocationValues() failed" << std::endl;
return;
}
PCADES_BLOB_ARRAY pCadesCTimestamps = 0;
if(!CadesMsgGetCadesCTimestampsEx(pSignerInfo, &pCadesCTimestamps))
{
std::cout << "CadesMsgGetCadesCTimestamps() failed" << std::endl;
return;
}
if(!CadesFreeBlobArray(pCadesCTimestamps))
{
std::cout << "CadesFreeBlobArray() failed" << std::endl;
return;
}
if(!CadesFreeBlobArray(pCRLs))
{
CadesFreeBlobArray(pOCSPs);
std::cout << "CadesFreeBlobArray() failed" << std::endl;
return;
}
if(!CadesFreeBlobArray(pOCSPs))
{
std::cout << "CadesFreeBlobArray() failed" << std::endl;
return;
}
std::cout << "All CAdES countersignature attributes obtained successfully." << std::endl;