OpenVPN 3 Core Library
Loading...
Searching...
No Matches
tls_crypt_v2.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) 2017-2018 OpenVPN Technologies, Inc.
8//
9// This program is free software: you can redistribute it and/or modify
10// it under the terms of the GNU General Public License Version 3
11// as published by the Free Software Foundation.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program in the COPYING file.
20// If not, see <http://www.gnu.org/licenses/>.
21
22// Classes for handling OpenVPN tls-crypt-v2 internals
23
24#ifndef OPENVPN_CRYPTO_TLS_CRYPT_V2_H
25#define OPENVPN_CRYPTO_TLS_CRYPT_V2_H
26
27#include <string>
28
34
35namespace openvpn {
36constexpr static const char *tls_crypt_v2_server_key_name = "OpenVPN tls-crypt-v2 server key";
37constexpr static const char *tls_crypt_v2_client_key_name = "OpenVPN tls-crypt-v2 client key";
38
40{
41 public:
42 OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_server_key_parse_error);
43 OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_server_key_encode_error);
44 OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_server_key_bad_size);
45
47 : key_size(128),
48 key(key_size, BufAllocFlags::DESTRUCT_ZERO)
49 {
50 }
51
52 bool defined() const
53 {
54 return key.defined();
55 }
56
57 void parse(const std::string &key_text)
58 {
59 if (!SSLLib::PEMAPI::pem_decode(key, key_text.c_str(), key_text.length(), tls_crypt_v2_server_key_name))
60 throw tls_crypt_v2_server_key_parse_error();
61
62 if (key.size() != key_size)
63 throw tls_crypt_v2_server_key_bad_size();
64 }
65
67 {
68 std::memcpy(tls_key.raw_alloc(), key.c_data(), key_size);
69 }
70
71 std::string render() const
72 {
73 BufferAllocated data(32 + 2 * key.size(), 0);
74
75 if (!SSLLib::PEMAPI::pem_encode(data, key.c_data(), key.size(), tls_crypt_v2_server_key_name))
76 throw tls_crypt_v2_server_key_encode_error();
77
78 return std::string((const char *)data.c_data());
79 }
80
81 private:
82 const size_t key_size;
84};
85
86
88{
89 public:
90 enum
91 {
92 WKC_MAX_SIZE = 1024, // bytes
93 };
94
95 OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_client_key_parse_error);
96 OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_client_key_encode_error);
97 OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_client_key_bad_size);
98
100
102 : key_size(OpenVPNStaticKey::KEY_SIZE),
103 tag_size(context->digest_size())
104 {
105 }
106
107 bool defined() const
108 {
109 return key.defined() && wkc.defined();
110 }
111
112 void parse(const std::string &key_text)
113 {
115
116 if (!SSLLib::PEMAPI::pem_decode(data, key_text.c_str(), key_text.length(), tls_crypt_v2_client_key_name))
117 throw tls_crypt_v2_client_key_parse_error();
118
119 if (data.size() < (tag_size + key_size))
120 throw tls_crypt_v2_client_key_bad_size();
121
123 wkc.init(data.data() + key_size, data.size() - key_size, BufAllocFlags::DESTRUCT_ZERO);
124 }
125
127 {
128 std::memcpy(tls_key.raw_alloc(), key.c_data(), key_size);
129 }
130
131 std::string render() const
132 {
133 BufferAllocated data(32 + 2 * (key.size() + wkc.size()), 0);
135 in.append(wkc);
136
137 if (!SSLLib::PEMAPI::pem_encode(data, in.c_data(), in.size(), tls_crypt_v2_client_key_name))
138 throw tls_crypt_v2_client_key_encode_error();
139
140 return std::string((const char *)data.c_data());
141 }
142
143 void extract_wkc(BufferAllocated &wkc_out) const
144 {
145 wkc_out = wkc;
146 }
147
148 private:
151
152 const size_t key_size;
153 const size_t tag_size;
154};
155
156// the user can extend the TLSCryptMetadata and the TLSCryptMetadataFactory
157// classes to implement its own metadata verification method.
158//
159// default method is to *ignore* the metadata contained in the WKc sent by the client
160class TLSCryptMetadata : public RC<thread_unsafe_refcount>
161{
162 public:
164
165 // override this method with your own verification mechanism.
166 //
167 // If type is -1 it means that metadata is empty.
168 //
169 virtual bool verify(int type, Buffer &metadata) const
170 {
171 return true;
172 }
173};
174
175// abstract class to be extended when creating other factories
176class TLSCryptMetadataFactory : public RC<thread_unsafe_refcount>
177{
178 public:
180
182};
183
184// factory implementation for the basic verification method
186{
187 public:
189 {
190 return new TLSCryptMetadata();
191 }
192};
193} // namespace openvpn
194
195#endif /* OPENVPN_CRYPTO_TLS_CRYPT_V2_H */
void init(const size_t capacity, const unsigned int flags)
Initializes the buffer with the specified capacity and flags.
Definition buffer.hpp:1707
bool defined() const
Returns true if the buffer is not empty.
Definition buffer.hpp:1207
const T * c_data() const
Returns a const pointer to the start of the buffer.
Definition buffer.hpp:1177
void append(const B &other)
Append data from another buffer to this buffer.
Definition buffer.hpp:1607
const T * c_str() const
Returns a const pointer to the null-terminated string representation of the buffer.
Definition buffer.hpp:1165
size_t size() const
Returns the size of the buffer in T objects.
Definition buffer.hpp:1225
unsigned char * raw_alloc()
Reference count base class for objects tracked by RCPtr. Disallows copying and assignment.
Definition rc.hpp:912
virtual TLSCryptMetadata::Ptr new_obj()=0
RCPtr< TLSCryptMetadataFactory > Ptr
RCPtr< TLSCryptMetadata > Ptr
virtual bool verify(int type, Buffer &metadata) const
void parse(const std::string &key_text)
TLSCryptV2ClientKey(TLSCryptContext::Ptr context)
void extract_wkc(BufferAllocated &wkc_out) const
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_client_key_bad_size)
void extract_key(OpenVPNStaticKey &tls_key)
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_client_key_parse_error)
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_client_key_encode_error)
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_server_key_bad_size)
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_server_key_parse_error)
void extract_key(OpenVPNStaticKey &tls_key)
void parse(const std::string &key_text)
std::string render() const
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_server_key_encode_error)
Support deferred server-side state creation when client connects.
Definition ovpncli.cpp:95
static constexpr const char * tls_crypt_v2_client_key_name
static constexpr const char * tls_crypt_v2_server_key_name
@ DESTRUCT_ZERO
if enabled, destructor will zero data before deletion
Definition buffer.hpp:871
@ GROW
if enabled, buffer will grow (otherwise buffer_full exception will be thrown)
Definition buffer.hpp:872
const char key_text[]