OpenVPN 3 Core Library
Loading...
Searching...
No Matches
dh.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12// Wrap an OpenSSL DH object
13
14#pragma once
15
16#include <string>
17
18#include <openssl/opensslv.h>
19
24
25#if OPENSSL_VERSION_NUMBER < 0x30000000L
27#else
28
29
30namespace openvpn::OpenSSLPKI {
31
32
33
34class DH
35{
36 public:
37 DH()
38 : dh_(nullptr)
39 {
40 }
41
42 explicit DH(const std::string &dh_txt)
43 : dh_(nullptr)
44 {
45 parse_pem(dh_txt);
46 }
47
48 DH(const DH &other)
49 {
50 dup(other.dh_);
51 }
52
53 DH(DH &&other) noexcept
54 : dh_(other.dh_)
55 {
56 other.dh_ = nullptr;
57 }
58
59 void operator=(const DH &other)
60 {
61 if (this != &other)
62 {
63 erase();
64 dup(other.dh_);
65 }
66 }
67
68 DH &operator=(DH &&other) noexcept
69 {
70 if (this != &other)
71 {
72 erase();
73 dh_ = other.dh_;
74 other.dh_ = nullptr;
75 }
76 return *this;
77 }
78
79 bool defined() const
80 {
81 return dh_ != nullptr;
82 }
83 ::EVP_PKEY *obj() const
84 {
85 return dh_;
86 }
87
93 ::EVP_PKEY *obj_release()
94 {
95 auto dh = dh_;
96 dh_ = nullptr;
97 return dh;
98 }
99
100 void parse_pem(const std::string &dh_txt)
101 {
102 BIO *bio = ::BIO_new_mem_buf(const_cast<char *>(dh_txt.c_str()), numeric_cast<int>(dh_txt.length()));
103 if (!bio)
104 throw OpenSSLException();
105
106 ::EVP_PKEY *dh = ::PEM_read_bio_Parameters_ex(bio, nullptr, nullptr, nullptr);
107 ::BIO_free(bio);
108 if (!dh)
109 throw OpenSSLException("DH::parse_pem");
110
111 erase();
112 dh_ = dh;
113 }
114
115 std::string render_pem() const
116 {
117 if (dh_)
118 {
119 BIO *bio = ::BIO_new(BIO_s_mem());
120 const int ret = ::PEM_write_bio_Parameters(bio, dh_);
121 if (ret == 0)
122 {
123 ::BIO_free(bio);
124 throw OpenSSLException("DH::render_pem");
125 }
126
127 {
128 char *temp;
129 const size_t buf_len = ::BIO_get_mem_data(bio, &temp);
130 std::string ret = std::string(temp, buf_len);
131 ::BIO_free(bio);
132 return ret;
133 }
134 }
135 else
136 return "";
137 }
138
139 ~DH()
140 {
141 erase();
142 }
143
144 private:
145 void erase()
146 {
147 if (dh_)
148 ::EVP_PKEY_free(dh_);
149 }
150
151 void dup(const ::EVP_PKEY *dh)
152 {
153 if (dh)
154 dh_ = EVP_PKEY_dup(const_cast<EVP_PKEY *>(dh));
155 else
156 dh_ = nullptr;
157 }
158
159 ::EVP_PKEY *dh_;
160};
161} // namespace openvpn::OpenSSLPKI
162#endif
void parse_pem(const std::string &dh_txt)
Definition dh-compat.hpp:94
void dup(const ::DH *dh)
void operator=(const DH &other)
Definition dh-compat.hpp:65
std::string render_pem() const
std::string ret