OpenVPN 3 Core Library
Loading...
Searching...
No Matches
psid_cookie_impl.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) 2022- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12// A 64-bit protocol session ID, used by ProtoContext. But, unlike being random
13// in psid.hpp, the PsidCookieImpl class derives it via an HMAC of information
14// on the incoming client's OpenVPN HARD_RESET control message. This creates a
15// session id that acts like a syn-cookie on the OpenVPN startup 3-way
16// handshake.
17
18#pragma once
19
21
23#include <openvpn/common/rc.hpp>
26
27#include <openvpn/ssl/psid.hpp>
30
31namespace openvpn {
32
44{
45 public:
46 static constexpr int SID_SIZE = ProtoSessionID::SIZE;
47 static constexpr int OPCODE_SIZE = 1;
48
49 // must be called _before_ the server implementation starts threads; it guarantees
50 // that all per thread instances get the same psid cookie hmac key
51 static void pre_threading_setup()
52 {
53 get_key();
54 }
55
57 : pcfg_(*psfp->proto_context_config),
58 now_(pcfg_.now), handwindow_(pcfg_.handshake_window)
59 {
61 {
64
65 // init tls_auth hmac (see ProtoContext.reset() case TLS_AUTH; also TLSAuthPreValidate ctor)
66 if (pcfg_.key_direction >= 0)
67 {
68 // key-direction is 0 or 1
71 | OpenVPNStaticKey::ENCRYPT | key_dir));
73 | OpenVPNStaticKey::DECRYPT | key_dir));
74 }
75 else
76 {
77 // key-direction bidirectional mode
80 }
81 }
82
83 // initialize psid HMAC context with digest type and key
84 const StaticKey &key = get_key();
85 hmac_ctx_.init(digest_, key.data(), key.size());
86 }
87
88 Intercept intercept(Buffer &pkt_buf, const PsidCookieAddrInfoBase &pcaib) override
89 {
92
93 if (pkt_buf.empty())
94 return Intercept::EARLY_DROP; // packet validation fails, no opcode
95
96 CookieHelper chelp(pkt_buf[0]);
97
98 const bool is_tls_crypt_v2 = (chelp.is_tls_crypt_v2() && pcfg_.tls_crypt_v2_enabled());
99
100 if (chelp.is_clients_initial_reset())
101 {
102 return is_tls_crypt_v2
103 ? process_clients_initial_reset_tls_crypt(pkt_buf, pcaib, chelp)
105 }
106 if (is_tls_crypt_v2 && chelp.is_clients_handshake_ack_tls_crypt_v2())
107 {
108 return process_clients_server_reset_ack_tls_crypt(pkt_buf, pcaib);
109 }
111 {
112 return process_clients_server_reset_ack_tls_auth(pkt_buf, pcaib, chelp.is_ack_v1());
113 }
114
115 // JMD_TODO: log failure? Logging DDoS?
116 return Intercept::EARLY_DROP; // bad op field
117 }
118
120 {
123 return ret_val;
124 }
125
127 {
128 pctb_ = std::move(pctb);
129 }
130
131#ifndef UNIT_TEST
132 private:
133#endif
135
136 // Returns true iff the reliable::id_t read from `buf` is within the early-handshake
137 // range (0 or 1); false for mid-session values (> 1).
138 template <typename Buf>
139 static bool read_id_is_early_handshake(Buf &buf)
140 {
141 reliable::id_t net_id;
142 buf.read(&net_id, sizeof(net_id));
143 return ntohl(net_id) <= 1;
144 }
145
146 // Validates the payload of the third 3WHS packet (client ACK of server HARD_RESET).
147 // The "0 or 1" tolerance on pktids matches OpenVPN 2's check_session_hmac_and_pkt_id():
148 // anything higher is clearly mid-session traffic, not a 3WHS completion.
149 // When has_own_pktid is false (P_ACK_V1 wire format), the own message-id field is
150 // absent on the wire and the check is skipped.
151 // Sets cookie_psid_ and returns true on success.
152 template <typename Buf>
154 const ProtoSessionID &cli_psid,
155 const PsidCookieAddrInfoBase &pcaib,
156 bool has_own_pktid = true)
157 {
158 // We _should_ have one ACK (for the HARD_RESET previous message).
159 if (buf[0] != 1)
160 return false;
161
162 buf.advance(1);
163
165 return false;
166
167 cookie_psid_.read(buf);
168
169 if (has_own_pktid && !read_id_is_early_handshake(buf))
170 return false;
171
172 return check_session_id_hmac(cookie_psid_, cli_psid, pcaib);
173 }
174
176 {
177 static const size_t hmac_size = ta_hmac_recv_->output_size();
178
179 // ovpn_hmac_cmp checks for adequate pkt_buf.size()
180 bool pkt_hmac_valid = ta_hmac_recv_->ovpn_hmac_cmp(pkt_buf.c_data(),
181 pkt_buf.size(),
183 hmac_size,
185 if (!pkt_hmac_valid)
186 {
187 // JMD_TODO: log failure? Logging DDoS?
188 return Intercept::DROP_1ST;
189 }
190
191 // check for adequate packet size to complete this function
192 static const size_t reqd_packet_size
193 // clang-format off
194 // [op_field] [cli_psid] [HMAC] [cli_auth_pktid] [cli_pktid]
196 // clang-format on
197 if (pkt_buf.size() < reqd_packet_size)
198 {
199 // JMD_TODO: log failure? Logging DDoS?
200 return Intercept::DROP_1ST;
201 }
202
203 // "buf_copy" here uses the same underlying data, but has it's own offset; skip
204 // past client's op_field.
205 ConstBuffer recv_buf_copy(pkt_buf.c_data() + 1, pkt_buf.size() - 1, true);
206 // decapsulate_tls_auth
207 const ProtoSessionID cli_psid(recv_buf_copy);
208 recv_buf_copy.advance(hmac_size);
209
210 PacketIDControl cli_auth_pktid; // a.k.a, replay_packet_id in draft RFC
211 cli_auth_pktid.read(recv_buf_copy);
212
213 uint8_t cli_net_id[4]; // a.k.a., packet_id in draft RFC
214
215 recv_buf_copy.read(cli_net_id, sizeof(cli_net_id));
216
217 // start building the server reply HARD_RESET packet
218 BufferAllocated send_buf;
219 static const Frame &frame = *pcfg_.frame;
220 frame.prepare(Frame::WRITE_SSL_INIT, send_buf);
221
222 // set server packet id (a.k.a., msg seq no) which would come from the
223 // reliability layer, if we had one
224 const reliable::id_t net_id = 0; // no htonl(0) since result is 0
225 send_buf.prepend(static_cast<const void *>(&net_id), sizeof(net_id));
226
227 // prepend_dest_psid_and_acks
228 cli_psid.prepend(send_buf);
229 send_buf.prepend(cli_net_id, sizeof(cli_net_id));
230 send_buf.push_front((unsigned char)1);
231
232 // gen head
233 PacketIDControlSend svr_auth_pid{};
234 svr_auth_pid.write_next(send_buf, true, now_->seconds_since_epoch());
235 // make space for tls-auth HMAC
237 // write source PSID
238 const ProtoSessionID srv_psid = calculate_session_id_hmac(cli_psid, pcaib, 0);
239 srv_psid.prepend(send_buf);
240 // write opcode
241 const unsigned char op_field = CookieHelper::get_server_hard_reset_opfield();
242 send_buf.push_front(op_field);
243 // write hmac
244 ta_hmac_send_->ovpn_hmac_gen(send_buf.data(),
245 send_buf.size(),
249
250 // consumer's implementation to send the SERVER_HARD_RESET to the client
251 bool send_ok = pctb_->psid_cookie_send_const(send_buf, pcaib);
252 if (send_ok)
253 {
255 }
256
257 return Intercept::DROP_1ST;
258 }
259
261 const PsidCookieAddrInfoBase &pcaib,
262 bool is_ack_v1)
263 {
264 static const size_t hmac_size = ta_hmac_recv_->output_size();
265 // ovpn_hmac_cmp checks for adequate pkt_buf.size()
266 bool pkt_hmac_valid = ta_hmac_recv_->ovpn_hmac_cmp(pkt_buf.c_data(),
267 pkt_buf.size(),
269 hmac_size,
271 if (!pkt_hmac_valid)
272 {
273 // JMD_TODO: log failure? Logging DDoS?
274 return Intercept::DROP_2ND;
275 }
276
277 // [op_field][cli_psid][HMAC][cli_auth_pktid][acked][srv_psid] and,
278 // for CONTROL_V1 only, a trailing [own_pktid]. P_ACK_V1 has no own
279 // message-id on the wire, so its required size is shorter.
280 const size_t reqd_packet_size = OPCODE_SIZE + SID_SIZE + hmac_size + PacketIDControl::size() + 5 + SID_SIZE
281 + (is_ack_v1 ? 0 : reliable::id_size);
282 if (pkt_buf.size() < reqd_packet_size)
283 {
284 // JMD_TODO: log failure? Logging DDoS?
285 return Intercept::DROP_2ND;
286 }
287
288 // "buf_copy" here uses the same underlying data, but has it's own offset; skip
289 // past client's op_field.
290 ConstBuffer recv_buf_copy(pkt_buf.c_data() + 1, pkt_buf.size() - 1, true);
291 // decapsulate_tls_auth
292 const ProtoSessionID cli_psid(recv_buf_copy);
293 recv_buf_copy.advance(hmac_size);
294
295 PacketIDControl cli_auth_pktid; // a.k.a, replay_packet_id in draft RFC
296 cli_auth_pktid.read(recv_buf_copy);
297
298 return validate_3whs_ack_payload(recv_buf_copy, cli_psid, pcaib, !is_ack_v1)
301 }
302
304 const PsidCookieAddrInfoBase &pcaib,
305 const CookieHelper &ch)
306 {
307 static const size_t hmac_size = pcfg_.tls_crypt_context->digest_size();
308
309 // Check the size before reading any of it. intercept() turns away only an empty
310 // datagram, and unlike the tls-auth path there is no hmac comparison ahead of this to
311 // vet the length on the way past -- the WKc is what authenticates a packet here, and
312 // that is not looked at until below.
313 static const size_t reqd_packet_size = TLSCryptContext::hmac_offset;
314 if (pkt_buf.size() < reqd_packet_size)
315 {
316 return Intercept::DROP_1ST;
317 }
318
319 ConstBuffer recv_buf_copy(pkt_buf.c_data() + 1, pkt_buf.size() - 1, true);
320
321 ProtoSessionID client_session_id(recv_buf_copy);
322 PacketIDControl replay_packet_id;
323 replay_packet_id.read(recv_buf_copy);
324
325 // This could be user-configurable so that we could just drop packets here if
326 // we don't want to allow clients that don't support re-sending the WKc.
327 if (!ch.supports_early_negotiation(replay_packet_id))
329
330 // A shallow view, for the same reason the third packet's path takes one: the unwrap
331 // trims the WKc off the buffer it is handed, and this one is the caller's.
332 Buffer work_buf(pkt_buf);
334
335 if (!send)
336 return Intercept::DROP_1ST;
337
338 // Create synthetic RESET packet payload.
339 BufferAllocated payload;
341
343
344 PacketIDControl packet_id{.id = 0, .time = 0};
345 packet_id.write(payload, true);
346
347 client_session_id.prepend(payload);
348
349 const reliable::id_t acked_packet_id = 0;
350 payload.prepend(&acked_packet_id, sizeof(acked_packet_id));
351 payload.push_front((unsigned char)1);
352
354 // in 'work' we store all the fields that are not supposed to be encrypted
356 // make space for HMAC
357 work.prepend_alloc(hmac_size);
358 // write tls-crypt packet ID
359 PacketIDControlSend svr_auth_pid;
360 svr_auth_pid.write_next(work, true, now_->seconds_since_epoch());
361 // write source PSID
362 const ProtoSessionID srv_psid = calculate_session_id_hmac(client_session_id, pcaib, 0);
363 srv_psid.prepend(work);
364 // write opcode
366
367 // compute HMAC using header fields (from 'work') and plaintext
368 // payload
369 send->hmac_gen(work.data(), TLSCryptContext::hmac_offset, payload.c_data(), payload.size());
370
371 const size_t data_offset = TLSCryptContext::hmac_offset + hmac_size;
372
373 // encrypt the content of 'payload' (packet payload) into 'work'
374 const size_t encrypt_bytes = send->encrypt(work.c_data() + TLSCryptContext::hmac_offset,
375 work.data() + data_offset,
376 work.max_size() - data_offset,
377 payload.c_data(),
378 payload.size());
379 work.inc_size(encrypt_bytes);
380
381 // consumer's implementation to send the SERVER_HARD_RESET to the client
382 bool send_ok = pctb_->psid_cookie_send_const(work, pcaib);
383 if (send_ok)
385
386 return Intercept::DROP_1ST;
387 }
388
390 {
391 // The unwrap below works on a shallow view over the same bytes, trimming the WKc
392 // off it to leave the tls-crypt frame the auth tag covers -- the size everything
393 // else here has to work on. pkt_buf keeps the packet as it arrived, so that the
394 // session created for this client finds the WKc where it expects it and keys
395 // itself.
396 Buffer work_buf(pkt_buf);
397
399
400 if (!recv)
401 return Intercept::DROP_2ND;
402
403 static const size_t hmac_size = pcfg_.tls_crypt_context->digest_size();
404
405 const size_t head_size = TLSCryptContext::hmac_offset;
406 const unsigned char *orig_data = work_buf.c_data();
407
408 ConstBuffer recv_buf_copy(work_buf.c_data() + 1, work_buf.size() - 1, true);
409
410 ProtoSessionID client_session_id(recv_buf_copy);
411 recv_buf_copy.advance(PacketIDControl::size() + hmac_size);
412
415
416 // Decrypt into `work`.
417 const size_t decrypt_bytes = recv->decrypt(orig_data + head_size,
418 work.data(),
419 work.max_size(),
420 recv_buf_copy.c_data(),
421 recv_buf_copy.size());
422 if (!decrypt_bytes)
423 return Intercept::DROP_2ND;
424
425 work.inc_size(decrypt_bytes);
426
427 // Verify HMAC.
428 if (!recv->hmac_cmp(orig_data, TLSCryptContext::hmac_offset, work.c_data(), work.size()))
429 return Intercept::DROP_2ND;
430
431 // Decrypted plaintext layout: ack_count(1) | acked_pktid(4) | peer_session_id(8) | packet_id(4) | payload
432 static const size_t reqd_decrypted_size = 1 + reliable::id_size + ProtoSessionID::SIZE + reliable::id_size;
433 if (work.size() < reqd_decrypted_size)
434 return Intercept::DROP_2ND;
435
436 // The WKc's metadata is judged by the session, not here: it can count the answer
437 // against the session it concerns, and a replayed packet meets its replay window.
438 return validate_3whs_ack_payload(work, client_session_id, pcaib)
441 }
442
443 // key must be common to all threads
445 {
446 StrongRandomAPI::Ptr rng(new SSLLib::RandomAPI());
448
449 // guarantee that the key is large enough
450 StaticKey key;
451 key.init_from_rng(*rng, alg.size());
452 return key;
453 }
454
455 static const StaticKey &get_key()
456 {
457 static const StaticKey key = create_key();
458 return key;
459 }
460
470 const PsidCookieAddrInfoBase &pcaib,
471 unsigned int offset)
472 {
474
475 // Get the time window for which the ProtoSessionID hmac is valid. The window
476 // size is an interval given by handwindow/2, one half of the configured
477 // handshake timeout, typically 30 seconds. The valid_time is the count of
478 // intervals since the beginning of the epoch. With offset zero, the valid_time
479 // is the server's current interval; with offsets 1 to n, it is the server's nth
480 // previous interval.
481 //
482 // There is the theoretical issue of valid_time wrapping after 2^32 intervals.
483 // With 30 second intervals, around the year 4010. Will not spoil my weekend.
484 uint64_t interval = (handwindow_.raw() + 1) / 2;
485 uint32_t valid_time = static_cast<uint32_t>(now_->raw() / interval - offset);
486 // no endian concerns; hmac is created and checked by the same host
487 hmac_ctx_.update(reinterpret_cast<const unsigned char *>(&valid_time),
488 sizeof(valid_time));
489
490 // the memory slab at cli_addr_port of size cli_addrport_size is a reproducibly
491 // hashable representation of the client's address and port
492 size_t cli_addrport_size;
493 const unsigned char *cli_addr_port = pcaib.get_abstract_cli_addrport(cli_addrport_size);
494 hmac_ctx_.update(cli_addr_port, cli_addrport_size);
495
496 // add session id of client
497 const Buffer cli_psid_buf = cli_psid.get_buf();
498 hmac_ctx_.update(cli_psid_buf.c_data(), SID_SIZE);
499
500 // finalize the hmac and package it as the server's ProtoSessionID
501 BufferAllocated hmac_result(SSLLib::CryptoAPI::HMACContext::MAX_HMAC_SIZE);
502 ProtoSessionID srv_psid;
503 hmac_ctx_.final(hmac_result.write_alloc(hmac_ctx_.size()));
504 srv_psid.read(hmac_result);
505
506 return srv_psid;
507 }
508
510 const ProtoSessionID &cli_psid,
511 const PsidCookieAddrInfoBase &pcaib)
512 {
513 // check the current timestamp and the previous one in case the server's clock
514 // has moved to the one following that given to the client
515 for (unsigned int offset = 0; offset <= 1; ++offset)
516 {
517 ProtoSessionID calc_psid = calculate_session_id_hmac(cli_psid, pcaib, offset);
518
519 if (srv_psid.match(calc_psid))
520 {
521 return true;
522 }
523 }
524 return false;
525 }
526
536 TLSCryptInstance::Ptr init_tls_crypt_v2(Buffer &pkt_buf, const unsigned int slice)
537 {
538 // The record the WKc carries dies with this call: nothing here judges it, and the
539 // session created for this client unwraps the same WKc for itself.
542
543 if (ProtoContext::KeyContext::unwrap_tls_crypt_wkc(pkt_buf, pcfg_, *tls_crypt_server, unwrapped) != Error::SUCCESS)
544 return nullptr;
545
546 const unsigned int key_dir = pcfg_.ssl_factory->mode().is_server()
549
550 const OpenVPNStaticKey &kc = unwrapped.client_key;
551
552 // ENCRYPT is the zero of the pair, so the bit is what there is to test
556
557 instance->init(pcfg_.ssl_factory->libctx(),
558 kc.slice(OpenVPNStaticKey::HMAC | slice | key_dir),
559 kc.slice(OpenVPNStaticKey::CIPHER | slice | key_dir));
560
561 return instance;
562 }
563
565
568 const Time::Duration &handwindow_;
569
572
573 // the psid cookie specific hmac object
574 SSLLib::CryptoAPI::HMACContext hmac_ctx_;
575
578};
579
580} // namespace openvpn
const T * c_data() const
Returns a const pointer to the start of the buffer.
Definition buffer.hpp:1193
T * prepend_alloc(const size_t size)
Allocate space for prepending data to the buffer.
Definition buffer.hpp:1597
T * write_alloc(const size_t size)
Allocate space for writing data to the buffer.
Definition buffer.hpp:1587
void prepend(const T *data, const size_t size)
Prepend data to the buffer.
Definition buffer.hpp:1574
size_t size() const
Returns the size of the buffer in T objects.
Definition buffer.hpp:1241
T * data()
Get a mutable pointer to the start of the array.
Definition buffer.hpp:1448
void advance(const size_t delta)
Advances the buffer by the specified delta.
Definition buffer.hpp:1276
bool empty() const
Returns true if the buffer is empty.
Definition buffer.hpp:1235
void push_front(const T &value)
Append a T object to the array, with possible resize.
Definition buffer.hpp:1488
void read(NCT *data, const size_t size)
Read data from the buffer into the specified memory location.
Definition buffer.hpp:1330
size_t prepare(const unsigned int context, Buffer &buf) const
Definition frame.hpp:263
bool is_server() const
Definition mode.hpp:36
StaticKey slice(unsigned int key_specifier) const
virtual OvpnHMACInstance::Ptr new_obj()=0
virtual void ovpn_hmac_gen(unsigned char *data, const size_t data_size, const size_t l1, const size_t l2, const size_t l3)=0
virtual void init(const StaticKey &key)=0
virtual bool ovpn_hmac_cmp(const unsigned char *data, const size_t data_size, const size_t l1, const size_t l2, const size_t l3)=0
virtual size_t output_size() const =0
void write_next(Buffer &buf, const bool prepend, const PacketIDControl::time_t now)
static Error::Type unwrap_tls_crypt_wkc(Buffer &recv, const ProtoConfig &proto_config, TLSCryptInstance &tls_crypt_server, UnwrappedWkc &unwrapped)
Extract and process the TLS crypt WKc information.
Definition proto.hpp:2926
SSLFactoryAPI::Ptr ssl_factory
Definition proto.hpp:368
TLSCryptContext::Ptr tls_crypt_context
Definition proto.hpp:447
OpenVPNStaticKey tls_auth_key
leave this undefined to disable tls_auth
Definition proto.hpp:425
OvpnHMACContext::Ptr tls_auth_context
Definition proto.hpp:443
bool is_clients_handshake_ack_tls_auth() const
Returns true if this could be the third packet of the 3-way handshake (tls-auth/none).
Definition proto.hpp:4353
static unsigned char get_server_hard_reset_opfield()
Definition proto.hpp:4383
bool is_clients_handshake_ack_tls_crypt_v2() const
Returns true if this could be the third packet of the 3-way handshake (tls-crypt-v2).
Definition proto.hpp:4359
bool supports_early_negotiation(const PacketIDControl &pidc) const noexcept
Returns true if the peer supports early negotiation (i.e. is able to reply with CONTROL_WKC_V1).
Definition proto.hpp:4347
bool is_ack_v1() const
Returns true if the packet is a P_ACK_V1 (no own message-id field on the wire).
Definition proto.hpp:4365
static void prepend_TLV(Buffer &payload)
Adds an {EARLY_NEG_FLAGS, 2, EARLY_NEG_FLAG_RESEND_WKC} TLV to a payload buffer (use with TLS crypt V...
Definition proto.hpp:4371
bool is_tls_crypt_v2() const noexcept
Returns true if this is a TLS crypt V2 protocol packet.
Definition proto.hpp:4341
bool match(const ProtoSessionID &other) const
Definition psid.hpp:90
const Buffer get_buf() const
Definition psid.hpp:76
void read(BufType &buf)
Definition psid.hpp:59
void prepend(Buffer &buf) const
Definition psid.hpp:70
Interface to communicate the server's address semantics.
virtual const unsigned char * get_abstract_cli_addrport(size_t &slab_size) const =0
Implements the PsidCookie interface.
static StaticKey create_key()
SSLLib::CryptoAPI::HMACContext hmac_ctx_
OvpnHMACInstance::Ptr ta_hmac_recv_
ProtoSessionID get_cookie_psid() override
Get the cookie psid from client's 2nd packet.
static const StaticKey & get_key()
const Time::Duration & handwindow_
TLSCryptInstance::Ptr init_tls_crypt_v2(Buffer &pkt_buf, const unsigned int slice)
Set up the one TLSCryptInstance a caller needs from a tls-crypt-v2 packet's WKc.
static bool read_id_is_early_handshake(Buf &buf)
bool check_session_id_hmac(const ProtoSessionID &srv_psid, const ProtoSessionID &cli_psid, const PsidCookieAddrInfoBase &pcaib)
PsidCookieTransportBase::Ptr pctb_
Intercept process_clients_initial_reset_tls_crypt(Buffer &pkt_buf, const PsidCookieAddrInfoBase &pcaib, const CookieHelper &ch)
Intercept process_clients_server_reset_ack_tls_auth(ConstBuffer &pkt_buf, const PsidCookieAddrInfoBase &pcaib, bool is_ack_v1)
static constexpr int SID_SIZE
ProtoContext::ProtoConfig & pcfg_
Intercept intercept(Buffer &pkt_buf, const PsidCookieAddrInfoBase &pcaib) override
Called when a potential new client session packet is received.
ProtoSessionID calculate_session_id_hmac(const ProtoSessionID &cli_psid, const PsidCookieAddrInfoBase &pcaib, unsigned int offset)
Calculate the psid cookie, the ProtoSessionID hmac.
Intercept process_clients_initial_reset_tls_auth(ConstBuffer &pkt_buf, const PsidCookieAddrInfoBase &pcaib)
static constexpr CryptoAlgs::Type digest_
bool validate_3whs_ack_payload(Buf &buf, const ProtoSessionID &cli_psid, const PsidCookieAddrInfoBase &pcaib, bool has_own_pktid=true)
Intercept process_clients_server_reset_ack_tls_crypt(Buffer &pkt_buf, const PsidCookieAddrInfoBase &pcaib)
static constexpr int OPCODE_SIZE
void provide_psid_cookie_transport(PsidCookieTransportBase::Ptr pctb) override
Give this component the transport needed to send the server's HARD_RESET.
PsidCookieImpl(ServerProto::Factory *psfp)
OvpnHMACInstance::Ptr ta_hmac_send_
virtual bool psid_cookie_send_const(Buffer &send_buf, const PsidCookieAddrInfoBase &pcaib)=0
Interface to integrate this component into the server implementation.
Intercept
Values returned by the intercept() function.
virtual SSLLib::Ctx libctx()=0
virtual const Mode & mode() const =0
void init_from_rng(StrongRandomAPI &rng, const size_t key_size)
const unsigned char * data() const
size_t size() const
virtual TLSCryptInstance::Ptr new_obj_send()=0
virtual TLSCryptInstance::Ptr new_obj_recv()=0
constexpr static const size_t hmac_offset
virtual size_t digest_size() const =0
virtual bool hmac_cmp(const unsigned char *header, const size_t header_len, const unsigned char *payload, const size_t payload_len)=0
virtual bool hmac_gen(unsigned char *header, const size_t header_len, const unsigned char *payload, const size_t payload_len)=0
virtual size_t encrypt(const unsigned char *iv, unsigned char *out, const size_t olen, const unsigned char *in, const size_t ilen)=0
virtual void init(SSLLib::Ctx libctx, const StaticKey &key_hmac, const StaticKey &key_crypt)=0
virtual size_t decrypt(const unsigned char *iv, unsigned char *out, const size_t olen, const unsigned char *in, const size_t ilen)=0
T raw() const
Definition time.hpp:404
base_type seconds_since_epoch() const
Definition time.hpp:289
void work(openvpn_io::io_context &io_context, ThreadCommon &tc, MyRunContext &runctx, const unsigned int unit)
const Alg & get(const Type type)
static constexpr std::size_t id_size
Definition relcommon.hpp:23
std::uint32_t id_t
Definition relcommon.hpp:22
static constexpr size_t size()
static constexpr size_t idsize
What a WKc yields, owned by whoever asked for the unwrap.
Definition proto.hpp:2911
OpenVPNStaticKey client_key
Kc, the client key the WKc wrapped.
Definition proto.hpp:2913