На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются.
4. Используйте теги [ code=cpp ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Старайтесь формулировать свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной и более давности без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта (C++) user posted image FAQ Форума user posted image Наши Исходники user posted image Поиск по Разделу user posted image MSDN Library Online (Windows Driver Kit) user posted image Google

Ваше мнение о модераторах: user posted image B.V.
Модераторы: B.V.
  
> Объединение данных в формате ASN.1 штатными средствами
    Добрый день. Возникла у меня такая задача: на входе строка с данными об издателе сертификата. Нужно получить массив байт в формате ASN.1. Все бы ничего, но: строка приходит в следующем виде:
    ExpandedWrap disabled
      issuer:CN="Тестовый УЦ ООО \"КРИПТО-ПРО\"", O="ООО \"КРИПТО-ПРО\"", C=RU, EMAILADDRESS=info@cryptopro.ru, L=Москва, ST=77 г. Москва, STREET="ул. Сущёвский вал, д. 18", OID.1.2.643.3.131.1.1=#120C303037373137313037393931, OID.1.2.643.100.1=#120D31303337373030303835343434

    Соответственно мы видим Х509 строку и две строки с OID'ами. Ага, что делать? 1) Парсим строку. 2) Перегоняем в ASN.1 вызовом
    ExpandedWrap disabled
      CertStrToNameW/*и ударом в бубен*/
    . На выходе получаем 3 массива в нужном нам формате. А вот тут и начинаются проблемы. Строки нужно объединить, но объединить так, чтобы при этом изменился (правильно пересчитался) заголовок сообщения. И здесь, что называется, нашла коса на камень. Как это грамотно сделать - не придумаю. Может кто сталкивался с подобным? Ниже код тестовый.

    ExpandedWrap disabled
      #include <cstdio>
      #include <cstdlib>
      #include <iostream>
      #include <string>
      #include <wtypes.h>
      #include <wincrypt.h>
      #include <fstream>
      #pragma comment(lib, "crypt32.lib")
      #include <Windows.h>
      #include <vector>
       
      #define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
      #define MY_STRING_TYPE (CERT_SIMPLE_NAME_STR)
      using ByteArray = std::vector<uint8_t>;
       
      static std::vector<uint8_t> read_file(const std::string& path)
      {
          std::ifstream file(path, std::ifstream::binary);
          if (!file)
              throw std::runtime_error("Couldn't open file: " + path);
       
       
          file.seekg(0, std::ios::end);
          std::vector<uint8_t> data(static_cast<size_t>(file.tellg()));
       
          file.seekg(0, std::ios::beg);
          file.read(reinterpret_cast<char*>(data.data()), data.size());
          if (!file)
              throw std::runtime_error("Couldn't read file: " + path);
       
          file.close();
          return data;
      }// read_file
       
       
      static ByteArray wstring2asn1(LPCWSTR pszString, int str_type)
      {
          ByteArray result;
          DWORD cbSize;
          CERT_NAME_BLOB blobEncodedIssuerName;
       
       
          if (!(CertStrToNameW(
              MY_ENCODING_TYPE,
              pszString,
              str_type,
              NULL,
              NULL,
              &cbSize,
              NULL)))
          {
              std::cout << "\nCould not get the length of the BLOB.";
              return  result;
          }
       
          if (!(blobEncodedIssuerName.pbData = (LPBYTE)malloc(cbSize)))
          {
              std::cout << "\nMemory Allocation for the BLOB failed.";
              return  result;
          }
          blobEncodedIssuerName.cbData = cbSize;
       
          if (!(CertStrToNameW(
              MY_ENCODING_TYPE | CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG,
              pszString,
              str_type,
              NULL,
              blobEncodedIssuerName.pbData,
              &blobEncodedIssuerName.cbData,
              NULL)))
          {
              std::cout << "\nCould not write the blob.";
              return  result;
          }
          return ByteArray(blobEncodedIssuerName.pbData, blobEncodedIssuerName.pbData + blobEncodedIssuerName.cbData);
      }// wstring2asn1
       
      int main(int argc, char* argv[])
      {
          LPCWSTR oid1 = L"OID.1.2.643.3.131.1.1=#120C303037373137313037393931";
          LPCWSTR oid2 = L"OID.1.2.643.100.1=#120D31303337373030303835343434";
          LPCWSTR issuer = L"CN = \"Тестовый УЦ ООО КРИПТО-ПРО\", O = ООО КРИПТО-ПРО, C = RU, E = info@cryptopro.ru, L = Москва, ST = 77 г.Москва, STREET=\"ул.Сущёвский вал, д. 18\"";
          ByteArray result;
          auto b_issuer = wstring2asn1(issuer, CERT_X500_NAME_STR);
          auto b_oid1 = wstring2asn1(oid1, CERT_OID_NAME_STR);
          auto b_oid2 = wstring2asn1(oid2, CERT_OID_NAME_STR);
          
          result.insert(result.end(), b_issuer.begin(), b_issuer.end());
          result.insert(result.end(), b_oid1.begin(), b_oid1.end());
          result.insert(result.end(), b_oid2.begin(), b_oid2.end());
       
          CERT_ISSUER_SERIAL_NUMBER cert_issuer_serial_number;
          auto serial_orig = read_file("C:\\test\\serial.txt");// здесь оригинальный серийник
          cert_issuer_serial_number.Issuer.pbData = result.data();
          cert_issuer_serial_number.Issuer.cbData = static_cast<DWORD>(result.size());
          cert_issuer_serial_number.SerialNumber.pbData = const_cast<BYTE*>(serial_orig.data());
          cert_issuer_serial_number.SerialNumber.cbData = static_cast<DWORD>(serial_orig.size());
          CERT_ID cert_id;
          cert_id.dwIdChoice = 1;
          cert_id.IssuerSerialNumber = cert_issuer_serial_number;
          HCERTSTORE store_handle;
          // Открываем хранилище сертификатов
          if (!(store_handle = CertOpenStore(
              CERT_STORE_PROV_SYSTEM,
              0,
              NULL,
              CERT_SYSTEM_STORE_CURRENT_USER,
              L"MY")))
          {
              std::cout << "cert not found";
          }
       
          PCCERT_CONTEXT pCertCtx = CertFindCertificateInStore(
              store_handle,
              MY_ENCODING_TYPE,
              0,
              CERT_FIND_CERT_ID,
              &cert_id,
              nullptr);
          if (!pCertCtx)
          {
              std::cout << "cert not found\n";
              system("pause");
              return 0;
          }
          std::cout << "cert found\n";
          system("pause");
          return 0;
      }
      Цитата kotmatroskin55 @
      Строки нужно объединить, но объединить так, чтобы при этом изменился (правильно пересчитался) заголовок сообщения

      Нужны критерии изменения/правильного пересчета заголовка сообщения.
        Цитата JoeUser @
        Нужны критерии изменения/правильного пересчета заголовка сообщения.

        Знал бы прикуп - жил бы в Сочи ;)
        А если серьезно, то первая строка это
        ExpandedWrap disabled
          SEQUENCE (7 elem)
            SET (1 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 2.5.4.3 commonName (X.520 DN component)
                BMPString Тестовый УЦ ООО КРИПТО-ПРО
            SET (1 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 2.5.4.10 organizationName (X.520 DN component)
                BMPString ООО КРИПТО-ПРО
            SET (1 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 2.5.4.6 countryName (X.520 DN component)
                PrintableString RU
            SET (1 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 1.2.840.113549.1.9.1 emailAddress (PKCS #9. Deprecated, use an altName extension instead)
                IA5String info@cryptopro.ru
            SET (1 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 2.5.4.7 localityName (X.520 DN component)
                BMPString Москва
            SET (1 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 2.5.4.8 stateOrProvinceName (X.520 DN component)
                BMPString 77 г.Москва
            SET (1 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 2.5.4.9 streetAddress (X.520 DN component)
                BMPString ул.Сущёвский вал, д. 18

        вторая
        ExpandedWrap disabled
          SEQUENCE (1 elem)
            SET (1 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 1.2.643.3.131.1.1
          Offset: 6
          Length: 2+8
          Value:
          1.2.643.3.131.1.1
                OCTET STRING (1 elem)
                  NumericString 007717107991

        третья
        ExpandedWrap disabled
          SEQUENCE (1 elem)
            SET (1 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 1.2.643.100.1
                OCTET STRING (1 elem)
                  NumericString 1037700085444

        А должно получиться
        ExpandedWrap disabled
          SEQUENCE (9 elem)
            SET (1 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 1.2.643.100.1
                NumericString 1037700085444
            SET (1 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 1.2.643.3.131.1.1
                NumericString 007717107991
            SET (1 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 2.5.4.9 streetAddress (X.520 DN component)
                BMPString ул. Сущёвский вал, д. 18
            SET (1 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 2.5.4.8 stateOrProvinceName (X.520 DN component)
                BMPString 77 г. Москва
            SET (1 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 2.5.4.7 localityName (X.520 DN component)
                BMPString Москва
            SET (1 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 1.2.840.113549.1.9.1 emailAddress (PKCS #9. Deprecated, use an altName extension instead)
                IA5String info@cryptopro.ru
            SET (1 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 2.5.4.6 countryName (X.520 DN component)
                PrintableString RU
            SET (1 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 2.5.4.10 organizationName (X.520 DN component)
          Offset: 226
          Length: 2+3
          Value:
          2.5.4.10
          organizationName
          X.520 DN component
                BMPString ООО "КРИПТО-ПРО"
            SET (1 elem)
              SEQUENCE (2 elem)
                OBJECT IDENTIFIER 2.5.4.3 commonName (X.520 DN component)
                BMPString Тестовый УЦ ООО "КРИПТО-ПРО"

        более-менее вменяемый ман
          Проблема оказалась совсем не там, где ее искали. CertStrToNameW не хочет работать с кавычками. Точнее в документации сказано:
          Цитата
          Quotation marks ("") are supported. A quotation can be included in a quoted value by using two sets of quotation marks, for example, CN="User ""one""".
          . Но видимо я чего-то недопонял.
          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
          0 пользователей:


          Рейтинг@Mail.ru
          [ Script execution time: 0,0346 ]   [ 16 queries used ]   [ Generated: 19.04.24, 17:36 GMT ]