Развернуть все
Свернуть все

Получение доказательств из удостоверяющей подписи

Пример получения доказательств достоверности подписи из удостоверяющей подписи с помощью низкоуровневых функций КриптоПро ЭЦП 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,&paramBlob[0],&size))
    {
        CryptMsgClose(hMsg);
        std::cout << "CryptMsgGetParam() failed" << std::endl;
        return;
    }
    PCRYPT_ATTRIBUTES pAttrs = reinterpret_cast<PCRYPT_ATTRIBUTES>(&paramBlob[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;