OpenVPN 3 Core Library
Loading...
Searching...
No Matches
x509track.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#ifndef OPENVPN_PKI_X509TRACK_H
13#define OPENVPN_PKI_X509TRACK_H
14
15#include <string>
16#include <vector>
17
23
25
41
42static const char *const names[] = {
43 // CONST GLOBAL
44 "SERIAL",
45 "SERIAL_HEX",
46 "SHA1",
47 "CN",
48 "C",
49 "L",
50 "ST",
51 "O",
52 "OU",
53 "emailAddress",
54};
55
56OPENVPN_EXCEPTION(x509_track_error);
57
58inline const char *name(const Type type)
59{
60 static_assert(N_TYPES == array_size(names), "x509 names array inconsistency");
61 if (type >= 0 && type < N_TYPES)
62 return names[type];
63 return "UNDEF";
64}
65
66inline Type parse_type(const std::string &name)
67{
68 for (size_t i = 0; i < N_TYPES; ++i)
69 if (name == names[i])
70 return Type(i);
71 return UNDEF;
72}
73
74struct Config
75{
76 Config(const Type type_arg, const bool full_chain_arg)
77 : type(type_arg),
78 full_chain(full_chain_arg)
79 {
80 }
81
82 Config(const std::string &spec)
83 {
84 full_chain = (!spec.empty() && spec[0] == '+');
85 type = parse_type(spec.substr(full_chain ? 1 : 0));
86 if (type == UNDEF)
87 throw Exception("cannot parse attribute '" + spec + "'");
88 }
89
90 std::string to_string() const
91 {
92 std::string ret;
93 if (full_chain)
94 ret += '+';
95 ret += name(type);
96 return ret;
97 }
98
99 bool depth_match(const int depth) const
100 {
101 return !depth || full_chain;
102 }
103
106};
107
108struct ConfigSet : public std::vector<Config>
109{
110 ConfigSet() = default;
111
113 const bool include_serial,
114 const bool include_serial_hex)
115 {
116 const auto *xt = opt.get_index_ptr("x509-track");
117 if (xt)
118 {
119 for (const auto &i : *xt)
120 {
121 try
122 {
123 const Option &o = opt[i];
124 o.touch();
125 emplace_back(o.get(1, 64));
126 }
127 catch (const std::exception &e)
128 {
129 throw x509_track_error(e.what());
130 }
131 }
132 }
133
134 if (include_serial && !exists(SERIAL))
135 emplace_back(SERIAL, true);
136 if (include_serial_hex && !exists(SERIAL_HEX))
137 emplace_back(SERIAL_HEX, true);
138 }
139
140 bool exists(const Type t) const
141 {
142 for (auto &c : *this)
143 if (c.type == t)
144 return true;
145 return false;
146 }
147
148 std::string to_string() const
149 {
150 std::string ret;
151 for (auto &c : *this)
152 {
153 ret += c.to_string();
154 ret += '\n';
155 }
156 return ret;
157 }
158};
159
161{
162 KeyValue(const Type type_arg,
163 const int depth_arg,
164 std::string value_arg)
165 : type(type_arg),
166 depth(depth_arg),
167 value(std::move(value_arg))
168 {
169 }
170
171 std::string to_string(const bool omi_form) const
172 {
173 std::string ret;
174 ret.reserve(128);
175 if (omi_form)
176 ret += ">CLIENT:ENV,";
177 ret += key_name();
178 ret += '=';
180 return ret;
181 }
182
183 std::string key_name() const
184 {
185 switch (type)
186 {
187 case SERIAL:
188 return "tls_serial_" + openvpn::to_string(depth);
189 case SERIAL_HEX:
190 return "tls_serial_hex_" + openvpn::to_string(depth);
191 default:
192 return "X509_" + openvpn::to_string(depth) + '_' + name(type);
193 }
194 }
195
197 int depth = 0;
198 std::string value;
199};
200
201struct Set : public std::vector<KeyValue>
202{
203 std::string to_string(const bool omi_form) const
204 {
205 std::string ret;
206 ret.reserve(512);
207 for (auto &kv : *this)
208 {
209 ret += kv.to_string(omi_form);
210 if (omi_form)
211 ret += '\r';
212 ret += '\n';
213 }
214 return ret;
215 }
216};
217
218} // namespace openvpn::X509Track
219
220#endif
const IndexList * get_index_ptr(const std::string &name) const
Definition options.hpp:1260
void touch(bool lightly=false) const
Definition options.hpp:378
const std::string & get(const size_t index, const size_t max_len) const
Definition options.hpp:184
#define OPENVPN_EXCEPTION(C)
Definition exception.hpp:99
static const char *const names[]
Definition x509track.hpp:42
const char * name(const Type type)
Definition x509track.hpp:58
Type parse_type(const std::string &name)
Definition x509track.hpp:66
std::string reduce_spaces(const std::string &str, const char rep)
Definition string.hpp:333
constexpr std::size_t array_size(T(&)[N])
Definition arraysize.hpp:19
std::string to_string(const T &t)
Convert a value to a string.
Definition to_string.hpp:45
std::string to_string() const
bool exists(const Type t) const
ConfigSet(const OptionList &opt, const bool include_serial, const bool include_serial_hex)
bool depth_match(const int depth) const
Definition x509track.hpp:99
Config(const Type type_arg, const bool full_chain_arg)
Definition x509track.hpp:76
std::string to_string() const
Definition x509track.hpp:90
Config(const std::string &spec)
Definition x509track.hpp:82
std::string key_name() const
std::string to_string(const bool omi_form) const
KeyValue(const Type type_arg, const int depth_arg, std::string value_arg)
std::string to_string(const bool omi_form) const
std::string ret