Проверки есть, просто я убрал их для краткости, ошибок нет и подпись создается, на выходе 2 файла что прикреплял выше
bool CoSignMessage(/* options &opt*/ ) {
if (!FileExists(opt.file_in) || !DirExists(SplitFilename(opt.file_out).path)) {
cout << "File or dir not exists check file_in and file_out parameters\n";
return false;
}
if (opt.crt_serial.empty()) {
cout << "Certificate Serial empty" << endl;
return false;
}
HCERTSTORE hStoreHandle = CertOpenSystemStore(0, _TEXT("MY"));
// Ищем сертификат в хранилище по серийному номеру
PCCERT_CONTEXT context = FindCertificate(hStoreHandle, opt.crt_serial);
if (context == NULL) {
cout << "Certificate has not this Serial " << endl;
return false;
}
// Если сертификат не найден, завершаем работу
if (!context) {
cout << "There is no certificate with a CERT_KEY_CONTEXT_PROP_ID " << endl
<< "property and an AT_KEYEXCHANGE private key available." << endl
<< "While the message could be sign, in this case, it could" << endl
<< "not be verify in this program." << endl
<< "For more information, read the documentation
http://cpdn.cryptopro.ru/" << endl;
return false;
}
int mustFree;
DWORD dwKeySpec = 0;
HCRYPTPROV hProv;
// Получаем ссылку на закрытый ключ сертификата и дестриптор криптопровайдера
if (!CryptAcquireCertificatePrivateKey(context, 0, 0, &hProv, &dwKeySpec, &mustFree)) {
cout << "CryptAcquireCertificatePrivateKey() failed" << "GetLastError() = " << GetLastError() << endl;
CertFreeCertificateContext(context);
return false;
}
const auto encodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
HCRYPTMSG hMsg = CryptMsgOpenToDecode(encodingType, (opt.detached ? CMSG_DETACHED_FLAG : 0), 0, 0, 0, 0);
// Формируем данные для подписания
vector<unsigned char> data;
if (ReadFileToVector(opt.file_in.c_str(), data)) {
cout << "ReadFileToVector() failed" << endl;
return false;
}
// Добавляем подпись в сообщение
if (!CryptMsgUpdate(hMsg, &data[0], (DWORD)data.size(), TRUE)) {
if (mustFree)
CryptReleaseContext(hProv, 0);
CertFreeCertificateContext(context);
CryptMsgClose(hMsg);
cout << "CryptMsgUpdate() failed in " __FUNCTION__ << endl;
return false;
}
// Задаем параметры
CMSG_SIGNER_ENCODE_INFO signer = { sizeof(CMSG_SIGNER_ENCODE_INFO) };
signer.pCertInfo = context->pCertInfo; // Сертификат подписчика
signer.hCryptProv = hProv; // Дескриптор криптопровайдера
signer.dwKeySpec = dwKeySpec;
signer.HashAlgorithm.pszObjId = (LPSTR)GetHashOid(context);
CADES_SIGN_PARA signPara = { sizeof(signPara) };
signPara.dwCadesType = CADES_BES;
CADES_COSIGN_PARA cosignPara = { sizeof(cosignPara) };
cosignPara.pSigner = &signer;
cosignPara.pCadesSignPara = &signPara;
if (!CadesMsgAddEnhancedSignature(hMsg, &cosignPara)) {
CertFreeCertificateContext(context);
CryptReleaseContext(hProv, 0);
CryptMsgClose(hMsg);
std::cout << "CadesMsgAddEnhanceSignature() failed" << std::endl;
return false;
}
DWORD cbCosignedMessageBlob = 0;
std::vector<unsigned char> pbCosignedMessageBlob;
if (CryptMsgGetParam(hMsg, CMSG_ENCODED_MESSAGE, 0, 0, &cbCosignedMessageBlob)) {
cout << "The size for the encoded BLOB is " << cbCosignedMessageBlob << '\n';
pbCosignedMessageBlob.resize(cbCosignedMessageBlob);
} else {
cout << "Sizing of cbSignerInfo failed.\n";
}
// Get the cosigned message BLOB.
if (CryptMsgGetParam(hMsg, CMSG_ENCODED_MESSAGE, 0, &(pbCosignedMessageBlob[0]), &cbCosignedMessageBlob)) {
cout << "The message was cosigned successfully. \n";
} else {
cout << "Sizing of cbSignerInfo failed.\n";
}
// Сохраняем результат в файл sign.dat
if (SaveVectorToFile<unsigned char>((opt.file_out + ".cosign").c_str(), pbCosignedMessageBlob)) {
cout << "Signature was not saved" << endl;
return false;
}
//CadesMsgUIDisplaySignature(hMsg, 0, NULL, _TEXT("Sign"));
// Освобождаем ресурсы
if (context)
CertFreeCertificateContext(context);
// CryptReleaseContext(hProv, 0);
// CertFreeCertificateContext(context);
return true;
}