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
26// workaround for bug in DHparams_dup macro on OpenSSL 0.9.8 and lower
27#if SSLEAY_VERSION_NUMBER <= 0x00908000L
28#undef CHECKED_PTR_OF
29#define CHECKED_PTR_OF(type, p) ((char *)(1 ? p : (type *)0))
30#endif
31
32namespace openvpn::OpenSSLPKI {
33
34namespace DH_private {
35// defined outside of DH class to avoid symbol collision in way
36// that DHparams_dup macro is defined
37inline ::DH *dup(const ::DH *dh)
38{
39 if (dh)
40 return DHparams_dup(const_cast<::DH *>(dh));
41 else
42 return nullptr;
43}
44} // namespace DH_private
45
46class DH
47{
48 public:
50 : dh_(nullptr)
51 {
52 }
53
54 explicit DH(const std::string &dh_txt)
55 : dh_(nullptr)
56 {
57 parse_pem(dh_txt);
58 }
59
60 DH(const DH &other)
61 {
62 dup(other.dh_);
63 }
64
65 DH(DH &&other) noexcept
66 : dh_(other.dh_)
67 {
68 other.dh_ = nullptr;
69 }
70
71 void operator=(const DH &other)
72 {
73 if (this != &other)
74 {
75 erase();
76 dup(other.dh_);
77 }
78 }
79
80 DH &operator=(DH &&other) noexcept
81 {
82 if (this != &other)
83 {
84 erase();
85 dh_ = other.dh_;
86 other.dh_ = nullptr;
87 }
88 return *this;
89 }
90
91 bool defined() const
92 {
93 return dh_ != nullptr;
94 }
95 ::DH *obj() const
96 {
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()), dh_txt.length());
103 if (!bio)
104 throw OpenSSLException();
105
106 ::DH *dh = ::PEM_read_bio_DHparams(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_DHparams(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 int 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
140 {
141 erase();
142 }
143
144 private:
145 void erase()
146 {
147 if (dh_)
148 ::DH_free(dh_);
149 }
150
151 void dup(const ::DH *dh)
152 {
153 dh_ = DH_private::dup(dh);
154 }
155
157};
158} // namespace openvpn::OpenSSLPKI
DH(const DH &other)
Definition dh-compat.hpp:60
DH(const std::string &dh_txt)
Definition dh-compat.hpp:54
void parse_pem(const std::string &dh_txt)
void dup(const ::DH *dh)
void operator=(const DH &other)
Definition dh-compat.hpp:71
std::string render_pem() const
DH & operator=(DH &&other) noexcept
Definition dh-compat.hpp:80
DH(DH &&other) noexcept
Definition dh-compat.hpp:65
inline ::DH * dup(const ::DH *dh)
Definition dh-compat.hpp:37
std::string ret