OpenVPN 3 Core Library
Loading...
Searching...
No Matches
x509.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 X509 object
13
14#pragma once
15
16#include <string>
17#include <vector>
18
19#include <openssl/ssl.h>
20#include <openssl/bio.h>
21
26
27namespace openvpn::OpenSSLPKI {
28
29class X509
30{
31 using X509_unique_ptr = std::unique_ptr<::X509, decltype(&::X509_free)>;
32
33 public:
34 X509() = default;
35
36 X509(const std::string &cert_txt, const std::string &title)
37 {
38 parse_pem(cert_txt, title);
39 }
40
41 explicit X509(::X509 *x509, const bool create = true)
42 {
43 if (create)
44 x509_ = {x509, ::X509_free};
45 else
46 x509_ = {dup(x509), ::X509_free};
47 }
48
49 X509(const X509 &other)
50 : x509_{dup(other.x509_.get()), ::X509_free}
51 {
52 }
53
54 X509(X509 &&other) noexcept
55 : x509_(std::move(other.x509_))
56 {
57 }
58
59 X509 &operator=(const X509 &other)
60 {
61 if (this != &other)
62 {
63 x509_ = dup(other.x509_);
64 }
65 return *this;
66 }
67
68 X509 &operator=(X509 &&other) noexcept
69 {
70 if (this != &other)
71 {
72 x509_ = std::move(other.x509_);
73 }
74 return *this;
75 }
76
77 bool defined() const
78 {
79 return static_cast<bool>(x509_);
80 }
81
82 ::X509 *obj() const
83 {
84 return x509_.get();
85 }
86
87 [[nodiscard]] ::X509 *obj_dup() const
88 {
89 return dup(x509_.get());
90 }
91
92 void parse_pem(const std::string &cert_txt, const std::string &title)
93 {
94 BIO *bio = ::BIO_new_mem_buf(const_cast<char *>(cert_txt.c_str()), numeric_cast<int>(cert_txt.length()));
95 if (!bio)
96 throw OpenSSLException();
97
98 ::X509 *cert = ::PEM_read_bio_X509(bio, nullptr, nullptr, nullptr);
99 ::BIO_free(bio);
100 if (!cert)
101 throw OpenSSLException(std::string("X509::parse_pem: error in ") + title + std::string(":"));
102
103 x509_ = {cert, X509_free};
104 }
105
106 [[nodiscard]] std::string render_pem() const
107 {
108 if (x509_)
109 {
110 BIO *bio = ::BIO_new(BIO_s_mem());
111 const int ret = ::PEM_write_bio_X509(bio, x509_.get());
112 if (ret == 0)
113 {
114 ::BIO_free(bio);
115 throw OpenSSLException("X509::render_pem");
116 }
117
118 {
119 char *temp;
120 const auto buf_len = ::BIO_get_mem_data(bio, &temp);
121 std::string ret = std::string(temp, buf_len);
122 ::BIO_free(bio);
123 return ret;
124 }
125 }
126 else
127 return "";
128 }
129
130
131
132 private:
134 {
135 if (x509)
136 {
137 ::X509 *dup = ::X509_dup(const_cast<::X509 *>(x509.get()));
138 return {dup, ::X509_free};
139 }
140 else
141 {
142 return {nullptr, ::X509_free};
143 }
144 }
145 static ::X509 *dup(const ::X509 *x509)
146 {
147 if (x509)
148 return ::X509_dup(const_cast<::X509 *>(x509));
149 else
150 return nullptr;
151 }
152
153 X509_unique_ptr x509_{nullptr, ::X509_free};
154};
155
156class X509List : public std::vector<X509>
157{
158 public:
159 typedef X509 Item;
160
161 bool defined() const
162 {
163 return !empty();
164 }
165
166 std::string render_pem() const
167 {
168 std::string ret;
169 for (const auto &e : *this)
170 ret += e.render_pem();
171 return ret;
172 }
173};
174} // namespace openvpn::OpenSSLPKI
std::string render_pem() const
Definition x509.hpp:166
std::unique_ptr<::X509, decltype(&::X509_free)> X509_unique_ptr
Definition x509.hpp:31
X509(::X509 *x509, const bool create=true)
Definition x509.hpp:41
X509_unique_ptr x509_
Definition x509.hpp:153
X509(const X509 &other)
Definition x509.hpp:49
X509(X509 &&other) noexcept
Definition x509.hpp:54
X509 & operator=(const X509 &other)
Definition x509.hpp:59
::X509 * obj_dup() const
Definition x509.hpp:87
::X509 * obj() const
Definition x509.hpp:82
static X509_unique_ptr dup(const X509_unique_ptr &x509)
Definition x509.hpp:133
X509 & operator=(X509 &&other) noexcept
Definition x509.hpp:68
::X509 * dup(const ::X509 *x509)
Definition x509.hpp:145
void parse_pem(const std::string &cert_txt, const std::string &title)
Definition x509.hpp:92
X509(const std::string &cert_txt, const std::string &title)
Definition x509.hpp:36
bool defined() const
Definition x509.hpp:77
std::string render_pem() const
Definition x509.hpp:106
const std::string cert_txt
std::string ret