Advertisement
Shokedbrain

CryptoLab3

Apr 10th, 2022
1,672
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <iostream>
  2. #include <Windows.h>
  3. #include <wincrypt.h>
  4. #include <vector>
  5. using namespace std;
  6.  
  7. void ErrorHandling(const string& message)
  8. {
  9.     DWORD dw = GetLastError();
  10.     cout << "Error with: " << message << "\n";
  11.     cout << "Error code: " << dw << "\n";
  12. }
  13.  
  14. wstring strToWide(string inp)
  15. {
  16.     return wstring(inp.begin(), inp.end());
  17. }
  18.  
  19.  
  20. DWORD chooseProvType()
  21. {
  22.     LPTSTR  pszName;
  23.     DWORD   dwType;
  24.     DWORD   cbName;
  25.     DWORD   dwIndex = 0;
  26.     LPTSTR  choseProvName; // выбранный провайдер пользователем
  27.     DWORD   choseProvType; // выбранный тип провайдера пользователем
  28.     vector<std::pair<LPTSTR, DWORD>> providersList;
  29.     // переменная содержит всех провайдеров после парсинга локальных значений
  30.  
  31.     // Цикл по перечисляемым типам провайдеров.
  32.     dwIndex = 0;
  33.     while (CryptEnumProviderTypes(
  34.         dwIndex,     // in -- dwIndex
  35.         nullptr,        // in -- pdwReserved- устанавливается в NULL
  36.         0,           // in -- dwFlags -- устанавливается в ноль
  37.         &dwType,     // out -- pdwProvType
  38.         nullptr,        // out -- pszProvName -- NULL при первом вызове
  39.         &cbName      // in, out -- pcbProvName
  40.     ))
  41.     {
  42.         //  cbName - длина имени следующего провайдера.
  43.         //  Распределение памяти в буфере для восстановления этого имени.
  44.         pszName = static_cast<LPTSTR>(malloc(cbName));
  45.         if (!pszName)
  46.             ErrorHandling("malloc failed!");
  47.         memset(pszName, 0, cbName);
  48.         //  Получение имени типа провайдера.
  49.         if (CryptEnumProviderTypes(
  50.             dwIndex++,
  51.             nullptr,
  52.             0,
  53.             &dwType,
  54.             pszName,
  55.             &cbName))
  56.         {
  57.             providersList.emplace_back(pszName, dwType);
  58.         }
  59.         else
  60.         {
  61.             ErrorHandling("CryptEnumProviderTypes");
  62.             return -1;
  63.         }
  64.     }
  65.     cout << "\nfound types provider\n";
  66.     for (size_t i = 0; i < providersList.size(); i++)
  67.     {
  68.         wcout << i << " " << providersList[i].first << " " << providersList[i].second << "\n";
  69.     }
  70.  
  71.     cout << "choose provider: ";
  72.     int choice = 0;
  73.     do
  74.     {
  75.         cin >> choice;
  76.     } while (choice < 0 && choice > providersList.size());
  77.     choseProvName = providersList[choice].first;
  78.     choseProvType = providersList[choice].second;
  79.     wcout << "Chose provider name: " << choseProvName << "\n";
  80.     wcout << "Chose provider type: " << choseProvType << "\n";
  81.     return choseProvType;
  82. }
  83.  
  84. LPCWSTR chooseContainer(DWORD provType)
  85. {
  86.     HCRYPTPROV          hCryptProv; // дескриптор криптопровайдера
  87.     DWORD               cbContainerName{};    // Размер имени контейнера
  88.     if (CryptAcquireContext(&hCryptProv,
  89.         nullptr,
  90.         nullptr,
  91.         provType,
  92.         CRYPT_VERIFYCONTEXT))
  93.     {
  94.         cout << "CryptAcquireContext successful\n";
  95.     }
  96.     else
  97.     {
  98.         ErrorHandling("CryptAcquireContext");
  99.         return nullptr;
  100.     }
  101.     // Получение размера параметра
  102.     if (CryptGetProvParam(hCryptProv, PP_ENUMCONTAINERS, nullptr,
  103.         &cbContainerName, CRYPT_FIRST))
  104.     {
  105.         cout << "CryptGetProvParam PP_ENUMCONTAINERS succeeded. \n";
  106.     }
  107.     else
  108.     {
  109.         ErrorHandling("CryptGetProvParam");
  110.         return nullptr;
  111.     }
  112.  
  113.     DWORD       dwFlags = CRYPT_FIRST; // флаг для CryptGetProvParam
  114.     vector <wstring> containers{};
  115.     int index = 0;
  116.     while (true)
  117.     {
  118.         string bufContainer(cbContainerName + 1, 0); // Имя контейнера
  119.         DWORD dwContainerLen = cbContainerName;
  120.         if (!CryptGetProvParam(hCryptProv, PP_ENUMCONTAINERS,
  121.             reinterpret_cast<BYTE*>(&bufContainer[0]), &dwContainerLen, dwFlags))
  122.         {
  123.             // при возникновении ошибки ERROR_NO_MORE_ITEMS
  124.             // нумерация контейнеров криптопровайдера завершена
  125.             if (ERROR_NO_MORE_ITEMS == GetLastError())
  126.             {
  127.                 cout << "The end of the enumeration has been reached\n";
  128.             }
  129.             break;
  130.         }
  131.  
  132.         wstring conName = strToWide(bufContainer);
  133.         containers.push_back(conName);
  134.         bufContainer.clear();// очищаем имя контейнера для следующего использования
  135.         dwFlags = CRYPT_NEXT; // переключаем флаг для продолжения перечисления имён контейнеров
  136.         //++index;
  137.     }
  138.     if (!containers.empty())
  139.     {
  140.         for (int i = 0; i < containers.size(); i++)
  141.         {
  142.             wcout << i << " " << containers.at(i) << "\n";
  143.         }
  144.         int choice = 0;
  145.         cout << "enter choice: ";
  146.         do { cin >> choice; } while (choice < 0 && choice > containers.size());
  147.         wcout << "chose container: " << containers.at(choice) << "\n";
  148.         return containers.at(choice).c_str();
  149.     }
  150.     else
  151.     {
  152.         cout << "list of containers is empty...\n";
  153.         return nullptr;
  154.     }
  155.  
  156. }
  157.  
  158. int main()
  159. {
  160.     const DWORD provType = chooseProvType(); // выбираем тип криптопровайдера
  161.     // --------------------------------------
  162.     LPCWSTR containerName = chooseContainer(provType);
  163.  
  164.  
  165.  
  166.     return 0;
  167. }
  168.  
  169.  
  170.  
  171.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement