Вычислить дайджест сообщения для TSA для CMS_sign до CMS_final

#security #openssl #signing #pki #pkcs#7

#Безопасность #openssl #подписание #pki #pkcs#7

Вопрос:

У меня есть код для создания подписи CMS. Это сработало хорошо, теперь мне нужно добавить надежные временные метки.

 BIO *data_output = BIO_new(BIO_s_mem());
const EVP_MD *sign_md = EVP_get_digestbyname(digest_name);

cms = CMS_sign(NULL, NULL, NULL, bio_in, flags);
BOOST_ASSERT(cms);

for (size_t i = 0; i < m_signers.size(); i  ) {
    int tflags = flags;

    SignerInfo si = m_signers[i];

    CMS_SignerInfo *signer_info = CMS_add1_signer(cms,
        si.m_x509, si.m_privateKey, sign_md, tflags);
    BOOST_ASSERT(signer_info != NULL);

    for (int c = 0; c < sk_X509_num(si.m_ca); c  ) {
        X509* cert = sk_X509_value(si.m_ca, c);
        BOOST_ASSERT(CMS_add0_cert(cms, cert) != 0);
    }
}

BOOST_ASSERT(CMS_final(cms, bio_in, NULL, flags) != 0);
BOOST_ASSERT(i2d_CMS_bio_stream(data_output, cms, bio_in, flags) != 0);
  

Чтобы связаться с TSA, мне нужно значение дайджеста, но нет способа получить значение дайджеста до вызова CMS_final. Я нигде не смог найти ответ.

Комментарии:

1. Напишите мне вне списка на noloader, учетная запись gmail.

Ответ №1:

id-aa-timeStampToken является атрибутом без знака. Если в вашей реализации нет перехватов для последующего изменения сообщения, вы можете сделать это в два прохода. Выполните вызов final, получите хэш и отправьте его в TSA. Затем создайте вторую идентичную CMS и добавьте неподписанный идентификатор-aa-timeStampToken attibute (OID 1.2.840.113549.1.9.16.2.14). Вставьте туда timestampToken и вызовите final.

Имейте в виду, что для использования метки времени обычно требуется подписанный атрибут signing-time Pkcs9SigningTime (OID 1.2.840.113549.1.9.5), поэтому сэкономьте время, затраченное на первом проходе, чтобы получить два идентичных сообщения CMS.

Это немного дешево, но оно выполняет свою работу. Если вам нужно запросить PIN-код на смарт-карте, он запросит два раза.