MySQL 26.10.0
Source Code Documentation
digest.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2018, 2026, 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 <span>
32#include <stdexcept>
33#include <string>
34#include <string_view>
35#include <vector>
36
37#include <openssl/evp.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 */
62 Digest(Type type) : type_{type}, ctx_{EVP_MD_CTX_new(), &EVP_MD_CTX_free} {
63 reinit();
64 }
65
66 /**
67 * initialize or reinitialize the message digest functions.
68 *
69 * Allows reused of the Digest function without reallocating memory.
70 */
71 void reinit() {
72 EVP_MD_CTX_reset(ctx_.get());
73 EVP_DigestInit(ctx_.get(), Digest::get_evp_md(type_));
74 }
75
76 /**
77 * update Digest.
78 *
79 * @param data data to update digest function with
80 */
81 void update(const std::span<const uint8_t> &data) {
82 EVP_DigestUpdate(ctx_.get(), data.data(), data.size());
83 }
84
85 void update(const std::string_view &data) {
86 EVP_DigestUpdate(ctx_.get(), data.data(), data.length());
87 }
88
89 void update(const char *data, size_t length) {
90 EVP_DigestUpdate(ctx_.get(), data, length);
91 }
92
93 /**
94 * finalize the digest and get digest value.
95 *
96 * @param out vector to place the digest value in
97 */
98 void finalize(std::vector<uint8_t> &out) { finalize_impl(out); }
99
100 /**
101 * finalize the digest and get digest value.
102 *
103 * @param out string to place the digest value in
104 */
105 void finalize(std::string &out) { finalize_impl(out); }
106
107 /**
108 * get size of the digest value.
109 *
110 * @param type type of message digest
111 * @returns size of message digest
112 */
113 static size_t digest_size(Type type) {
114 if (auto *dg = Digest::get_evp_md(type)) {
115 return EVP_MD_size(dg);
116 } else {
117 // compiler should ensure this can't happen
118 throw std::invalid_argument("type wasn't part of Type");
119 }
120 }
121
122 private:
123 template <typename Container>
124 void finalize_impl(Container &out) {
125 // if cap is too large, limit it to uint::max and let narrowing handle the
126 // rest
127 unsigned int out_len{static_cast<unsigned int>(std::min(
128 out.capacity(),
129 static_cast<size_t>(std::numeric_limits<unsigned int>::max())))};
130
131 EVP_DigestFinal_ex(ctx_.get(), reinterpret_cast<uint8_t *>(&out[0]),
132 &out_len);
133 out.resize(out_len);
134 }
135
136 static const EVP_MD *get_evp_md(Type type) noexcept {
137 switch (type) {
138 case Type::Md5:
139 return EVP_md5();
140 case Type::Sha1:
141 return EVP_sha1();
142 case Type::Sha224:
143 return EVP_sha224();
144 case Type::Sha256:
145 return EVP_sha256();
146 case Type::Sha384:
147 return EVP_sha384();
148 case Type::Sha512:
149 return EVP_sha512();
150 }
151
152 return nullptr;
153 }
155 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_free)> ctx_;
156};
157
158#endif
message digest.
Definition: digest.h:53
void update(const char *data, size_t length)
Definition: digest.h:89
void finalize(std::vector< uint8_t > &out)
finalize the digest and get digest value.
Definition: digest.h:98
static size_t digest_size(Type type)
get size of the digest value.
Definition: digest.h:113
Type type_
Definition: digest.h:154
void finalize(std::string &out)
finalize the digest and get digest value.
Definition: digest.h:105
void update(const std::span< const uint8_t > &data)
update Digest.
Definition: digest.h:81
static const EVP_MD * get_evp_md(Type type) noexcept
Definition: digest.h:136
std::unique_ptr< EVP_MD_CTX, decltype(&EVP_MD_CTX_free)> ctx_
Definition: digest.h:155
void finalize_impl(Container &out)
Definition: digest.h:124
Type
Definition: digest.h:55
void reinit()
initialize or reinitialize the message digest functions.
Definition: digest.h:71
void update(const std::string_view &data)
Definition: digest.h:85
Digest(Type type)
constructor.
Definition: digest.h:62
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:76
ValueType max(X &&first)
Definition: gtid.h:103
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:2284
required string type
Definition: replication_group_member_actions.proto:34