MySQL 8.0.37
Source Code Documentation
digest.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2018, 2024, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is designed to work with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have either included with
14 the program or referenced in the documentation.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24*/
25#ifndef MYSQLROUTER_DIGEST_INCLUDED
26#define MYSQLROUTER_DIGEST_INCLUDED
27
28#include <algorithm>
29#include <limits>
30#include <memory>
31#include <stdexcept>
32#include <string>
33#include <vector>
34
35#include <openssl/evp.h>
36
37#include "openssl_version.h"
38
39/**
40 * message digest.
41 *
42 * Wrapper around Digest functions of openssl (EVP_MD_...)
43 *
44 * - MD5
45 * - SHA1
46 * - SHA224
47 * - SHA256
48 * - SHA384
49 * - SHA512
50 *
51 * @see openssl's EVP_sha512()
52 */
53class Digest {
54 public:
55 enum class Type { Md5, Sha1, Sha224, Sha256, Sha384, Sha512 };
56
57 /**
58 * constructor.
59 *
60 * initializes the digest function.
61 */
63#if defined(OPENSSL_VERSION_NUMBER) && \
64 (OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0))
65 EVP_MD_CTX_new(), &EVP_MD_CTX_free
66#else
67 EVP_MD_CTX_create(), &EVP_MD_CTX_destroy
68#endif
69 }
70 { reinit(); }
71
72 /**
73 * initialize or reinitialize the message digest functions.
74 *
75 * Allows reused of the Digest function without reallocating memory.
76 */
77 void reinit() {
78#if defined(OPENSSL_VERSION_NUMBER) && \
79 (OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0))
80 EVP_MD_CTX_reset(ctx_.get());
81#else
82 EVP_MD_CTX_cleanup(ctx_.get());
83#endif
84 EVP_DigestInit(ctx_.get(), Digest::get_evp_md(type_));
85 }
86
87 /**
88 * update Digest.
89 *
90 * @param data data to update digest function with
91 */
92 void update(const std::string &data) {
93 EVP_DigestUpdate(ctx_.get(), data.data(), data.size());
94 }
95
96 /**
97 * update Digest.
98 *
99 * @param data data to update digest function with
100 */
101 void update(const std::vector<uint8_t> &data) {
102 EVP_DigestUpdate(ctx_.get(), data.data(), data.size());
103 }
104
105 /**
106 * finalize the digest and get digest value.
107 *
108 * @param out vector to place the digest value in
109 */
110 void finalize(std::vector<uint8_t> &out) { finalize_impl(out); }
111
112 /**
113 * finalize the digest and get digest value.
114 *
115 * @param out string to place the digest value in
116 */
117 void finalize(std::string &out) { finalize_impl(out); }
118
119 /**
120 * get size of the digest value.
121 *
122 * @param type type of message digest
123 * @returns size of message digest
124 */
125 static size_t digest_size(Type type) {
126 if (auto *dg = Digest::get_evp_md(type)) {
127 return EVP_MD_size(dg);
128 } else {
129 // compiler should ensure this can't happen
130 throw std::invalid_argument("type wasn't part of Type");
131 }
132 }
133
134 private:
135 template <typename Container>
136 void finalize_impl(Container &out) {
137 // if cap is too large, limit it to uint::max and let narrowing handle the
138 // rest
139 unsigned int out_len{static_cast<unsigned int>(std::min(
140 out.capacity(),
141 static_cast<size_t>(std::numeric_limits<unsigned int>::max())))};
142
143 EVP_DigestFinal_ex(ctx_.get(), reinterpret_cast<uint8_t *>(&out[0]),
144 &out_len);
145 out.resize(out_len);
146 }
147
148 static const EVP_MD *get_evp_md(Type type) noexcept {
149 switch (type) {
150 case Type::Md5:
151 return EVP_md5();
152 case Type::Sha1:
153 return EVP_sha1();
154 case Type::Sha224:
155 return EVP_sha224();
156 case Type::Sha256:
157 return EVP_sha256();
158 case Type::Sha384:
159 return EVP_sha384();
160 case Type::Sha512:
161 return EVP_sha512();
162 }
163
164 return nullptr;
165 }
167 std::unique_ptr<EVP_MD_CTX, decltype(
168#if defined(OPENSSL_VERSION_NUMBER) && \
169 (OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0))
170 &EVP_MD_CTX_free
171#else
172 &EVP_MD_CTX_destroy
173#endif
174 )>
176};
177
178#endif
message digest.
Definition: digest.h:53
void finalize(std::vector< uint8_t > &out)
finalize the digest and get digest value.
Definition: digest.h:110
static size_t digest_size(Type type)
get size of the digest value.
Definition: digest.h:125
Type type_
Definition: digest.h:166
void finalize(std::string &out)
finalize the digest and get digest value.
Definition: digest.h:117
void update(const std::vector< uint8_t > &data)
update Digest.
Definition: digest.h:101
void update(const std::string &data)
update Digest.
Definition: digest.h:92
static const EVP_MD * get_evp_md(Type type) noexcept
Definition: digest.h:148
void finalize_impl(Container &out)
Definition: digest.h:136
Type
Definition: digest.h:55
void reinit()
initialize or reinitialize the message digest functions.
Definition: digest.h:77
std::unique_ptr< EVP_MD_CTX, decltype(&EVP_MD_CTX_destroy)> ctx_
Definition: digest.h:175
Digest(Type type)
constructor.
Definition: digest.h:62
if(!(yy_init))
Definition: lexyy.cc:1144
std::conditional_t< !std::is_array< T >::value, std::unique_ptr< T, detail::Deleter< T > >, std::conditional_t< detail::is_unbounded_array_v< T >, std::unique_ptr< T, detail::Array_deleter< std::remove_extent_t< T > > >, void > > unique_ptr
The following is a common type that is returned by all the ut::make_unique (non-aligned) specializati...
Definition: ut0new.h:2438
#define ROUTER_OPENSSL_VERSION(MAJOR, MINOR, FIX)
build openssl version (pre-releases and stable).
Definition: openssl_version.h:60
required string type
Definition: replication_group_member_actions.proto:34