OpenVPN 3 Core Library
Loading...
Searching...
No Matches
dh-compat.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/ssl.h>
19#include <openssl/bio.h>
20#include <openssl/dh.h>
21
25
26namespace openvpn::OpenSSLPKI {
27
28namespace DH_private {
29// defined outside of DH class to avoid symbol collision in way
30// that DHparams_dup macro is defined
31inline ::DH *dup(const ::DH *dh)
32{
33 if (dh)
34 return DHparams_dup(const_cast<::DH *>(dh));
35 else
36 return nullptr;
37}
38} // namespace DH_private
39
40class DH
41{
42 public:
44 : dh_(nullptr)
45 {
46 }
47
48 explicit DH(const std::string &dh_txt)
49 : dh_(nullptr)
50 {
51 parse_pem(dh_txt);
52 }
53
54 DH(const DH &other)
55 {
56 dup(other.dh_);
57 }
58
59 DH(DH &&other) noexcept
60 : dh_(other.dh_)
61 {
62 other.dh_ = nullptr;
63 }
64
65 void operator=(const DH &other)
66 {
67 if (this != &other)
68 {
69 erase();
70 dup(other.dh_);
71 }
72 }
73
74 DH &operator=(DH &&other) noexcept
75 {
76 if (this != &other)
77 {
78 erase();
79 dh_ = other.dh_;
80 other.dh_ = nullptr;
81 }
82 return *this;
83 }
84
85 bool defined() const
86 {
87 return dh_ != nullptr;
88 }
89 ::DH *obj() const
90 {
91 return dh_;
92 }
93
94 void parse_pem(const std::string &dh_txt)
95 {
96 BIO *bio = ::BIO_new_mem_buf(const_cast<char *>(dh_txt.c_str()), dh_txt.length());
97 if (!bio)
98 throw OpenSSLException();
99
100 ::DH *dh = ::PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr);
101 ::BIO_free(bio);
102 if (!dh)
103 throw OpenSSLException("DH::parse_pem");
104
105 erase();
106 dh_ = dh;
107 }
108
109 std::string render_pem() const
110 {
111 if (dh_)
112 {
113 BIO *bio = ::BIO_new(BIO_s_mem());
114 const int ret = ::PEM_write_bio_DHparams(bio, dh_);
115 if (ret == 0)
116 {
117 ::BIO_free(bio);
118 throw OpenSSLException("DH::render_pem");
119 }
120
121 {
122 char *temp;
123 const int buf_len = ::BIO_get_mem_data(bio, &temp);
124 std::string ret = std::string(temp, buf_len);
125 ::BIO_free(bio);
126 return ret;
127 }
128 }
129 else
130 return "";
131 }
132
134 {
135 erase();
136 }
137
138 private:
139 void erase()
140 {
141 if (dh_)
142 ::DH_free(dh_);
143 }
144
145 void dup(const ::DH *dh)
146 {
147 dh_ = DH_private::dup(dh);
148 }
149
151};
152} // namespace openvpn::OpenSSLPKI
DH(const DH &other)
Definition dh-compat.hpp:54
DH(const std::string &dh_txt)
Definition dh-compat.hpp:48
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
DH & operator=(DH &&other) noexcept
Definition dh-compat.hpp:74
DH(DH &&other) noexcept
Definition dh-compat.hpp:59
inline ::DH * dup(const ::DH *dh)
Definition dh-compat.hpp:31
std::string ret