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
253 class cert_context : public dplhandle<PCCERT_CONTEXT, NULL>
254 {
256
257 public:
264 {
265 if (m_h != invalid)
267 }
268
277 bool operator==(_In_ const handle_type &other) const noexcept
278 {
279 // TODO: [Crypto] Make constant time.
280 return
281 m_h == other ||
282 m_h->cbCertEncoded == other->cbCertEncoded && memcmp(m_h->pbCertEncoded, other->pbCertEncoded, m_h->cbCertEncoded) == 0;
283 }
284
293 bool operator!=(_In_ const handle_type &other) const noexcept
294 {
295 return !operator==(other);
296 }
297
306 bool operator<(_In_ const handle_type &other) const noexcept
307 {
308 // TODO: [Crypto] Make constant time.
309 const int r = memcmp(m_h->pbCertEncoded, other->pbCertEncoded, std::min<DWORD>(m_h->cbCertEncoded, other->cbCertEncoded));
310 return r < 0 || r == 0 && m_h->cbCertEncoded < other->cbCertEncoded;
311 }
312
321 bool operator>(_In_ const handle_type &other) const noexcept
322 {
323 // TODO: [Crypto] Make constant time.
324 const int r = memcmp(m_h->pbCertEncoded, other->pbCertEncoded, std::min<DWORD>(m_h->cbCertEncoded, other->cbCertEncoded));
325 return r > 0 || r == 0 && m_h->cbCertEncoded > other->cbCertEncoded;
326 }
327
336 bool operator<=(_In_ const handle_type &other) const noexcept
337 {
338 return !operator>(other);
339 }
340
349 bool operator>=(_In_ const handle_type &other) const noexcept
350 {
351 return !operator<(other);
352 }
353
354 protected:
360 void free_internal() noexcept override
361 {
362 CertFreeCertificateContext(m_h);
363 }
364
374 handle_type duplicate_internal(_In_ handle_type h) const noexcept override
375 {
376 return CertDuplicateCertificateContext(h);
377 }
378 };
379
385 class cert_chain_context : public dplhandle<PCCERT_CHAIN_CONTEXT, NULL>
386 {
388
389 public:
396 {
397 if (m_h != invalid)
399 }
400
401 protected:
407 void free_internal() noexcept override
408 {
409 CertFreeCertificateChain(m_h);
410 }
411
421 handle_type duplicate_internal(_In_ handle_type h) const noexcept override
422 {
423 return CertDuplicateCertificateChain(h);
424 }
425 };
426
433 class cert_store : public handle<HCERTSTORE, NULL>
434 {
436
437 public:
443 virtual ~cert_store()
444 {
445 if (m_h != invalid)
447 }
448
449 protected:
455 void free_internal() noexcept override
456 {
457 CertCloseStore(m_h, 0);
458 }
459 };
460
466 class crypt_prov : public handle<HCRYPTPROV, NULL>
467 {
469
470 public:
476 virtual ~crypt_prov()
477 {
478 if (m_h != invalid)
480 }
481
482 protected:
488 void free_internal() noexcept override
489 {
490 CryptReleaseContext(m_h, 0);
491 }
492 };
493
499 class crypt_hash : public dplhandle<HCRYPTHASH, NULL>
500 {
502
503 public:
509 virtual ~crypt_hash()
510 {
511 if (m_h != invalid)
513 }
514
515 protected:
521 void free_internal() noexcept override
522 {
523 CryptDestroyHash(m_h);
524 }
525
535 handle_type duplicate_internal(_In_ handle_type h) const noexcept override
536 {
537 handle_type hNew;
538 return CryptDuplicateHash(h, NULL, 0, &hNew) ? hNew : invalid;
539 }
540 };
541
550 class crypt_key : public dplhandle<HCRYPTKEY, NULL>
551 {
553
554 public:
560 virtual ~crypt_key()
561 {
562 if (m_h != invalid)
564 }
565
574 bool create_exp1(_In_ HCRYPTPROV hProv, _In_ DWORD dwKeySpec)
575 {
576 if (dwKeySpec != AT_KEYEXCHANGE && dwKeySpec != AT_SIGNATURE) {
577 SetLastError(ERROR_INVALID_PARAMETER);
578 return false;
579 }
580
581 // Generate the private key.
582 handle_type h;
583 if (CryptGenKey(hProv, dwKeySpec, CRYPT_EXPORTABLE, &h)) {
584 // Export the private key, we'll convert it to a private exponent of one key.
585 std::vector<BYTE, sanitizing_allocator<BYTE>> key_blob;
586 if (CryptExportKey(h, 0, PRIVATEKEYBLOB, 0, key_blob)) {
587 CryptDestroyKey(h);
588
589 // Get the byte length of the key.
590 size_t
591 size_key = *reinterpret_cast<DWORD*>(&key_blob[12])/8,
592 size_prime = size_key/2;
593
594 // Modify the Exponent in Key BLOB format
595 // Key BLOB format is documented in SDK
596
597 // Convert pubexp in rsapubkey to 1
598 LPBYTE ptr = &key_blob[16];
599 *reinterpret_cast<DWORD*>(ptr) = 1;
600 ptr += sizeof(DWORD);
601
602 // Skip modulus, prime1, prime2
603 ptr += size_key;
604 ptr += size_prime;
605 ptr += size_prime;
606
607 // Convert exponent1 to 1
608 ptr[0] = 1;
609 memset(ptr + 1, 0, size_prime - 1);
610 ptr += size_prime;
611
612 // Convert exponent2 to 1
613 ptr[0] = 1;
614 memset(ptr + 1, 0, size_prime - 1);
615 ptr += size_prime;
616
617 // Skip coefficient
618 ptr += size_prime;
619
620 // Convert privateExponent to 1
621 ptr[0] = 1;
622 memset(ptr + 1, 0, size_key - 1);
623
624 // Import the exponent-of-one private key.
625 if (CryptImportKey(hProv, key_blob.data(), static_cast<DWORD>(key_blob.size()), 0, 0, &h)) {
626 attach(h);
627 return true;
628 }
629 } else
630 CryptDestroyKey(h);
631 }
632
633 return false;
634 }
635
636 protected:
642 void free_internal() noexcept override
643 {
644 CryptDestroyKey(m_h);
645 }
646
656 handle_type duplicate_internal(_In_ handle_type h) const noexcept override
657 {
658 handle_type hNew;
659 return CryptDuplicateKey(h, NULL, 0, &hNew) ? hNew : invalid;
660 }
661 };
662
666 #pragma warning(push)
667 #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.
668 class data_blob : public DATA_BLOB
669 {
670 public:
674 data_blob() noexcept
675 {
676 cbData = 0;
677 pbData = NULL;
678 }
679
683 data_blob(_In_count_(size) BYTE *data, _In_ DWORD size) noexcept
684 {
685 cbData = size;
686 pbData = data;
687 }
688
692 data_blob(_In_ const DATA_BLOB &other)
693 {
694 cbData = other.cbData;
695 if (cbData) {
696 pbData = static_cast<BYTE*>(LocalAlloc(LMEM_FIXED, other.cbData));
697 if (!pbData) throw win_runtime_error("LocalAlloc failed.");
698 memcpy(pbData, other.pbData, other.cbData);
699 } else
700 pbData = NULL;
701 }
702
706 data_blob(_Inout_ data_blob &&other) noexcept
707 {
708 cbData = other.cbData;
709 pbData = other.pbData;
710 other.cbData = 0;
711 other.pbData = NULL;
712 }
713
717 virtual ~data_blob()
718 {
719 if (pbData != NULL)
720 LocalFree(pbData);
721 }
722
726 data_blob& operator=(_In_ const DATA_BLOB &other)
727 {
728 if (this != &other) {
729 cbData = other.cbData;
730 if (pbData)
731 LocalFree(pbData);
732 if (cbData) {
733 pbData = static_cast<BYTE*>(LocalAlloc(LMEM_FIXED, other.cbData));
734 if (!pbData) throw win_runtime_error("LocalAlloc failed.");
735 memcpy(pbData, other.pbData, other.cbData);
736 } else
737 pbData = NULL;
738 }
739
740 return *this;
741 }
742
746 data_blob& operator=(_Inout_ data_blob &&other) noexcept
747 {
748 if (this != &other) {
749 cbData = other.cbData;
750 if (pbData)
751 LocalFree(pbData);
752 pbData = other.pbData;
753 other.cbData = 0;
754 other.pbData = NULL;
755 }
756
757 return *this;
758 }
759
763 DWORD size() const noexcept
764 {
765 return cbData;
766 }
767
771 const BYTE* data() const noexcept
772 {
773 return pbData;
774 }
775
779 BYTE* data() noexcept
780 {
781 return pbData;
782 }
783 };
784 #pragma warning(pop)
785
787}
788
791
792#pragma warning(push)
793#pragma warning(disable: 4505) // Don't warn on unused code
794
800static 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)
801{
802 PCCERT_CHAIN_CONTEXT pChainContext;
803 BOOL bResult = CertGetCertificateChain(hChainEngine, pCertContext, pTime, hAdditionalStore, pChainPara, dwFlags, pvReserved, &pChainContext);
804 if (bResult)
805 ctx.attach(pChainContext);
806 return bResult;
807}
808
810static BOOL CryptAcquireContextA(_Inout_ winstd::crypt_prov &prov, _In_opt_ LPCSTR szContainer, _In_opt_ LPCSTR szProvider, _In_ DWORD dwProvType, _In_ DWORD dwFlags)
811{
812 HCRYPTPROV h;
813 BOOL bResult = CryptAcquireContextA(&h, szContainer, szProvider, dwProvType, dwFlags);
814 if (bResult)
815 prov.attach(h);
816 return bResult;
817}
818
824static BOOL CryptAcquireContextW(_Inout_ winstd::crypt_prov &prov, _In_opt_ LPCWSTR szContainer, _In_opt_ LPCWSTR szProvider, _In_ DWORD dwProvType, _In_ DWORD dwFlags)
825{
826 HCRYPTPROV h;
827 BOOL bResult = CryptAcquireContextW(&h, szContainer, szProvider, dwProvType, dwFlags);
828 if (bResult)
829 prov.attach(h);
830 return bResult;
831}
832
838static BOOL CryptCreateHash(_In_ HCRYPTPROV hProv, _In_ ALG_ID Algid, _In_ HCRYPTKEY hKey, _In_ DWORD dwFlags, _Inout_ winstd::crypt_hash &hash)
839{
840 HCRYPTHASH h;
841 BOOL bResult = CryptCreateHash(hProv, Algid, hKey, dwFlags, &h);
842 if (bResult)
843 hash.attach(h);
844 return bResult;
845}
846
852static BOOL CryptGenKey(_In_ HCRYPTPROV hProv, _In_ ALG_ID Algid, _In_ DWORD dwFlags, _Inout_ winstd::crypt_key &key)
853{
854 HCRYPTKEY h;
855 BOOL bResult = CryptGenKey(hProv, Algid, dwFlags, &h);
856 if (bResult)
857 key.attach(h);
858 return bResult;
859}
860
866static bool CryptImportKey(_In_ HCRYPTPROV hProv, __in_bcount(dwDataLen) LPCBYTE pbData, _In_ DWORD dwDataLen, _In_ HCRYPTKEY hPubKey, _In_ DWORD dwFlags, _Inout_ winstd::crypt_key &key)
867{
868 HCRYPTKEY h;
869 BOOL bResult = CryptImportKey(hProv, pbData, dwDataLen, hPubKey, dwFlags, &h);
870 if (bResult)
871 key.attach(h);
872 return bResult;
873}
874
880static bool CryptImportPublicKeyInfo(_In_ HCRYPTPROV hCryptProv, _In_ DWORD dwCertEncodingType, _In_ PCERT_PUBLIC_KEY_INFO pInfo, _Inout_ winstd::crypt_key &key)
881{
882 HCRYPTKEY h;
883 BOOL bResult = CryptImportPublicKeyInfo(hCryptProv, dwCertEncodingType, pInfo, &h);
884 if (bResult)
885 key.attach(h);
886 return bResult;
887}
888
894static bool CryptDeriveKey(_In_ HCRYPTPROV hProv, _In_ ALG_ID Algid, _In_ HCRYPTHASH hBaseData, _In_ DWORD dwFlags, _Inout_ winstd::crypt_key &key)
895{
896 HCRYPTKEY h;
897 BOOL bResult = CryptDeriveKey(hProv, Algid, hBaseData, dwFlags, &h);
898 if (bResult)
899 key.attach(h);
900 return bResult;
901}
902
903#pragma warning(pop)
904
PCCERT_CHAIN_CONTEXT wrapper class.
Definition: Crypt.h:386
handle_type duplicate_internal(handle_type h) const noexcept override
Duplicates the certificate chain context.
Definition: Crypt.h:421
virtual ~cert_chain_context()
Destroys the certificate chain context.
Definition: Crypt.h:395
void free_internal() noexcept override
Destroys the certificate chain context.
Definition: Crypt.h:407
PCCERT_CONTEXT wrapper class.
Definition: Crypt.h:254
bool operator<=(const handle_type &other) const noexcept
Is certificate less than or equal?
Definition: Crypt.h:336
void free_internal() noexcept override
Destroys the certificate context.
Definition: Crypt.h:360
bool operator==(const handle_type &other) const noexcept
Is certificate equal to?
Definition: Crypt.h:277
handle_type duplicate_internal(handle_type h) const noexcept override
Duplicates the certificate context.
Definition: Crypt.h:374
bool operator>=(const handle_type &other) const noexcept
Is certificate greater than or equal?
Definition: Crypt.h:349
bool operator>(const handle_type &other) const noexcept
Is certificate greater than?
Definition: Crypt.h:321
bool operator<(const handle_type &other) const noexcept
Is certificate less than?
Definition: Crypt.h:306
bool operator!=(const handle_type &other) const noexcept
Is certificate not equal to?
Definition: Crypt.h:293
virtual ~cert_context()
Destroys the certificate context.
Definition: Crypt.h:263
HCERTSTORE wrapper class.
Definition: Crypt.h:434
virtual ~cert_store()
Closes the certificate store.
Definition: Crypt.h:443
void free_internal() noexcept override
Closes the certificate store.
Definition: Crypt.h:455
HCRYPTHASH wrapper class.
Definition: Crypt.h:500
void free_internal() noexcept override
Destroys the hash context.
Definition: Crypt.h:521
virtual ~crypt_hash()
Destroys the hash context.
Definition: Crypt.h:509
handle_type duplicate_internal(handle_type h) const noexcept override
Duplicates the hash context.
Definition: Crypt.h:535
HCRYPTKEY wrapper class.
Definition: Crypt.h:551
virtual ~crypt_key()
Destroys the key.
Definition: Crypt.h:560
bool create_exp1(HCRYPTPROV hProv, DWORD dwKeySpec)
Creates Exponent-of-one key.
Definition: Crypt.h:574
handle_type duplicate_internal(handle_type h) const noexcept override
Duplicates the key.
Definition: Crypt.h:656
void free_internal() noexcept override
Destroys the key.
Definition: Crypt.h:642
HCRYPTPROV wrapper class.
Definition: Crypt.h:467
virtual ~crypt_prov()
Releases the cryptographic context.
Definition: Crypt.h:476
void free_internal() noexcept override
Releases the cryptographic context.
Definition: Crypt.h:488
DATA_BLOB wrapper class.
Definition: Crypt.h:669
data_blob(const DATA_BLOB &other)
Duplicate an existing BLOB.
Definition: Crypt.h:692
virtual ~data_blob()
Destroys the BLOB.
Definition: Crypt.h:717
BYTE * data() noexcept
Get BLOB buffer.
Definition: Crypt.h:779
const BYTE * data() const noexcept
Get BLOB buffer.
Definition: Crypt.h:771
data_blob() noexcept
Initializes an empty BLOB.
Definition: Crypt.h:674
data_blob(data_blob &&other) noexcept
Move an existing BLOB.
Definition: Crypt.h:706
data_blob & operator=(data_blob &&other) noexcept
Move an existing BLOB.
Definition: Crypt.h:746
data_blob(BYTE *data, DWORD size) noexcept
Initializes a BLOB from existing data.
Definition: Crypt.h:683
DWORD size() const noexcept
Get BLOB size.
Definition: Crypt.h:763
data_blob & operator=(const DATA_BLOB &other)
Copy an existing BLOB.
Definition: Crypt.h:726
Base abstract template class to support object handle keeping for objects that support trivial handle...
Definition: Common.h:865
Base abstract template class to support generic object handle keeping.
Definition: Common.h:603
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