WinStd
Additional templates and function helpers for Microsoft Windows using Standard C++ classes
Crypt.h
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 1991-2022 Amebis
4 Copyright © 2016 GÉANT
5*/
6
7#pragma once
8
9#include "Common.h"
10#include <assert.h>
11#include <WinCrypt.h>
12#include <algorithm>
13#include <string>
14#include <vector>
15
21
23template<class _Traits, class _Ax>
24static DWORD CertGetNameStringA(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_opt_ void *pvTypePara, _Out_ std::basic_string<char, _Traits, _Ax> &sNameString)
25{
26 // Query the final string length first.
27 DWORD dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0);
28
29 // Allocate buffer on heap to format the string data into and read it.
30 std::unique_ptr<char[]> szBuffer(new char[dwSize]);
31 dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, szBuffer.get(), dwSize);
32 sNameString.assign(szBuffer.get(), dwSize - 1);
33 return dwSize;
34}
35
41template<class _Traits, class _Ax>
42static DWORD CertGetNameStringW(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_opt_ void *pvTypePara, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sNameString)
43{
44 // Query the final string length first.
45 DWORD dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0);
46
47 // Allocate buffer on heap to format the string data into and read it.
48 std::unique_ptr<wchar_t[]> szBuffer(new wchar_t[dwSize]);
49 dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, szBuffer.get(), dwSize);
50 sNameString.assign(szBuffer.get(), dwSize - 1);
51 return dwSize;
52}
53
59template<class _Ty, class _Ax>
60static _Success_(return != 0) BOOL WINAPI CertGetCertificateContextProperty(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwPropId, _Out_ std::vector<_Ty, _Ax> &aData)
61{
63 DWORD dwSize = WINSTD_STACK_BUFFER_BYTES;
64
65 // Try with the stack buffer first.
66 if (CertGetCertificateContextProperty(pCertContext, dwPropId, buf, &dwSize)) {
67 // Copy from stack.
68 aData.assign((const _Ty*)buf, (const _Ty*)buf + (dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
69 return TRUE;
70 } else if (GetLastError() == ERROR_MORE_DATA) {
71 aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
72 if (CertGetCertificateContextProperty(pCertContext, dwPropId, (BYTE*)aData.data(), &dwSize))
73 return TRUE;
74 }
75
76 return FALSE;
77}
78
84template<class _Ty, class _Ax>
85static _Success_(return != 0) BOOL CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_ DWORD dwParam, _Out_ std::vector<_Ty, _Ax> &aData, _In_ DWORD dwFlags)
86{
88 DWORD dwSize = WINSTD_STACK_BUFFER_BYTES;
89
90 // Try with the stack buffer first.
91 if (CryptGetHashParam(hHash, dwParam, buf, &dwSize, dwFlags)) {
92 // Copy from stack.
93 aData.assign((const _Ty*)buf, (const _Ty*)buf + (dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
94 return TRUE;
95 } else if (GetLastError() == ERROR_MORE_DATA) {
96 aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
97 if (CryptGetHashParam(hHash, dwParam, (BYTE*)aData.data(), &dwSize, dwFlags))
98 return TRUE;
99 }
100
101 return FALSE;
102}
103
109template<class T>
110static _Success_(return != 0) BOOL CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_ DWORD dwParam, _Out_ T &data, _In_ DWORD dwFlags)
111{
112 DWORD dwSize = sizeof(T);
113 return CryptGetHashParam(hHash, dwParam, (BYTE*)&data, &dwSize, dwFlags);
114}
115
121template<class _Ty, class _Ax>
122static _Success_(return != 0) BOOL CryptGetKeyParam(_In_ HCRYPTKEY hKey, _In_ DWORD dwParam, _Out_ std::vector<_Ty, _Ax> &aData, _In_ DWORD dwFlags)
123{
125 DWORD dwSize = WINSTD_STACK_BUFFER_BYTES;
126
127 // Try with the stack buffer first.
128 if (CryptGetKeyParam(hKey, dwParam, buf, &dwSize, dwFlags)) {
129 // Copy from stack.
130 aData.assign((const _Ty*)buf, (const _Ty*)buf + (dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
131 return TRUE;
132 } else if (GetLastError() == ERROR_MORE_DATA) {
133 aData.resize((dwSize + sizeof(_Ty) - 1) / sizeof(_Ty));
134 if (CryptGetKeyParam(hKey, dwParam, (BYTE*)aData.data(), &dwSize, dwFlags))
135 return TRUE;
136 }
137
138 return FALSE;
139}
140
146template<class T>
147static BOOL CryptGetKeyParam(_In_ HCRYPTKEY hKey, _In_ DWORD dwParam, _Out_ T &data, _In_ DWORD dwFlags)
148{
149 DWORD dwSize = sizeof(T);
150 return CryptGetKeyParam(hKey, dwParam, (BYTE*)&data, &dwSize, dwFlags);
151}
152
158template<class _Ty, class _Ax>
159static _Success_(return != 0) BOOL CryptExportKey(_In_ HCRYPTKEY hKey, _In_ HCRYPTKEY hExpKey, _In_ DWORD dwBlobType, _In_ DWORD dwFlags, _Out_ std::vector<_Ty, _Ax> &aData)
160{
161 DWORD dwKeyBLOBSize = 0;
162
163 if (CryptExportKey(hKey, hExpKey, dwBlobType, dwFlags, NULL, &dwKeyBLOBSize)) {
164 aData.resize((dwKeyBLOBSize + sizeof(_Ty) - 1) / sizeof(_Ty));
165 if (CryptExportKey(hKey, hExpKey, dwBlobType, dwFlags, aData.data(), &dwKeyBLOBSize))
166 return TRUE;
167 }
168
169 return FALSE;
170}
171
177template<class _Ty, class _Ax>
178static _Success_(return != 0) BOOL CryptEncrypt(_In_ HCRYPTKEY hKey, _In_opt_ HCRYPTHASH hHash, _In_ BOOL Final, _In_ DWORD dwFlags, _Inout_ std::vector<_Ty, _Ax> &aData)
179{
180 DWORD
181 dwDataLen = (DWORD)(aData.size() * sizeof(_Ty)),
182 dwBufLen = (DWORD)(aData.capacity() * sizeof(_Ty)),
183 dwEncLen = dwDataLen,
184 dwResult;
185
186 if (dwBufLen) {
187 aData.resize(dwBufLen);
188 if (CryptEncrypt(hKey, hHash, Final, dwFlags, (BYTE*)aData.data(), &dwEncLen, dwBufLen)) {
189 // Encryption succeeded.
190 assert(dwEncLen <= dwBufLen);
191 if (dwEncLen < dwBufLen)
192 aData.resize((dwEncLen + sizeof(_Ty) - 1) / sizeof(_Ty));
193 return TRUE;
194 } else
195 dwResult = GetLastError();
196 } else if (CryptEncrypt(hKey, NULL, Final, dwFlags, NULL, &dwEncLen, 0)) {
197 // CryptEncrypt() always succeeds for output data size queries.
198 // dwEncLen contains required output data size. Continue as if the buffer was to small. Actually, the output buffer _was_ too small!
199 dwResult = ERROR_MORE_DATA;
200 } else
201 dwResult = GetLastError();
202
203 if (dwResult == ERROR_MORE_DATA) {
204 // Encrypted data will be longer. Reserve more space and retry.
205 aData.resize(((dwBufLen = dwEncLen) + sizeof(_Ty) - 1) / sizeof(_Ty));
206 dwEncLen = dwDataLen;
207 if (CryptEncrypt(hKey, hHash, Final, dwFlags, (BYTE*)aData.data(), &dwEncLen, dwBufLen)) {
208 // Encryption succeeded.
209 assert(dwEncLen <= dwBufLen);
210 if (dwEncLen < dwBufLen)
211 aData.resize((dwEncLen + sizeof(_Ty) - 1) / sizeof(_Ty));
212 return TRUE;
213 }
214 } else {
215 // Resize back to data length.
216 aData.resize((dwDataLen + sizeof(_Ty) - 1) / sizeof(_Ty));
217 }
218
219 return FALSE;
220}
221
227template<class _Ty, class _Ax>
228static _Success_(return != 0) BOOL CryptDecrypt(_In_ HCRYPTKEY hKey, _In_opt_ HCRYPTHASH hHash, _In_ BOOL Final, _In_ DWORD dwFlags, _Inout_ std::vector<_Ty, _Ax> &aData)
229{
230 DWORD dwDataLen = (DWORD)(aData.size() * sizeof(_Ty));
231
232 if (CryptDecrypt(hKey, hHash, Final, dwFlags, (BYTE*)aData.data(), &dwDataLen)) {
233 // Decryption succeeded.
234 aData.resize((dwDataLen + sizeof(_Ty) - 1) / sizeof(_Ty));
235 return TRUE;
236 }
237
238 return FALSE;
239}
240
242
243namespace winstd
244{
247
251 class cert_context : public dplhandle<PCCERT_CONTEXT, NULL>
252 {
254
255 public:
262 {
263 if (m_h != invalid)
265 }
266
276 __declspec(deprecated("Use CertCreateCertificateContext"))
277 bool create(_In_ DWORD dwCertEncodingType, _In_ LPCBYTE pbCertEncoded, _In_ DWORD cbCertEncoded) noexcept
278 {
279 handle_type h = CertCreateCertificateContext(dwCertEncodingType, pbCertEncoded, cbCertEncoded);
280 if (h != invalid) {
281 attach(h);
282 return true;
283 } else
284 return false;
285 }
286
295 bool operator==(_In_ const handle_type &other) const noexcept
296 {
297 // TODO: [Crypto] Make constant time.
298 return
299 m_h == other ||
300 m_h->cbCertEncoded == other->cbCertEncoded && memcmp(m_h->pbCertEncoded, other->pbCertEncoded, m_h->cbCertEncoded) == 0;
301 }
302
311 bool operator!=(_In_ const handle_type &other) const noexcept
312 {
313 return !operator==(other);
314 }
315
324 bool operator<(_In_ const handle_type &other) const noexcept
325 {
326 // TODO: [Crypto] Make constant time.
327 const int r = memcmp(m_h->pbCertEncoded, other->pbCertEncoded, std::min<DWORD>(m_h->cbCertEncoded, other->cbCertEncoded));
328 return r < 0 || r == 0 && m_h->cbCertEncoded < other->cbCertEncoded;
329 }
330
339 bool operator>(_In_ const handle_type &other) const noexcept
340 {
341 // TODO: [Crypto] Make constant time.
342 const int r = memcmp(m_h->pbCertEncoded, other->pbCertEncoded, std::min<DWORD>(m_h->cbCertEncoded, other->cbCertEncoded));
343 return r > 0 || r == 0 && m_h->cbCertEncoded > other->cbCertEncoded;
344 }
345
354 bool operator<=(_In_ const handle_type &other) const noexcept
355 {
356 return !operator>(other);
357 }
358
367 bool operator>=(_In_ const handle_type &other) const noexcept
368 {
369 return !operator<(other);
370 }
371
372 protected:
378 void free_internal() noexcept override
379 {
380 CertFreeCertificateContext(m_h);
381 }
382
392 handle_type duplicate_internal(_In_ handle_type h) const noexcept override
393 {
394 return CertDuplicateCertificateContext(h);
395 }
396 };
397
401 class cert_chain_context : public dplhandle<PCCERT_CHAIN_CONTEXT, NULL>
402 {
404
405 public:
412 {
413 if (m_h != invalid)
415 }
416
426 __declspec(deprecated("Use CertGetCertificateChain"))
427 bool create(_In_opt_ HCERTCHAINENGINE hChainEngine, _In_ PCCERT_CONTEXT pCertContext, _In_opt_ LPFILETIME pTime, _In_opt_ HCERTSTORE hAdditionalStore, _In_ PCERT_CHAIN_PARA pChainPara, _In_ DWORD dwFlags, __reserved LPVOID pvReserved = NULL) noexcept
428 {
429 handle_type h;
430 if (CertGetCertificateChain(hChainEngine, pCertContext, pTime, hAdditionalStore, pChainPara, dwFlags, pvReserved, &h)) {
431 attach(h);
432 return true;
433 } else
434 return false;
435 }
436
437 protected:
443 void free_internal() noexcept override
444 {
445 CertFreeCertificateChain(m_h);
446 }
447
457 handle_type duplicate_internal(_In_ handle_type h) const noexcept override
458 {
459 return CertDuplicateCertificateChain(h);
460 }
461 };
462
466 class cert_store : public handle<HCERTSTORE, NULL>
467 {
469
470 public:
476 virtual ~cert_store()
477 {
478 if (m_h != invalid)
480 }
481
491 __declspec(deprecated("Use CertOpenStore"))
492 bool create(_In_ LPCSTR lpszStoreProvider, _In_ DWORD dwEncodingType, _In_opt_ HCRYPTPROV_LEGACY hCryptProv, _In_ DWORD dwFlags, _In_opt_ const void *pvPara) noexcept
493 {
494 handle_type h = CertOpenStore(lpszStoreProvider, dwEncodingType, hCryptProv, dwFlags, pvPara);
495 if (h != invalid) {
496 attach(h);
497 return true;
498 } else
499 return false;
500 }
501
511 __declspec(deprecated("Use CertOpenSystemStore"))
512 bool create(_In_opt_ HCRYPTPROV_LEGACY hCryptProv, _In_z_ LPCTSTR szSubsystemProtocol) noexcept
513 {
514 handle_type h = CertOpenSystemStore(hCryptProv, szSubsystemProtocol);
515 if (h != invalid) {
516 attach(h);
517 return true;
518 } else
519 return false;
520 }
521
522 protected:
528 void free_internal() noexcept override
529 {
530 CertCloseStore(m_h, 0);
531 }
532 };
533
537 class crypt_prov : public handle<HCRYPTPROV, NULL>
538 {
540
541 public:
547 virtual ~crypt_prov()
548 {
549 if (m_h != invalid)
551 }
552
562 __declspec(deprecated("Use CryptAcquireContext"))
563 bool create(_In_opt_z_ LPCTSTR szContainer, _In_opt_z_ LPCTSTR szProvider, _In_ DWORD dwProvType, _In_ DWORD dwFlags = 0) noexcept
564 {
565 handle_type h;
566 if (CryptAcquireContext(&h, szContainer, szProvider, dwProvType, dwFlags)) {
567 attach(h);
568 return true;
569 } else
570 return false;
571 }
572
573 protected:
579 void free_internal() noexcept override
580 {
581 CryptReleaseContext(m_h, 0);
582 }
583 };
584
588 class crypt_hash : public dplhandle<HCRYPTHASH, NULL>
589 {
591
592 public:
598 virtual ~crypt_hash()
599 {
600 if (m_h != invalid)
602 }
603
613 __declspec(deprecated("Use CryptCreateHash"))
614 bool create(_In_ HCRYPTPROV hProv, _In_ ALG_ID Algid, _In_opt_ HCRYPTKEY hKey = NULL, _In_opt_ DWORD dwFlags = 0) noexcept
615 {
616 handle_type h;
617 if (CryptCreateHash(hProv, Algid, hKey, dwFlags, &h)) {
618 attach(h);
619 return true;
620 } else
621 return false;
622 }
623
624 protected:
630 void free_internal() noexcept override
631 {
632 CryptDestroyHash(m_h);
633 }
634
644 handle_type duplicate_internal(_In_ handle_type h) const noexcept override
645 {
646 handle_type hNew;
647 return CryptDuplicateHash(h, NULL, 0, &hNew) ? hNew : invalid;
648 }
649 };
650
654 class crypt_key : public dplhandle<HCRYPTKEY, NULL>
655 {
657
658 public:
664 virtual ~crypt_key()
665 {
666 if (m_h != invalid)
668 }
669
675 __declspec(deprecated("Use CryptGenKey"))
676 bool generate(_In_ HCRYPTPROV hProv, _In_ ALG_ID Algid, _In_ DWORD dwFlags) noexcept
677 {
678 handle_type h;
679 if (CryptGenKey(hProv, Algid, dwFlags, &h)) {
680 attach(h);
681 return true;
682 } else
683 return false;
684 }
685
691 __declspec(deprecated("Use CryptImportKey"))
692 bool import(_In_ HCRYPTPROV hProv, __in_bcount(dwDataLen) LPCBYTE pbData, _In_ DWORD dwDataLen, _In_ HCRYPTKEY hPubKey, _In_ DWORD dwFlags) noexcept
693 {
694 handle_type h;
695 if (CryptImportKey(hProv, pbData, dwDataLen, hPubKey, dwFlags, &h)) {
696 attach(h);
697 return true;
698 } else
699 return false;
700 }
701
707 __declspec(deprecated("Use CryptImportPublicKeyInfo"))
708 bool import_public(_In_ HCRYPTPROV hCryptProv, _In_ DWORD dwCertEncodingType, _In_ PCERT_PUBLIC_KEY_INFO pInfo) noexcept
709 {
710 handle_type h;
711 if (CryptImportPublicKeyInfo(hCryptProv, dwCertEncodingType, pInfo, &h)) {
712 attach(h);
713 return true;
714 } else
715 return false;
716 }
717
723 __declspec(deprecated("Use CryptDeriveKey"))
724 bool derive(_In_ HCRYPTPROV hProv, _In_ ALG_ID Algid, _In_ HCRYPTHASH hBaseData, _In_ DWORD dwFlags) noexcept
725 {
726 handle_type h;
727 if (CryptDeriveKey(hProv, Algid, hBaseData, dwFlags, &h)) {
728 attach(h);
729 return true;
730 } else
731 return false;
732 }
733
742 bool create_exp1(_In_ HCRYPTPROV hProv, _In_ DWORD dwKeySpec)
743 {
744 if (dwKeySpec != AT_KEYEXCHANGE && dwKeySpec != AT_SIGNATURE) {
745 SetLastError(ERROR_INVALID_PARAMETER);
746 return false;
747 }
748
749 // Generate the private key.
750 handle_type h;
751 if (CryptGenKey(hProv, dwKeySpec, CRYPT_EXPORTABLE, &h)) {
752 // Export the private key, we'll convert it to a private exponent of one key.
753 std::vector<BYTE, sanitizing_allocator<BYTE>> key_blob;
754 if (CryptExportKey(h, 0, PRIVATEKEYBLOB, 0, key_blob)) {
755 CryptDestroyKey(h);
756
757 // Get the byte length of the key.
758 size_t
759 size_key = *reinterpret_cast<DWORD*>(&key_blob[12])/8,
760 size_prime = size_key/2;
761
762 // Modify the Exponent in Key BLOB format
763 // Key BLOB format is documented in SDK
764
765 // Convert pubexp in rsapubkey to 1
766 LPBYTE ptr = &key_blob[16];
767 *reinterpret_cast<DWORD*>(ptr) = 1;
768 ptr += sizeof(DWORD);
769
770 // Skip modulus, prime1, prime2
771 ptr += size_key;
772 ptr += size_prime;
773 ptr += size_prime;
774
775 // Convert exponent1 to 1
776 ptr[0] = 1;
777 memset(ptr + 1, 0, size_prime - 1);
778 ptr += size_prime;
779
780 // Convert exponent2 to 1
781 ptr[0] = 1;
782 memset(ptr + 1, 0, size_prime - 1);
783 ptr += size_prime;
784
785 // Skip coefficient
786 ptr += size_prime;
787
788 // Convert privateExponent to 1
789 ptr[0] = 1;
790 memset(ptr + 1, 0, size_key - 1);
791
792 // Import the exponent-of-one private key.
793 if (CryptImportKey(hProv, key_blob.data(), static_cast<DWORD>(key_blob.size()), 0, 0, &h)) {
794 attach(h);
795 return true;
796 }
797 } else
798 CryptDestroyKey(h);
799 }
800
801 return false;
802 }
803
804 protected:
810 void free_internal() noexcept override
811 {
812 CryptDestroyKey(m_h);
813 }
814
824 handle_type duplicate_internal(_In_ handle_type h) const noexcept override
825 {
826 handle_type hNew;
827 return CryptDuplicateKey(h, NULL, 0, &hNew) ? hNew : invalid;
828 }
829 };
830
834 #pragma warning(push)
835 #pragma warning(disable: 26432) // Copy constructor and assignment operator are also present, but not detected by code analysis as they are using base type source object reference.
836 class data_blob : public DATA_BLOB
837 {
838 public:
842 data_blob() noexcept
843 {
844 cbData = 0;
845 pbData = NULL;
846 }
847
851 data_blob(_In_count_(size) BYTE *data, _In_ DWORD size) noexcept
852 {
853 cbData = size;
854 pbData = data;
855 }
856
860 data_blob(_In_ const DATA_BLOB &other)
861 {
862 cbData = other.cbData;
863 if (cbData) {
864 pbData = static_cast<BYTE*>(LocalAlloc(LMEM_FIXED, other.cbData));
865 if (!pbData) throw win_runtime_error("LocalAlloc failed.");
866 memcpy(pbData, other.pbData, other.cbData);
867 } else
868 pbData = NULL;
869 }
870
874 data_blob(_Inout_ data_blob &&other) noexcept
875 {
876 cbData = other.cbData;
877 pbData = other.pbData;
878 other.cbData = 0;
879 other.pbData = NULL;
880 }
881
885 virtual ~data_blob()
886 {
887 if (pbData != NULL)
888 LocalFree(pbData);
889 }
890
894 data_blob& operator=(_In_ const DATA_BLOB &other)
895 {
896 if (this != &other) {
897 cbData = other.cbData;
898 if (pbData)
899 LocalFree(pbData);
900 if (cbData) {
901 pbData = static_cast<BYTE*>(LocalAlloc(LMEM_FIXED, other.cbData));
902 if (!pbData) throw win_runtime_error("LocalAlloc failed.");
903 memcpy(pbData, other.pbData, other.cbData);
904 } else
905 pbData = NULL;
906 }
907
908 return *this;
909 }
910
914 data_blob& operator=(_Inout_ data_blob &&other) noexcept
915 {
916 if (this != &other) {
917 cbData = other.cbData;
918 if (pbData)
919 LocalFree(pbData);
920 pbData = other.pbData;
921 other.cbData = 0;
922 other.pbData = NULL;
923 }
924
925 return *this;
926 }
927
931 DWORD size() const noexcept
932 {
933 return cbData;
934 }
935
939 const BYTE* data() const noexcept
940 {
941 return pbData;
942 }
943
947 BYTE* data() noexcept
948 {
949 return pbData;
950 }
951 };
952 #pragma warning(pop)
953
955}
956
959
960#pragma warning(push)
961#pragma warning(disable: 4505) // Don't warn on unused code
962
968static BOOL CertGetCertificateChain(_In_opt_ HCERTCHAINENGINE hChainEngine, _In_ PCCERT_CONTEXT pCertContext, _In_opt_ LPFILETIME pTime, _In_opt_ HCERTSTORE hAdditionalStore, _In_ PCERT_CHAIN_PARA pChainPara, _In_ DWORD dwFlags, _Reserved_ LPVOID pvReserved, _Inout_ winstd::cert_chain_context &ctx)
969{
970 PCCERT_CHAIN_CONTEXT pChainContext;
971 BOOL bResult = CertGetCertificateChain(hChainEngine, pCertContext, pTime, hAdditionalStore, pChainPara, dwFlags, pvReserved, &pChainContext);
972 if (bResult)
973 ctx.attach(pChainContext);
974 return bResult;
975}
976
978static BOOL CryptAcquireContextA(_Inout_ winstd::crypt_prov &prov, _In_opt_ LPCSTR szContainer, _In_opt_ LPCSTR szProvider, _In_ DWORD dwProvType, _In_ DWORD dwFlags)
979{
980 HCRYPTPROV h;
981 BOOL bResult = CryptAcquireContextA(&h, szContainer, szProvider, dwProvType, dwFlags);
982 if (bResult)
983 prov.attach(h);
984 return bResult;
985}
986
992static BOOL CryptAcquireContextW(_Inout_ winstd::crypt_prov &prov, _In_opt_ LPCWSTR szContainer, _In_opt_ LPCWSTR szProvider, _In_ DWORD dwProvType, _In_ DWORD dwFlags)
993{
994 HCRYPTPROV h;
995 BOOL bResult = CryptAcquireContextW(&h, szContainer, szProvider, dwProvType, dwFlags);
996 if (bResult)
997 prov.attach(h);
998 return bResult;
999}
1000
1006static BOOL CryptCreateHash(_In_ HCRYPTPROV hProv, _In_ ALG_ID Algid, _In_ HCRYPTKEY hKey, _In_ DWORD dwFlags, _Inout_ winstd::crypt_hash &hash)
1007{
1008 HCRYPTHASH h;
1009 BOOL bResult = CryptCreateHash(hProv, Algid, hKey, dwFlags, &h);
1010 if (bResult)
1011 hash.attach(h);
1012 return bResult;
1013}
1014
1020static BOOL CryptGenKey(_In_ HCRYPTPROV hProv, _In_ ALG_ID Algid, _In_ DWORD dwFlags, _Inout_ winstd::crypt_key &key)
1021{
1022 HCRYPTKEY h;
1023 BOOL bResult = CryptGenKey(hProv, Algid, dwFlags, &h);
1024 if (bResult)
1025 key.attach(h);
1026 return bResult;
1027}
1028
1034static bool CryptImportKey(_In_ HCRYPTPROV hProv, __in_bcount(dwDataLen) LPCBYTE pbData, _In_ DWORD dwDataLen, _In_ HCRYPTKEY hPubKey, _In_ DWORD dwFlags, _Inout_ winstd::crypt_key &key)
1035{
1036 HCRYPTKEY h;
1037 BOOL bResult = CryptImportKey(hProv, pbData, dwDataLen, hPubKey, dwFlags, &h);
1038 if (bResult)
1039 key.attach(h);
1040 return bResult;
1041}
1042
1048static bool CryptImportPublicKeyInfo(_In_ HCRYPTPROV hCryptProv, _In_ DWORD dwCertEncodingType, _In_ PCERT_PUBLIC_KEY_INFO pInfo, _Inout_ winstd::crypt_key &key)
1049{
1050 HCRYPTKEY h;
1051 BOOL bResult = CryptImportPublicKeyInfo(hCryptProv, dwCertEncodingType, pInfo, &h);
1052 if (bResult)
1053 key.attach(h);
1054 return bResult;
1055}
1056
1062static bool CryptDeriveKey(_In_ HCRYPTPROV hProv, _In_ ALG_ID Algid, _In_ HCRYPTHASH hBaseData, _In_ DWORD dwFlags, _Inout_ winstd::crypt_key &key)
1063{
1064 HCRYPTKEY h;
1065 BOOL bResult = CryptDeriveKey(hProv, Algid, hBaseData, dwFlags, &h);
1066 if (bResult)
1067 key.attach(h);
1068 return bResult;
1069}
1070
1071#pragma warning(pop)
1072
PCCERT_CHAIN_CONTEXT wrapper class.
Definition: Crypt.h:402
virtual ~cert_chain_context()
Destroys the certificate chain context.
Definition: Crypt.h:411
__declspec(deprecated("Use CertGetCertificateChain")) bool create(HCERTCHAINENGINE hChainEngine
Creates the certificate chain context.
PCCERT_CONTEXT wrapper class.
Definition: Crypt.h:252
bool operator<=(const handle_type &other) const noexcept
Is certificate less than or equal?
Definition: Crypt.h:354
void free_internal() noexcept override
Destroys the certificate context.
Definition: Crypt.h:378
bool operator==(const handle_type &other) const noexcept
Is certificate equal to?
Definition: Crypt.h:295
handle_type duplicate_internal(handle_type h) const noexcept override
Duplicates the certificate context.
Definition: Crypt.h:392
bool operator>=(const handle_type &other) const noexcept
Is certificate greater than or equal?
Definition: Crypt.h:367
bool operator>(const handle_type &other) const noexcept
Is certificate greater than?
Definition: Crypt.h:339
bool operator<(const handle_type &other) const noexcept
Is certificate less than?
Definition: Crypt.h:324
__declspec(deprecated("Use CertCreateCertificateContext")) bool create(DWORD dwCertEncodingType
Creates the certificate context.
bool operator!=(const handle_type &other) const noexcept
Is certificate not equal to?
Definition: Crypt.h:311
virtual ~cert_context()
Destroys the certificate context.
Definition: Crypt.h:261
HCERTSTORE wrapper class.
Definition: Crypt.h:467
__declspec(deprecated("Use CertOpenStore")) bool create(LPCSTR lpszStoreProvider
Opens the certificate store.
virtual ~cert_store()
Closes the certificate store.
Definition: Crypt.h:476
__declspec(deprecated("Use CertOpenSystemStore")) bool create(HCRYPTPROV_LEGACY hCryptProv
Opens the most common system certificate store. To open certificate stores with more complex requirem...
void free_internal() noexcept override
Closes the certificate store.
Definition: Crypt.h:528
HCRYPTHASH wrapper class.
Definition: Crypt.h:589
__declspec(deprecated("Use CryptCreateHash")) bool create(HCRYPTPROV hProv
Creates the hash context.
virtual ~crypt_hash()
Destroys the hash context.
Definition: Crypt.h:598
HCRYPTKEY wrapper class.
Definition: Crypt.h:655
virtual ~crypt_key()
Destroys the key.
Definition: Crypt.h:664
__declspec(deprecated("Use CryptGenKey")) bool generate(HCRYPTPROV hProv
Generates the key.
bool create_exp1(HCRYPTPROV hProv, DWORD dwKeySpec)
Creates Exponent-of-one key.
Definition: Crypt.h:742
handle_type duplicate_internal(handle_type h) const noexcept override
Duplicates the key.
Definition: Crypt.h:824
void free_internal() noexcept override
Destroys the key.
Definition: Crypt.h:810
__declspec(deprecated("Use CryptImportPublicKeyInfo")) bool import_public(HCRYPTPROV hCryptProv
Imports the public key.
__declspec(deprecated("Use CryptImportKey")) bool import(HCRYPTPROV hProv
Imports the key.
__declspec(deprecated("Use CryptDeriveKey")) bool derive(HCRYPTPROV hProv
Generates cryptographic session keys derived from a base data value.
HCRYPTPROV wrapper class.
Definition: Crypt.h:538
__declspec(deprecated("Use CryptAcquireContext")) bool create(LPCTSTR szContainer
Acquires the cryptographic context.
virtual ~crypt_prov()
Releases the cryptographic context.
Definition: Crypt.h:547
DATA_BLOB wrapper class.
Definition: Crypt.h:837
data_blob(const DATA_BLOB &other)
Duplicate an existing BLOB.
Definition: Crypt.h:860
virtual ~data_blob()
Destroys the BLOB.
Definition: Crypt.h:885
BYTE * data() noexcept
Get BLOB buffer.
Definition: Crypt.h:947
const BYTE * data() const noexcept
Get BLOB buffer.
Definition: Crypt.h:939
data_blob() noexcept
Initializes an empty BLOB.
Definition: Crypt.h:842
data_blob(data_blob &&other) noexcept
Move an existing BLOB.
Definition: Crypt.h:874
data_blob & operator=(data_blob &&other) noexcept
Move an existing BLOB.
Definition: Crypt.h:914
data_blob(BYTE *data, DWORD size) noexcept
Initializes a BLOB from existing data.
Definition: Crypt.h:851
DWORD size() const noexcept
Get BLOB size.
Definition: Crypt.h:931
data_blob & operator=(const DATA_BLOB &other)
Copy an existing BLOB.
Definition: Crypt.h:894
Base abstract template class to support object handle keeping for objects that support trivial handle...
Definition: Common.h:865
virtual handle_type duplicate_internal(handle_type h) const noexcept=0
Abstract member function that must be implemented by child classes to do the actual object handle dup...
Base abstract template class to support generic object handle keeping.
Definition: Common.h:603
virtual void free_internal() noexcept=0
Abstract member function that must be implemented by child classes to do the actual object destructio...
PCCERT_CONTEXT handle_type
Datatype of the object handle this template class handles.
Definition: Common.h:608
handle_type m_h
Object handle.
Definition: Common.h:854
void attach(handle_type h) noexcept
Sets a new object handle for the class.
Definition: Common.h:817
Windows runtime error.
Definition: Common.h:1047
#define WINSTD_STACK_BUFFER_BYTES
Size of the stack buffer in bytes used for initial system function call.
Definition: Common.h:79
#define WINSTD_DPLHANDLE_IMPL(C, INVAL)
Implements default constructors and operators to prevent their auto-generation by compiler.
Definition: Common.h:173
#define WINSTD_HANDLE_IMPL(C, INVAL)
Implements default constructors and operators to prevent their auto-generation by compiler.
Definition: Common.h:161
static const PCCERT_CONTEXT invalid
Invalid handle value.
Definition: Common.h:613