Пример получения доказательств достоверности подписи из удостоверяющей подписи с помощью низкоуровневых функций КриптоПро ЭЦП 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; } 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;