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