|
OpenVPN 3 Core Library
|
#include <proto.hpp>
Classes | |
| struct | DataChannelKey |
| struct | UnwrappedWkc |
| What a WKc yields, owned by whoever asked for the unwrap. More... | |
| struct | WkcMetadata |
| The metadata record a WKc carried, for TLSCryptMetadata::verify() More... | |
Public Types | |
| enum | EventType { KEV_NONE , KEV_ACTIVE , KEV_NEGOTIATE , KEV_BECOME_PRIMARY , KEV_PRIMARY_PENDING , KEV_RENEGOTIATE , KEV_RENEGOTIATE_FORCE , KEV_RENEGOTIATE_QUEUE , KEV_EXPIRE } |
| using | Ptr = RCPtr< KeyContext > |
Public Types inherited from openvpn::RC< thread_unsafe_refcount > | |
| using | Ptr = RCPtr< RC > |
Public Member Functions | |
| OPENVPN_SIMPLE_EXCEPTION (tls_crypt_unwrap_wkc_error) | |
| KeyContext (ProtoContext &p, const bool initiator, bool psid_cookie_mode=false) | |
| void | set_protocol (const Protocol &p) |
| uint32_t | get_tls_warnings () const |
| void | start (const ProtoSessionID cookie_psid=ProtoSessionID()) |
| Initialize the state machine and start protocol negotiation. | |
| void | flush () |
| void | invalidate (const Error::Type reason) |
| void | retransmit () |
| Time | next_retransmit () const |
| void | app_send_validate (BufferPtr &&bp) |
| void | app_send (BufferPtr &&bp) |
| bool | net_recv (Packet &&pkt) |
| void | encrypt (BufferAllocated &buf) |
| void | decrypt (BufferAllocated &buf) |
| void | prepare_expire (const EventType current_ev=KeyContext::KEV_NONE) |
| void | set_next_event_if_unspecified () |
| void | key_limit_reneg (const EventType ev, const Time &t) |
| Time | become_primary_time () |
| bool | event_pending () |
| EventType | get_event () const |
| void | reset_event () |
| bool | invalidated () const |
| Error::Type | invalidation_reason () const |
| unsigned int | key_id () const |
| bool | data_channel_ready () const |
| bool | is_dirty () const |
| void | rekey (const CryptoDCInstance::RekeyType type) |
| Time | reached_active () const |
| void | send_keepalive () |
| void | send_explicit_exit_notify () |
| void | send_data_channel_message (const unsigned char *data, const size_t size) |
| void | generate_datachannel_keys () |
| void | calculate_mssfix (ProtoConfig &c) |
| void | init_data_channel () |
| void | data_limit_notify (const DataLimit::Mode cdl_mode, const DataLimit::State cdl_status) |
| int | get_state () const |
Public Member Functions inherited from openvpn::RC< thread_unsafe_refcount > | |
| RC () noexcept=default | |
| RC (const RC &)=delete | |
| virtual | ~RC ()=default |
| RC & | operator= (const RC &)=delete |
| olong | use_count () const noexcept |
| Delegates call to RCImpl and returns the result. | |
Static Public Member Functions | |
| static const char * | event_type_string (const EventType et) |
| static bool | validate (const Buffer &net_buf, ProtoContext &proto, TimePtr now) |
| static size_t | tls_crypt_frame_size (const ProtoConfig &proto_config) |
| Smallest tls-crypt frame a WKc can be appended to. | |
| static size_t | wkc_overhead (const ProtoConfig &proto_config) |
| What a WKc holds besides the client key and the metadata. | |
| static bool | trailing_wkc_len (const Buffer &recv, const ProtoConfig &proto_config, const size_t min_wkc_len, uint16_t &wkc_len) |
| Read and validate the WKc length a tls-crypt-v2 packet ends with. | |
| 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. | |
| static bool | strip_resent_wkc (Buffer &recv, const ProtoConfig &proto_config) |
| Virtually remove a resent WKc from the end of a CONTROL_WKC_V1 packet. | |
Static Public Member Functions inherited from openvpn::RC< thread_unsafe_refcount > | |
| static constexpr bool | is_thread_safe () |
| Delegates call to RCImpl and returns the result. | |
Private Types | |
| using | Base = ProtoStackBase< Packet, KeyContext > |
| using | ReliableSend = Base::ReliableSend |
| using | ReliableRecv = Base::ReliableRecv |
Private Types inherited from openvpn::ProtoStackBase< Packet, KeyContext > | |
| enum | NetSendType |
| using | id_t = reliable::id_t |
| using | ReliableSend = ReliableSendTemplate< Packet > |
| using | ReliableRecv = ReliableRecvTemplate< Packet > |
Private Member Functions | |
| bool | do_encrypt (BufferAllocated &buf, const bool compress_hint) |
| void | cache_op32 () |
| void | set_state (const int newstate) |
| void | set_event (const EventType current) |
| void | set_event (const EventType current, const EventType next, const Time &next_time) |
| void | invalidate_callback () |
| void | schedule_key_limit_renegotiation () |
| bool | data_limit_add (const DataLimit::Mode mode, const size_t size) |
| void | data_limit_event (const DataLimit::Mode mode, const DataLimit::State state) |
| bool | data_limit_defer () const |
| Time | data_limit_expire () const |
| void | active_event () |
| void | process_next_event () |
| void | kev_error (const EventType ev, const Error::Type reason) |
| unsigned int | initial_op (const bool sender, const bool tls_crypt_v2) const |
| void | send_reset () |
| bool | parse_early_negotiation (const Packet &pkt) |
| void | raw_recv (Packet &&raw_pkt) |
| void | app_recv (BufferPtr &&to_app_buf) |
| void | net_send (const Packet &net_pkt, const Base::NetSendType nstype) |
| void | post_ack_action () |
| void | send_auth () |
| void | recv_auth (BufferPtr buf) |
| bool | recv_auth_complete (BufferComplete &bc) const |
| void | active () |
| void | prepend_dest_psid_and_acks (Buffer &buf, unsigned int opcode) |
| bool | verify_src_psid (const ProtoSessionID &src_psid) |
| void | accept_peer (const ProtoSessionID &src_psid) |
Adopt src_psid as our peer, and mark this packet as ours. | |
| bool | verify_dest_psid (Buffer &buf) |
| void | gen_head_tls_auth (const unsigned int opcode, Buffer &buf) |
| void | gen_head_tls_crypt (const unsigned int opcode, BufferAllocated &buf) |
| void | gen_head_tls_plain (const unsigned int opcode, Buffer &buf) |
| void | gen_head (const unsigned int opcode, BufferAllocated &buf) |
| bool | packet_carries_wkc (id_t id) const |
| size_t | control_channel_wrap_overhead () const |
| size_t | control_ciphertext_capacity (id_t id) const |
| void | encapsulate (id_t id, Packet &pkt) |
| void | generate_ack (Packet &pkt) |
| bool | decapsulate_post_process (Packet &pkt, ProtoSessionID &src_psid, const PacketIDControl pid) |
| bool | decapsulate_tls_auth (Packet &pkt) |
| bool | decapsulate_tls_crypt (Packet &pkt) |
| bool | decapsulate_tls_plain (Packet &pkt) |
| bool | tls_crypt_v2_wanted (const Packet &pkt) const |
| May this packet make a tls-auth server session a tls-crypt-v2 one? | |
| bool | decapsulate (Packet &pkt) |
| bool | decapsulate_by_wrap_mode (Packet &pkt) |
Decapsulate pkt with the wrap mode this session is in. | |
| int | seconds_until (const Time &next_time) |
Private Member Functions inherited from openvpn::ProtoStackBase< Packet, KeyContext > | |
| OPENVPN_SIMPLE_EXCEPTION (proto_stack_invalidated) | |
| OPENVPN_SIMPLE_EXCEPTION (unknown_status_from_ssl_layer) | |
| ProtoStackBase (SSLFactoryAPI &ssl_factory, TimePtr now_arg, const Time::Duration &tls_timeout_arg, const Frame::Ptr &frame, const SessionStats::Ptr &stats_arg, bool psid_cookie_mode) | |
| void | start_handshake () |
| uint32_t | get_tls_warnings () const |
| bool | net_recv (Packet &&pkt) |
| void | app_send (BufferPtr &&buf) |
| void | raw_send (Packet &&pkt) |
| void | flush () |
| void | send_pending_acks () |
| void | retransmit () |
| Time | next_retransmit () const |
| bool | ssl_started () const |
| bool | invalidated () const |
| Error::Type | invalidation_reason () const |
| void | invalidate (const Error::Type reason) |
| std::string | ssl_handshake_details () const |
| void | export_key_material (OpenVPNStaticKey &key, const std::string &label) const |
| const AuthCert::Ptr & | auth_cert () const |
Static Private Member Functions | |
| static bool | validate_tls_auth (Buffer &recv, ProtoContext &proto, TimePtr now) |
| static bool | validate_tls_crypt (Buffer &recv, ProtoContext &proto, TimePtr now) |
| static bool | validate_tls_plain (Buffer &recv, ProtoContext &proto, TimePtr now) |
| static const char * | state_string (const int s) |
Private Attributes | |
| friend | Base |
| ProtoContext & | proto |
| int | state |
| unsigned int | key_id_ |
| unsigned int | crypto_flags |
| int | remote_peer_id |
| bool | enable_op32 |
| bool | resend_wkc = false |
| bool | pkt_from_peer = false |
| Set per packet by accept_peer(), read by decapsulate() | |
| bool | dirty |
| bool | key_limit_renegotiation_fired |
| bool | is_reliable |
| Compress::Ptr | compress |
| CryptoDCInstance::Ptr | crypto |
| TLSPRFInstance::Ptr | tlsprf |
| Time | construct_time |
| Time | reached_active_time_ |
| Time | next_event_time |
| EventType | current_event |
| EventType | next_event |
| std::deque< BufferPtr > | app_pre_write_queue |
| std::unique_ptr< DataChannelKey > | data_channel_key |
| BufferComposed | app_recv_buf |
| std::unique_ptr< DataLimit > | data_limit |
| BufferAllocated | work |
Private Attributes inherited from openvpn::ProtoStackBase< Packet, KeyContext > | |
| TimePtr | now |
| ReliableRecv | rel_recv |
| ReliableSend | rel_send |
| ReliableAck | xmit_acks |
Static Private Attributes | |
| static BufferAllocated | static_work |
Static Private Attributes inherited from openvpn::ProtoStackBase< Packet, KeyContext > | |
| static constexpr size_t | ovpn_sending_window |
| static constexpr size_t | ovpn_receiving_window |
|
private |
|
private |
|
private |
|
inline |
|
inlineprivate |
Adopt src_psid as our peer, and mark this packet as ours.
Reached only once a packet has verified under one of this session's keys and echoed the psid we chose. Pinning earlier let a packet that was then rejected name the peer anyway. Must precede any queued ACK: prepend_dest_psid_and_acks() throws without a peer psid.
Definition at line 3324 of file proto.hpp.
|
inlineprivate |
|
inlineprivate |
|
inlineprivate |
|
inline |
|
inline |
|
inline |
|
inlineprivate |
|
inline |
|
inlineprivate |
|
inlineprivate |
|
inline |
|
inlineprivate |
|
inlineprivate |
|
inlineprivate |
|
inlineprivate |
|
inline |
|
inlineprivate |
|
inlineprivate |
Decapsulate pkt with the wrap mode this session is in.
Split out of decapsulate() so that what the wrap mode decides stays separate from what every packet gets: the tls-crypt-v2 arm is the one with a step of its own, since on a server the key its frame is read with comes from the WKc the packet carries and from nowhere else.
Definition at line 3833 of file proto.hpp.
|
inlineprivate |
|
inlineprivate |
|
inlineprivate |
|
inlineprivate |
|
inline |
|
inlineprivate |
|
inline |
|
inline |
|
inlinestatic |
|
inline |
|
inlineprivate |
|
inlineprivate |
|
inlineprivate |
|
inlineprivate |
|
inlineprivate |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inlineprivate |
|
inline |
|
inlineprivate |
|
inline |
|
inline |
|
inline |
|
inlineprivate |
|
inline |
|
inline |
|
inlineprivate |
|
inline |
| openvpn::ProtoContext::KeyContext::OPENVPN_SIMPLE_EXCEPTION | ( | tls_crypt_unwrap_wkc_error | ) |
|
inlineprivate |
|
inlineprivate |
|
inlineprivate |
|
inline |
|
inlineprivate |
|
inlineprivate |
|
inlineprivate |
|
inline |
|
inlineprivate |
|
inlineprivate |
|
inline |
|
inline |
|
inline |
|
inlineprivate |
|
inlineprivate |
|
inlineprivate |
|
inline |
|
inline |
|
inline |
|
inlineprivate |
|
inlineprivate |
|
inline |
|
inline |
|
inlineprivate |
|
inline |
Initialize the state machine and start protocol negotiation.
Called by ProtoContext::start()
| cookie_psid | see comment in ProtoContext::reset() |
|
inlinestaticprivate |
|
inlinestatic |
Virtually remove a resent WKc from the end of a CONTROL_WKC_V1 packet.
A client asked to resend its WKc (EARLY_NEG_FLAG_RESEND_WKC) appends it to every transmission of the third handshake packet, retransmissions included, since encapsulate() re-runs for each of them. By the time such a packet reaches a session the client key it wraps is already set up, so the WKc is of no further use and must simply be taken off: the tls-crypt frame in front of it is what gets decapsulated, and its auth tag covers that frame alone.
OpenVPN 2 does the same in tls_crypt_v2_extract_client_key() when its initial_packet argument is false, turning the packet back into a CONTROL_V1.
Definition at line 2676 of file proto.hpp.
|
inlinestatic |
Smallest tls-crypt frame a WKc can be appended to.
Header, auth tag, an empty ACK array and the reliable ID, with no ciphertext – a WKc can fill a packet by itself, see control_ciphertext_capacity().
Definition at line 2399 of file proto.hpp.
|
inlineprivate |
May this packet make a tls-auth server session a tls-crypt-v2 one?
Only the opcode asks for the switch and packet_type() weighs nothing else, so a spoofed datagram gets a say. Hence: on offer only until a packet of our peer's has been accepted, and decapsulate() takes it back if this one is not.
Definition at line 3748 of file proto.hpp.
|
inlinestatic |
Read and validate the WKc length a tls-crypt-v2 packet ends with.
wkc_len is read straight from the last two bytes of the packet and is therefore fully attacker-controlled. It has to be validated before any pointer arithmetic uses it: the WKc must fit between the end of the tls-crypt frame and the end of the packet, and hold at least min_wkc_len bytes. Without this a bogus length underflows the unsigned size computations into a wild pointer, causing an out-of-bounds read during decryption – an unauthenticated remote DoS.
recv is too short to hold the tls-crypt frame and the length field, or if wkc_len is smaller than min_wkc_len or larger than the space behind the frame. Definition at line 2436 of file proto.hpp.
|
inlinestatic |
Extract and process the TLS crypt WKc information.
| recv | Buffer containing the raw packet. |
| proto_config | Config object holding the settings needed for processing. |
| tls_crypt_server | Server context used only to process incoming WKc's. |
| unwrapped | Receives the client key and the metadata record the WKc carried. Written only on success. |
Definition at line 2491 of file proto.hpp.
|
inlinestatic |
|
inlinestaticprivate |
|
inlinestaticprivate |
|
inlinestaticprivate |
|
inlineprivate |
|
inlineprivate |
|
inlinestatic |
What a WKc holds besides the client key and the metadata.
Its own trailing length field, the authentication tag T, and the server key ID where one is configured. A WKc smaller than this cannot be parsed at all, so it is the floor an attacker-supplied length is held to.
Definition at line 2415 of file proto.hpp.
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
|
private |
Set per packet by accept_peer(), read by decapsulate()
|
private |
|
private |
|
private |
|
private |
|
staticprivate |
|
private |
|
private |