MySQL 9.1.0
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 <span>
32#include <stdexcept>
33#include <string>
34#include <string_view>
35#include <vector>
36
37#include <openssl/evp.h>
38
39#include "openssl_version.h"
40
41/**
42 * message digest.
43 *
44 * Wrapper around Digest functions of openssl (EVP_MD_...)
45 *
46 * - MD5
47 * - SHA1
48 * - SHA224
49 * - SHA256
50 * - SHA384
51 * - SHA512
52 *
53 * @see openssl's EVP_sha512()
54 */
55class Digest {
56 public:
57 enum class Type { Md5, Sha1, Sha224, Sha256, Sha384, Sha512 };
58
59 /**
60 * constructor.
61 *
62 * initializes the digest function.
63 */
65#if defined(OPENSSL_VERSION_NUMBER) && \
66 (OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0))
67 EVP_MD_CTX_new(), &EVP_MD_CTX_free
68#else
69 EVP_MD_CTX_create(), &EVP_MD_CTX_destroy
70#endif
71 }
72 { reinit(); }
73
74 /**
75 * initialize or reinitialize the message digest functions.
76 *
77 * Allows reused of the Digest function without reallocating memory.
78 */
79 void reinit() {
80#if defined(OPENSSL_VERSION_NUMBER) && \
81 (OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0))
82 EVP_MD_CTX_reset(ctx_.get());
83#else
84 EVP_MD_CTX_cleanup(ctx_.get());
85#endif
86 EVP_DigestInit(ctx_.get(), Digest::get_evp_md(type_));
87 }
88
89 /**
90 * update Digest.
91 *
92 * @param data data to update digest function with
93 */
94 void update(const std::span<const uint8_t> &data) {
95 EVP_DigestUpdate(ctx_.get(), data.data(), data.size());
96 }
97
98 void update(const std::string_view &data) {
99 EVP_DigestUpdate(ctx_.get(), data.data(), data.length());
100 }
101
102 /**
103 * finalize the digest and get digest value.
104 *
105 * @param out vector to place the digest value in
106 */
107 void finalize(std::vector<uint8_t> &out) { finalize_impl(out); }
108
109 /**
110 * finalize the digest and get digest value.
111 *
112 * @param out string to place the digest value in
113 */
114 void finalize(std::string &out) { finalize_impl(out); }
115
116 /**
117 * get size of the digest value.
118 *
119 * @param type type of message digest
120 * @returns size of message digest
121 */
122 static size_t digest_size(Type type) {
123 if (auto *dg = Digest::get_evp_md(type)) {
124 return EVP_MD_size(dg);
125 } else {
126 // compiler should ensure this can't happen
127 throw std::invalid_argument("type wasn't part of Type");
128 }
129 }
130
131 private:
132 template <typename Container>
133 void finalize_impl(Container &out) {
134 // if cap is too large, limit it to uint::max and let narrowing handle the
135 // rest
136 unsigned int out_len{static_cast<unsigned int>(std::min(
137 out.capacity(),
138 static_cast<size_t>(std::numeric_limits<unsigned int>::max())))};
139
140 EVP_DigestFinal_ex(ctx_.get(), reinterpret_cast<uint8_t *>(&out[0]),
141 &out_len);
142 out.resize(out_len);
143 }
144
145 static const EVP_MD *get_evp_md(Type type) noexcept {
146 switch (type) {
147 case Type::Md5:
148 return EVP_md5();
149 case Type::Sha1:
150 return EVP_sha1();
151 case Type::Sha224:
152 return EVP_sha224();
153 case Type::Sha256:
154 return EVP_sha256();
155 case Type::Sha384:
156 return EVP_sha384();
157 case Type::Sha512:
158 return EVP_sha512();
159 }
160
161 return nullptr;
162 }
164 std::unique_ptr<EVP_MD_CTX, decltype(
165#if defined(OPENSSL_VERSION_NUMBER) && \
166 (OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0))
167 &EVP_MD_CTX_free
168#else
169 &EVP_MD_CTX_destroy
170#endif
171 )>
173};
174
175#endif
message digest.
Definition: digest.h:55
void finalize(std::vector< uint8_t > &out)
finalize the digest and get digest value.
Definition: digest.h:107
static size_t digest_size(Type type)
get size of the digest value.
Definition: digest.h:122
Type type_
Definition: digest.h:163
void finalize(std::string &out)
finalize the digest and get digest value.
Definition: digest.h:114
void update(const std::span< const uint8_t > &data)
update Digest.
Definition: digest.h:94
static const EVP_MD * get_evp_md(Type type) noexcept
Definition: digest.h:145
void finalize_impl(Container &out)
Definition: digest.h:133
Type
Definition: digest.h:57
void reinit()
initialize or reinitialize the message digest functions.
Definition: digest.h:79
std::unique_ptr< EVP_MD_CTX, decltype(&EVP_MD_CTX_destroy)> ctx_
Definition: digest.h:172
void update(const std::string_view &data)
Definition: digest.h:98
Digest(Type type)
constructor.
Definition: digest.h:64
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:2440
#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