Async 1.8.0
AsyncDigest.h
Go to the documentation of this file.
1
31#ifndef ASYNC_DIGEST_INCLUDED
32#define ASYNC_DIGEST_INCLUDED
33
34
35/****************************************************************************
36 *
37 * System Includes
38 *
39 ****************************************************************************/
40
41#include <stdlib.h>
42#include <openssl/evp.h>
43#include <openssl/err.h>
44
45#include <vector>
46#include <cstddef>
47
48
49/****************************************************************************
50 *
51 * Project Includes
52 *
53 ****************************************************************************/
54
55#include <AsyncSslKeypair.h>
56
57
58/****************************************************************************
59 *
60 * Local Includes
61 *
62 ****************************************************************************/
63
64
65
66/****************************************************************************
67 *
68 * Forward declarations
69 *
70 ****************************************************************************/
71
72
73
74/****************************************************************************
75 *
76 * Namespace
77 *
78 ****************************************************************************/
79
80namespace Async
81{
82
83
84/****************************************************************************
85 *
86 * Forward declarations of classes inside of the declared namespace
87 *
88 ****************************************************************************/
89
90
91
92/****************************************************************************
93 *
94 * Defines & typedefs
95 *
96 ****************************************************************************/
97
98
99
100/****************************************************************************
101 *
102 * Exported Global Variables
103 *
104 ****************************************************************************/
105
106
107
108/****************************************************************************
109 *
110 * Class definitions
111 *
112 ****************************************************************************/
113
124{
125 public:
126 using Signature = std::vector<uint8_t>;
127 using MsgDigest = std::vector<uint8_t>;
128
129 static bool sigEqual(const Signature& s1, const Signature& s2)
130 {
131 return (s1.size() == s2.size()) &&
132 (CRYPTO_memcmp(s1.data(), s2.data(), s1.size()) == 0);
133 }
134
138 Digest(void)
139 {
140#if OPENSSL_VERSION_MAJOR < 3
141 static bool global_is_initialized = false;
142 if (!global_is_initialized)
143 {
144 //std::cout << "### Digest::Digest: OpenSSL_add_all_digests"
145 // << std::endl;
146 OpenSSL_add_all_digests();
147 global_is_initialized = true;
148 }
149#endif
150 m_ctx = EVP_MD_CTX_new();
151 if (m_ctx == nullptr)
152 {
153 std::cerr << "*** ERROR: EVP_MD_CTX_new failed, error "
154 << ERR_get_error() << std::endl;
155 abort();
156 }
157 }
158
162 Digest(const Digest&) = delete;
163
167 Digest& operator=(const Digest&) = delete;
168
173 {
174 EVP_MD_CTX_free(m_ctx);
175 m_ctx = nullptr;
176 }
177
184 bool mdInit(const std::string& md_alg)
185 {
186 MessageDigest md(md_alg);
187 if (md == nullptr)
188 {
189 std::cerr << "*** ERROR: EVP_MD_fetch failed, error "
190 << ERR_get_error() << std::endl;
191 return false;
192 }
193 int rc = EVP_DigestInit_ex(m_ctx, md, nullptr);
194 //EVP_MD_free(md);
195 if (rc != 1)
196 {
197 std::cerr << "*** ERROR: EVP_DigestInit_ex failed, error "
198 << ERR_get_error() << std::endl;
199 return false;
200 }
201 return true;
202 }
203
204 bool mdUpdate(const void* d, size_t dlen)
205 {
206 int rc = EVP_DigestUpdate(m_ctx, d, dlen);
207 if (rc != 1)
208 {
209 std::cerr << "*** ERROR: EVP_DigestUpdate failed, error "
210 << ERR_get_error() << std::endl;
211 return false;
212 }
213 return true;
214 }
215
216 template <class T>
217 bool mdUpdate(const T& d)
218 {
219 return mdUpdate(d.data(), d.size());
220 }
221
223 {
224 unsigned int mdlen = EVP_MAX_MD_SIZE;
225 md.resize(mdlen);
226 int rc = EVP_DigestFinal_ex(m_ctx, md.data(), &mdlen);
227 if (rc != 1)
228 {
229 std::cerr << "*** ERROR: EVP_DigestFinal_ex failed, error "
230 << ERR_get_error() << std::endl;
231 md.clear();
232 return false;
233 }
234 md.resize(mdlen);
235 return true;
236 }
237
239 {
240 MsgDigest digest;
241 (void)mdFinal(digest);
242 return digest;
243 }
244
245 bool md(MsgDigest& digest, const std::string& md_alg,
246 const void* d, size_t dlen)
247 {
248 return mdInit(md_alg) && mdUpdate(d, dlen) && mdFinal(digest);
249 }
250
251 template <class T>
252 bool md(MsgDigest& digest, const std::string& md_alg, const T& d)
253 {
254 return md(digest, md_alg, d.data(), d.size());
255 }
256
257 template <class T>
258 MsgDigest md(const std::string& md_alg, const T& d)
259 {
260 MsgDigest digest;
261 (void)md(digest, md_alg, d);
262 return digest;
263 }
264
265
266 bool signInit(const std::string& md_alg, SslKeypair& pkey)
267 {
268 //EVP_MD* md = EVP_MD_fetch(nullptr, md_alg.c_str(), nullptr);
269 MessageDigest md(md_alg);
270 if (md == nullptr)
271 {
272 std::cerr << "*** ERROR: EVP_MD_fetch failed, error "
273 << ERR_get_error() << std::endl;
274 return false;
275 }
276 int rc = EVP_DigestSignInit(m_ctx, NULL, md, NULL, pkey);
277 //EVP_MD_free(md);
278 if (rc != 1)
279 {
280 std::cerr << "*** ERROR: EVP_DigestSignInit failed, error "
281 << ERR_get_error() << std::endl;
282 return false;
283 }
284 return true;
285 }
286
287 bool signUpdate(const void* msg, size_t mlen)
288 {
289 int rc = EVP_DigestSignUpdate(m_ctx,
290 reinterpret_cast<const unsigned char*>(msg), mlen);
291 if (rc != 1)
292 {
293 std::cerr << "*** ERROR: EVP_DigestSignUpdate failed, error "
294 << ERR_get_error() << std::endl;
295 return false;
296 }
297 return true;
298 }
299
300 template <class T>
301 bool signUpdate(const T& msg)
302 {
303 return signUpdate(msg.data(), msg.size());
304 }
305
307 {
308 sig.clear();
309 size_t req = 0;
310 int rc = EVP_DigestSignFinal(m_ctx, NULL, &req);
311 if (rc != 1)
312 {
313 std::cerr << "*** ERROR: EVP_DigestSignFinal (1) failed , error "
314 << ERR_get_error() << std::endl;
315 return false;
316 }
317 sig.resize(req);
318 rc = EVP_DigestSignFinal(m_ctx, sig.data(), &req);
319 if (rc != 1)
320 {
321 std::cerr << "*** ERROR: EVP_DigestSignFinal (2) failed, error "
322 << ERR_get_error() << std::endl;
323 sig.clear();
324 return false;
325 }
326 return true;
327 }
328
330 {
331 Signature sig;
332 (void)signFinal(sig);
333 return sig;
334 }
335
336 bool sign(Signature& sig, const void* msg, size_t mlen)
337 {
338 sig.clear();
339
340#if OPENSSL_VERSION_MAJOR >= 3
341 size_t siglen = 0;
342 int rc = EVP_DigestSign(m_ctx, nullptr, &siglen,
343 reinterpret_cast<const unsigned char*>(msg), mlen);
344 if (rc != 1)
345 {
346 std::cerr << "*** ERROR: EVP_DigestSign (1) failed, error "
347 << ERR_get_error() << std::endl;
348 return false;
349 }
350 sig.resize(siglen);
351 rc = EVP_DigestSign(m_ctx, sig.data(), &siglen,
352 reinterpret_cast<const unsigned char*>(msg), mlen);
353 if (rc != 1)
354 {
355 std::cerr << "*** ERROR: EVP_DigestSign (2) failed, error "
356 << ERR_get_error() << std::endl;
357 sig.clear();
358 return false;
359 }
360 return true;
361#else
362 return signUpdate(msg, mlen) && signFinal(sig);
363#endif
364 }
365
366 template <class T>
367 bool sign(Signature& sig, const T& msg)
368 {
369 return sign(sig, msg.data(), msg.size());
370 }
371
372 Signature sign(const void* msg, size_t mlen)
373 {
374 Signature sig;
375 (void)sign(sig, msg, mlen);
376 return sig;
377 }
378
379 template <class T>
380 Signature sign(const T& msg)
381 {
382 return sign(msg.data(), msg.size());
383 }
384
385 bool signVerifyInit(const std::string& md_alg, SslKeypair& pkey)
386 {
387 assert(!pkey.isNull());
388 //EVP_MD* md = EVP_MD_fetch(nullptr, md_alg.c_str(), nullptr);
389 MessageDigest md(md_alg);
390 if (md == nullptr)
391 {
392 return false;
393 }
394 int rc = EVP_DigestVerifyInit(m_ctx, NULL, md, NULL, pkey);
395 //EVP_MD_free(md);
396 if (rc != 1)
397 {
398 std::cerr << "*** ERROR: EVP_DigestVerifyInit failed, error "
399 << ERR_get_error() << std::endl;
400 return false;
401 }
402 return true;
403 }
404
405 bool signVerifyUpdate(const void* msg, size_t mlen)
406 {
407 assert((msg != nullptr) && (mlen > 0));
408 int rc = EVP_DigestVerifyUpdate(m_ctx,
409 reinterpret_cast<const unsigned char*>(msg), mlen);
410 if (rc != 1)
411 {
412 std::cerr << "*** ERROR: EVP_DigestVerifyUpdate failed, error "
413 << ERR_get_error() << std::endl;
414 return false;
415 }
416 return true;
417 }
418
419 template <class T>
420 bool signVerifyUpdate(const T& msg)
421 {
422 return signVerifyUpdate(msg.data(), msg.size());
423 }
424
425 bool signVerifyFinal(const Signature& sig)
426 {
427 int rc = EVP_DigestVerifyFinal(m_ctx, sig.data(), sig.size());
428 return (rc == 1);
429 }
430
431 bool signVerify(const Signature& sig, const void* msg, size_t mlen)
432 {
433#if OPENSSL_VERSION_MAJOR >= 3
434 int rc = EVP_DigestVerify(m_ctx, sig.data(), sig.size(),
435 reinterpret_cast<const unsigned char*>(msg), mlen);
436 return (rc == 1);
437#else
438 return signVerifyUpdate(msg, mlen) && signVerifyFinal(sig);
439#endif
440 }
441
442 template <class T>
443 bool signVerify(const Signature& sig, const T& msg)
444 {
445 return signVerify(sig, msg.data(), msg.size());
446 }
447
448 protected:
449
450 private:
451 class MessageDigest
452 {
453 public:
454 MessageDigest(const std::string& md_alg)
455 {
456#if OPENSSL_VERSION_MAJOR >= 3
457 m_md = EVP_MD_fetch(nullptr, md_alg.c_str(), nullptr);
458#else
459 m_md = EVP_get_digestbyname(md_alg.c_str());
460#endif
461 }
462 ~MessageDigest(void)
463 {
464#if OPENSSL_VERSION_MAJOR >= 3
465 EVP_MD_free(m_md);
466#endif
467 m_md = nullptr;
468 }
469 operator const EVP_MD*() const { return m_md; }
470 bool operator==(std::nullptr_t) const { return (m_md == nullptr); }
471 private:
472#if OPENSSL_VERSION_MAJOR >= 3
473 EVP_MD* m_md = nullptr;
474#else
475 const EVP_MD* m_md = nullptr;
476#endif
477 };
478
479 EVP_MD_CTX* m_ctx = nullptr;
480
481}; /* class Digest */
482
483
484} /* namespace Async */
485
486#endif /* ASYNC_DIGEST_INCLUDED */
487
488/*
489 * This file has not been truncated
490 */
Represent private and public keys.
A_brief_class_description.
MsgDigest md(const std::string &md_alg, const T &d)
bool mdUpdate(const void *d, size_t dlen)
bool signVerify(const Signature &sig, const T &msg)
bool signVerify(const Signature &sig, const void *msg, size_t mlen)
bool signUpdate(const void *msg, size_t mlen)
bool mdUpdate(const T &d)
bool signVerifyUpdate(const T &msg)
bool mdFinal(MsgDigest &md)
Signature signFinal(void)
Signature sign(const void *msg, size_t mlen)
~Digest(void)
Destructor.
Digest & operator=(const Digest &)=delete
Disallow copy assignment.
bool mdInit(const std::string &md_alg)
A_brief_member_function_description.
Digest(void)
Default constructor.
bool md(MsgDigest &digest, const std::string &md_alg, const T &d)
bool signVerifyFinal(const Signature &sig)
std::vector< uint8_t > Signature
bool signFinal(Signature &sig)
bool sign(Signature &sig, const T &msg)
MsgDigest mdFinal(void)
bool sign(Signature &sig, const void *msg, size_t mlen)
bool signVerifyUpdate(const void *msg, size_t mlen)
bool signInit(const std::string &md_alg, SslKeypair &pkey)
std::vector< uint8_t > MsgDigest
bool signVerifyInit(const std::string &md_alg, SslKeypair &pkey)
static bool sigEqual(const Signature &s1, const Signature &s2)
Digest(const Digest &)=delete
Disallow copy construction.
bool md(MsgDigest &digest, const std::string &md_alg, const void *d, size_t dlen)
Signature sign(const T &msg)
bool signUpdate(const T &msg)
A class representing private and public keys.
bool isNull(void) const
Check if the object is empty.
Namespace for the asynchronous programming classes.