[ATL] [3RDPARTY] Updated & moved atlex to sdk/lib/3rdparty
[reactos.git] / reactos / sdk / lib / 3rdparty / atlex / atlcrypt.h
1 /*
2 Copyright 1991-2017 Amebis
3
4 This file is part of atlex.
5
6 atlex is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
10
11 atlex is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with atlex. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #pragma once
21
22 #include "atlex.h"
23 #include <atlcoll.h>
24 #include <atlstr.h>
25 #include <WinCrypt.h>
26
27 ///
28 /// \defgroup ATLCryptoAPI Cryptography API
29 /// Integrates ATL classes with Microsoft Cryptography API
30 ///
31 /// @{
32
33 ///
34 /// Obtains the subject or issuer name from a certificate [CERT_CONTEXT](https://msdn.microsoft.com/en-us/library/windows/desktop/aa377189.aspx) structure and stores it in a ATL::CAtlStringA string.
35 ///
36 /// \sa [CertGetNameString function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376086.aspx)
37 ///
38 inline DWORD CertGetNameStringA(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_ void *pvTypePara, _Out_ ATL::CAtlStringA &sNameString)
39 {
40 // Query the final string length first.
41 DWORD dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0);
42
43 // Allocate buffer on heap to format the string data into and read it.
44 LPSTR szBuffer = sNameString.GetBuffer(dwSize);
45 if (!szBuffer) return ERROR_OUTOFMEMORY;
46 dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, szBuffer, dwSize);
47 sNameString.ReleaseBuffer(dwSize);
48 return dwSize;
49 }
50
51
52 ///
53 /// Obtains the subject or issuer name from a certificate [CERT_CONTEXT](https://msdn.microsoft.com/en-us/library/windows/desktop/aa377189.aspx) structure and stores it in a ATL::CAtlStringW string.
54 ///
55 /// \sa [CertGetNameString function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376086.aspx)
56 ///
57 inline DWORD CertGetNameStringW(_In_ PCCERT_CONTEXT pCertContext, _In_ DWORD dwType, _In_ DWORD dwFlags, _In_ void *pvTypePara, _Out_ ATL::CAtlStringW &sNameString)
58 {
59 // Query the final string length first.
60 DWORD dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0);
61
62 // Allocate buffer on heap to format the string data into and read it.
63 LPWSTR szBuffer = sNameString.GetBuffer(dwSize);
64 if (!szBuffer) return ERROR_OUTOFMEMORY;
65 dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, szBuffer, dwSize);
66 sNameString.ReleaseBuffer(dwSize);
67 return dwSize;
68 }
69
70
71 ///
72 /// Retrieves data that governs the operations of a hash object. The actual hash value can be retrieved by using this function.
73 ///
74 /// \sa [CryptGetHashParam function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379947.aspx)
75 ///
76 inline BOOL CryptGetHashParam(_In_ HCRYPTHASH hHash, _In_ DWORD dwParam, _Out_ ATL::CAtlArray<BYTE> &aData, _In_ DWORD dwFlags)
77 {
78 DWORD dwHashSize;
79
80 if (CryptGetHashParam(hHash, dwParam, NULL, &dwHashSize, dwFlags)) {
81 if (aData.SetCount(dwHashSize)) {
82 if (CryptGetHashParam(hHash, dwParam, aData.GetData(), &dwHashSize, dwFlags)) {
83 return TRUE;
84 } else {
85 aData.SetCount(0);
86 return FALSE;
87 }
88 } else {
89 SetLastError(ERROR_OUTOFMEMORY);
90 return FALSE;
91 }
92 } else
93 return FALSE;
94 }
95
96
97 ///
98 /// Exports a cryptographic key or a key pair from a cryptographic service provider (CSP) in a secure manner.
99 ///
100 /// \sa [CryptExportKey function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379931.aspx)
101 ///
102 inline BOOL CryptExportKey(_In_ HCRYPTKEY hKey, _In_ HCRYPTKEY hExpKey, _In_ DWORD dwBlobType, _In_ DWORD dwFlags, _Out_ ATL::CAtlArray<BYTE> &aData)
103 {
104 DWORD dwKeyBLOBSize;
105
106 if (CryptExportKey(hKey, hExpKey, dwBlobType, dwFlags, NULL, &dwKeyBLOBSize)) {
107 if (aData.SetCount(dwKeyBLOBSize)) {
108 if (CryptExportKey(hKey, hExpKey, dwBlobType, dwFlags, aData.GetData(), &dwKeyBLOBSize)) {
109 return TRUE;
110 } else {
111 aData.SetCount(0);
112 return FALSE;
113 }
114 } else {
115 SetLastError(ERROR_OUTOFMEMORY);
116 return FALSE;
117 }
118 } else
119 return FALSE;
120 }
121
122 /// @}
123
124
125 namespace ATL
126 {
127 namespace Crypt
128 {
129 /// \addtogroup ATLCryptoAPI
130 /// @{
131
132 ///
133 /// PCCERT_CONTEXT wrapper class
134 ///
135 class CCertContext : public ATL::CObjectWithHandleDuplT<PCCERT_CONTEXT>
136 {
137 public:
138 ///
139 /// Destroys the certificate context.
140 ///
141 /// \sa [CertFreeCertificateContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376075.aspx)
142 ///
143 virtual ~CCertContext()
144 {
145 if (m_h)
146 CertFreeCertificateContext(m_h);
147 }
148
149 ///
150 /// Creates the certificate context.
151 ///
152 /// \return
153 /// - TRUE when creation succeeds;
154 /// - FALSE when creation fails. For extended error information, call `GetLastError()`.
155 /// \sa [CertCreateCertificateContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376033.aspx)
156 ///
157 inline BOOL Create(_In_ DWORD dwCertEncodingType, _In_ const BYTE *pbCertEncoded, _In_ DWORD cbCertEncoded)
158 {
159 HANDLE h = CertCreateCertificateContext(dwCertEncodingType, pbCertEncoded, cbCertEncoded);
160 if (h) {
161 Attach(h);
162 return TRUE;
163 } else
164 return FALSE;
165 }
166
167 protected:
168 ///
169 /// Destroys the certificate context.
170 ///
171 /// \sa [CertFreeCertificateContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376075.aspx)
172 ///
173 virtual void InternalFree()
174 {
175 CertFreeCertificateContext(m_h);
176 }
177
178 ///
179 /// Duplicates the certificate context.
180 ///
181 /// \param[in] h Object handle of existing certificate context
182 /// \return Duplicated certificate context handle
183 /// \sa [CertDuplicateCertificateContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376045.aspx)
184 ///
185 virtual HANDLE InternalDuplicate(_In_ HANDLE h) const
186 {
187 return CertDuplicateCertificateContext(h);
188 }
189 };
190
191
192 ///
193 /// PCCERT_CHAIN_CONTEXT wrapper class
194 ///
195 class CCertChainContext : public ATL::CObjectWithHandleDuplT<PCCERT_CHAIN_CONTEXT>
196 {
197 public:
198 ///
199 /// Destroys the certificate chain context.
200 ///
201 /// \sa [CertFreeCertificateChain function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376073.aspx)
202 ///
203 virtual ~CCertChainContext()
204 {
205 if (m_h)
206 CertFreeCertificateChain(m_h);
207 }
208
209 ///
210 /// Creates the certificate chain context.
211 ///
212 /// \return
213 /// - TRUE when creation succeeds;
214 /// - FALSE when creation fails. For extended error information, call `GetLastError()`.
215 /// \sa [CertGetCertificateChain function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376078.aspx)
216 ///
217 inline 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)
218 {
219 HANDLE h;
220 if (CertGetCertificateChain(hChainEngine, pCertContext, pTime, hAdditionalStore, pChainPara, dwFlags, pvReserved, &h)) {
221 Attach(h);
222 return TRUE;
223 } else
224 return FALSE;
225 }
226
227 protected:
228 ///
229 /// Destroys the certificate chain context.
230 ///
231 /// \sa [CertFreeCertificateChain function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376073.aspx)
232 ///
233 virtual void InternalFree()
234 {
235 CertFreeCertificateChain(m_h);
236 }
237
238 ///
239 /// Duplicates the certificate chain context.
240 ///
241 /// \param[in] h Object handle of existing certificate chain context
242 /// \return Duplicated certificate chain context handle
243 /// \sa [CertDuplicateCertificateContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376045.aspx)
244 ///
245 virtual HANDLE InternalDuplicate(_In_ HANDLE h) const
246 {
247 return CertDuplicateCertificateChain(h);
248 }
249 };
250
251
252 ///
253 /// HCERTSTORE wrapper class
254 ///
255 class CCertStore : public ATL::CObjectWithHandleT<HCERTSTORE>
256 {
257 public:
258 ///
259 /// Closes the certificate store.
260 ///
261 /// \sa [CertCloseStore function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376026.aspx)
262 ///
263 virtual ~CCertStore()
264 {
265 if (m_h)
266 CertCloseStore(m_h, 0);
267 }
268
269 ///
270 /// Opens the certificate store.
271 ///
272 /// \return
273 /// - TRUE when creation succeeds;
274 /// - FALSE when creation fails. For extended error information, call `GetLastError()`.
275 /// \sa [CertOpenStore function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376559.aspx)
276 ///
277 inline BOOL Create(_In_ LPCSTR lpszStoreProvider, _In_ DWORD dwEncodingType, _In_opt_ HCRYPTPROV_LEGACY hCryptProv, _In_ DWORD dwFlags, _In_opt_ const void *pvPara)
278 {
279 HANDLE h = CertOpenStore(lpszStoreProvider, dwEncodingType, hCryptProv, dwFlags, pvPara);
280 if (h) {
281 Attach(h);
282 return TRUE;
283 } else
284 return FALSE;
285 }
286
287 protected:
288 ///
289 /// Closes the certificate store.
290 ///
291 /// \sa [CertCloseStore function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376026.aspx)
292 ///
293 virtual void InternalFree()
294 {
295 CertCloseStore(m_h, 0);
296 }
297 };
298
299
300 ///
301 /// HCRYPTPROV wrapper class
302 ///
303 class CContext : public ATL::CObjectWithHandleT<HCRYPTPROV>
304 {
305 public:
306 ///
307 /// Releases the cryptographi context.
308 ///
309 /// \sa [CryptReleaseContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380268.aspx)
310 ///
311 virtual ~CContext()
312 {
313 if (m_h)
314 CryptReleaseContext(m_h, 0);
315 }
316
317 ///
318 /// Acquires the cryptographic context.
319 ///
320 /// \return
321 /// - TRUE when creation succeeds;
322 /// - FALSE when creation fails. For extended error information, call `GetLastError()`.
323 /// \sa [CryptAcquireContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379886.aspx)
324 ///
325 inline BOOL Create(_In_opt_ LPCTSTR szContainer, _In_opt_ LPCTSTR szProvider, _In_ DWORD dwProvType, _In_ DWORD dwFlags)
326 {
327 HANDLE h;
328 if (CryptAcquireContext(&h, szContainer, szProvider, dwProvType, dwFlags)) {
329 Attach(h);
330 return TRUE;
331 } else
332 return FALSE;
333 }
334
335 protected:
336 ///
337 /// Releases the cryptographic context.
338 ///
339 /// \sa [CryptReleaseContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380268.aspx)
340 ///
341 virtual void InternalFree()
342 {
343 CryptReleaseContext(m_h, 0);
344 }
345 };
346
347
348 ///
349 /// HCRYPTHASH wrapper class
350 ///
351 class CHash : public ATL::CObjectWithHandleDuplT<HCRYPTHASH>
352 {
353 public:
354 ///
355 /// Destroys the hash context.
356 ///
357 /// \sa [CryptDestroyHash function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379917.aspx)
358 ///
359 virtual ~CHash()
360 {
361 if (m_h)
362 CryptDestroyHash(m_h);
363 }
364
365 ///
366 /// Creates the hash context.
367 ///
368 /// \return
369 /// - TRUE when creation succeeds;
370 /// - FALSE when creation fails. For extended error information, call `GetLastError()`.
371 /// \sa [CryptCreateHash function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379908.aspx)
372 ///
373 inline BOOL Create(_In_ HCRYPTPROV hProv, _In_ ALG_ID Algid, _In_ HCRYPTKEY hKey, _In_ DWORD dwFlags)
374 {
375 HANDLE h;
376 if (CryptCreateHash(hProv, Algid, hKey, dwFlags, &h)) {
377 Attach(h);
378 return TRUE;
379 } else
380 return FALSE;
381 }
382
383 protected:
384 ///
385 /// Destroys the hash context.
386 ///
387 /// \sa [CryptDestroyHash function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379917.aspx)
388 ///
389 virtual void InternalFree()
390 {
391 CryptDestroyHash(m_h);
392 }
393
394 ///
395 /// Duplicates the hash context.
396 ///
397 /// \param[in] h Object handle of existing hash context
398 /// \return Duplicated hash context handle
399 /// \sa [CryptDuplicateHash function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379919.aspx)
400 ///
401 virtual HANDLE InternalDuplicate(_In_ HANDLE h) const
402 {
403 HANDLE hNew = NULL;
404 return CryptDuplicateHash(h, NULL, 0, &hNew) ? hNew : NULL;
405 }
406 };
407
408
409 ///
410 /// HCRYPTKEY wrapper class
411 ///
412 class CKey : public ATL::CObjectWithHandleDuplT<HCRYPTKEY>
413 {
414 public:
415 ///
416 /// Destroys the key.
417 ///
418 /// \sa [CryptDestroyKey function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379918.aspx)
419 ///
420 virtual ~CKey()
421 {
422 if (m_h)
423 CryptDestroyKey(m_h);
424 }
425
426 ///
427 /// Generates the key.
428 ///
429 /// \sa [CryptGenKey function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379941.aspx)
430 ///
431 inline BOOL Generate(_In_ HCRYPTPROV hProv, _In_ ALG_ID Algid, _In_ DWORD dwFlags)
432 {
433 HANDLE h;
434 if (CryptGenKey(hProv, Algid, dwFlags, &h)) {
435 Attach(h);
436 return TRUE;
437 } else
438 return FALSE;
439 }
440
441 ///
442 /// Imports the key.
443 ///
444 /// \sa [CryptImportKey function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380207.aspx)
445 ///
446 inline BOOL Import(_In_ HCRYPTPROV hProv, __in_bcount(dwDataLen) CONST BYTE *pbData, _In_ DWORD dwDataLen, _In_ HCRYPTKEY hPubKey, _In_ DWORD dwFlags)
447 {
448 HANDLE h;
449 if (CryptImportKey(hProv, pbData, dwDataLen, hPubKey, dwFlags, &h)) {
450 Attach(h);
451 return TRUE;
452 } else
453 return FALSE;
454 }
455
456 ///
457 /// Imports the public key.
458 ///
459 /// \sa [CryptImportPublicKeyInfo function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa380209.aspx)
460 ///
461 inline BOOL ImportPublic(_In_ HCRYPTPROV hCryptProv, _In_ DWORD dwCertEncodingType, _In_ PCERT_PUBLIC_KEY_INFO pInfo)
462 {
463 HANDLE h;
464 if (CryptImportPublicKeyInfo(hCryptProv, dwCertEncodingType, pInfo, &h)) {
465 Attach(h);
466 return TRUE;
467 } else
468 return FALSE;
469 }
470
471 protected:
472 ///
473 /// Destroys the key.
474 ///
475 /// \sa [CryptDestroyKey function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379918.aspx)
476 ///
477 virtual void InternalFree()
478 {
479 CryptDestroyKey(m_h);
480 }
481
482 ///
483 /// Duplicates the key.
484 ///
485 /// \param[in] h Object handle of existing key
486 /// \return Duplicated key handle
487 /// \sa [CryptDuplicateKey function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379920.aspx)
488 ///
489 virtual HANDLE InternalDuplicate(_In_ HANDLE h) const
490 {
491 HANDLE hNew = NULL;
492 return CryptDuplicateKey(h, NULL, 0, &hNew) ? hNew : NULL;
493 }
494 };
495
496 /// @}
497 }
498 }