]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/sha.hh
rec: allow exception to proxy protocal usage for specific listen addresses
[thirdparty/pdns.git] / pdns / sha.hh
CommitLineData
12471842
PL
1/*
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
e8c59f2d 22#pragma once
e21df721 23
ec47cf6f
FM
24#include "config.h"
25#include <array>
26#include <memory>
27#include <stdexcept>
8b474616 28#include <string>
dd133337 29#include <openssl/sha.h>
e21df721 30#include <openssl/evp.h>
8b474616 31
ec47cf6f
FM
32namespace pdns
33{
34inline std::string sha1sum(const std::string& input)
8b474616 35{
ec47cf6f
FM
36 std::array<unsigned char, 20> result{};
37 // NOLINTNEXTLINE(*-cast): Using OpenSSL C APIs.
38 SHA1(reinterpret_cast<const unsigned char*>(input.c_str()), input.length(), result.data());
39 return {result.begin(), result.end()};
dd133337 40}
8b474616 41
ec47cf6f 42inline std::string sha256sum(const std::string& input)
8b474616 43{
ec47cf6f
FM
44 std::array<unsigned char, 32> result{};
45 // NOLINTNEXTLINE(*-cast): Using OpenSSL C APIs.
46 SHA256(reinterpret_cast<const unsigned char*>(input.c_str()), input.length(), result.data());
47 return {result.begin(), result.end()};
dd133337 48}
8b474616 49
ec47cf6f 50inline std::string sha384sum(const std::string& input)
8b474616 51{
ec47cf6f
FM
52 std::array<unsigned char, 48> result{};
53 // NOLINTNEXTLINE(*-cast): Using OpenSSL C APIs.
54 SHA384(reinterpret_cast<const unsigned char*>(input.c_str()), input.length(), result.data());
55 return {result.begin(), result.end()};
dd133337 56}
8b474616 57
ec47cf6f 58inline std::string sha512sum(const std::string& input)
8b474616 59{
ec47cf6f
FM
60 std::array<unsigned char, 64> result{};
61 // NOLINTNEXTLINE(*-cast): Using OpenSSL C APIs.
62 SHA512(reinterpret_cast<const unsigned char*>(input.c_str()), input.length(), result.data());
63 return {result.begin(), result.end()};
dd133337 64}
e21df721 65
2eaaa7c1
O
66class SHADigest
67{
68public:
ddeea7a6
KM
69 SHADigest() :
70 SHADigest(256) {}
4f8ef7a2 71 SHADigest(unsigned int bits) :
74848abf 72#if defined(HAVE_EVP_MD_CTX_NEW) && defined(HAVE_EVP_MD_CTX_FREE)
32a499f8 73 mdctx(std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_free)>(EVP_MD_CTX_new(), EVP_MD_CTX_free))
d9c81911 74#else
74848abf
OM
75 mdctx(std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_destroy)>(EVP_MD_CTX_create(), EVP_MD_CTX_destroy))
76#endif
e21df721 77 {
2eaaa7c1 78 if (mdctx == nullptr) {
01498d87 79 throw std::runtime_error("SHADigest: EVP_MD_CTX_new failed");
2eaaa7c1
O
80 }
81 switch (bits) {
82 case 256:
83 md = EVP_sha256();
84 break;
85 case 384:
86 md = EVP_sha384();
87 break;
88 case 512:
89 md = EVP_sha512();
90 break;
91 default:
a2a7b1db 92 throw std::invalid_argument("SHADigest: unsupported size");
e21df721 93 }
ec47cf6f 94 if (EVP_DigestInit_ex(mdctx.get(), md, nullptr) == 0) {
2eaaa7c1
O
95 throw std::runtime_error("SHADigest: init error");
96 }
97 }
e21df721 98
abb11ca4
RP
99 // No free of md needed and mdctx is cleaned up by unique_ptr
100 ~SHADigest() = default;
e21df721 101
01498d87 102 void process(const std::string& msg)
2eaaa7c1 103 {
4f8ef7a2 104 if (EVP_DigestUpdate(mdctx.get(), msg.data(), msg.size()) == 0) {
2eaaa7c1 105 throw std::runtime_error("SHADigest: update error");
e21df721 106 }
2eaaa7c1 107 }
e21df721 108
2eaaa7c1
O
109 std::string digest()
110 {
111 std::string md_value;
112 md_value.resize(EVP_MD_size(md));
ec47cf6f 113 unsigned int md_len = 0;
4f8ef7a2 114 if (EVP_DigestFinal_ex(mdctx.get(), reinterpret_cast<unsigned char*>(md_value.data()), &md_len) == 0) {
2eaaa7c1 115 throw std::runtime_error("SHADigest: finalize error");
e21df721 116 }
2eaaa7c1 117 if (md_len != md_value.size()) {
01498d87 118 throw std::runtime_error("SHADigest: inconsistent size");
2eaaa7c1
O
119 }
120 return md_value;
121 }
122
123private:
74848abf 124#if defined(HAVE_EVP_MD_CTX_NEW) && defined(HAVE_EVP_MD_CTX_FREE)
32a499f8 125 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_free)> mdctx;
74848abf
OM
126#else
127 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_destroy)> mdctx;
128#endif
2eaaa7c1
O
129 const EVP_MD* md;
130};
e21df721 131}