15#ifndef OPENVPN_SSL_PROTO_H
16#define OPENVPN_SSL_PROTO_H
80#ifndef OPENVPN_DEBUG_PROTO
81#define OPENVPN_DEBUG_PROTO 1
115namespace proto_context_private {
118const unsigned char auth_prefix[] = { 0, 0, 0, 0, 2 };
120const unsigned char keepalive_message[] = {
121 0x2a, 0x18, 0x7b, 0xf3, 0x64, 0x1e, 0xb4, 0xcb,
122 0x07, 0xed, 0x2d, 0x0a, 0x98, 0x1f, 0xc7, 0x48
127 KEEPALIVE_FIRST_BYTE = 0x2a
130inline bool is_keepalive(
const Buffer &buf)
132 return buf.
size() >=
sizeof(keepalive_message)
133 && buf[0] == KEEPALIVE_FIRST_BYTE
134 && !std::memcmp(keepalive_message, buf.
c_data(),
sizeof(keepalive_message));
137const unsigned char explicit_exit_notify_message[] = {
138 0x28, 0x7f, 0x34, 0x6b, 0xd4, 0xef, 0x7a, 0x81,
139 0x2d, 0x56, 0xb8, 0xd3, 0xaf, 0xc5, 0x45, 0x9c,
146 EXPLICIT_EXIT_NOTIFY_FIRST_BYTE = 0x28
181 const std::string &peer_info,
192 uint8_t empty[]{0x00, 0x00};
193 buf.
write(&empty, 2);
206 logging::LOG_LEVEL_VERB,
315 static unsigned char op_compose(
const unsigned int opcode,
const unsigned int key_id)
319 return static_cast<unsigned char>((opcode <<
OPCODE_SHIFT) | key_id);
323 const unsigned int key_id,
324 const int op_peer_id)
326 return (
op_compose(opcode, key_id) << 24) | (op_peer_id & 0x00FFFFFF);
469 const int default_key_direction,
489 throw proto_option_error(ERR_INVALID_CONFIG,
"missing dev-type or dev option");
490 const std::string &dev_type = dev->
get(1, 64);
494 throw proto_option_error(ERR_INVALID_CONFIG,
"TAP mode is not supported");
496 throw proto_option_error(ERR_INVALID_OPTION_VAL,
"bad dev-type");
509 const std::string &cipher_name = o->
get(1, 128);
510 if (cipher_name !=
"none")
522 const std::string &auth_name = o->
get(1, 128);
523 if (auth_name !=
"none")
538 throw proto_option_error(ERR_INVALID_OPTION_CRYPTO,
"tls-auth and tls-crypt are mutually exclusive");
556 throw proto_option_error(ERR_INVALID_OPTION_CRYPTO,
"tls-auth and tls-crypt are mutually exclusive");
558 throw proto_option_error(ERR_INVALID_OPTION_CRYPTO,
"tls-crypt and tls-crypt-v2 are mutually exclusive");
573 throw proto_option_error(ERR_INVALID_OPTION_CRYPTO,
"tls-auth and tls-crypt-v2 are mutually exclusive");
575 throw proto_option_error(ERR_INVALID_OPTION_CRYPTO,
"tls-crypt and tls-crypt-v2 are mutually exclusive");
580 std::string keyfile = o->
get(1, 0);
586 tls_crypt_v2_key.
parse(keyfile);
596 tls_crypt_v2_key.
parse(keyfile);
612 const std::string &dir = o->
get(1, 16);
617 else if (dir ==
"bidirectional" || dir ==
"bi")
620 throw proto_option_error(ERR_INVALID_OPTION_CRYPTO,
"bad key-direction parameter");
624 throw proto_option_error(ERR_INVALID_OPTION_CRYPTO,
"bad key-direction default");
634 const std::string meth_name = o->
get(1, 128);
637 OPENVPN_THROW_ARG1(proto_option_error, ERR_INVALID_OPTION_VAL,
"Unknown compressor: '" << meth_name <<
'\'');
648 if (o->
size() == 2 && o->
ref(1) ==
"no")
719 catch (
const std::exception &e)
721 OPENVPN_THROW(process_server_push_error,
"Problem accepting server-pushed parameter: " << e.what());
736 const auto &
flags = o->
get(2, 1024);
737 const auto &protocols = o->
get(3, 1024);
745 OPENVPN_LOG(
"Warning: custom app control requires base64 encoding to properly work");
749 catch (
const std::exception &e)
751 OPENVPN_THROW(process_server_push_error,
"Problem accepting server-pushed parameter: " << e.what());
759 std::string new_cipher;
765 new_cipher = o->
get(1, 128);
766 if (new_cipher !=
"none")
770 catch (
const std::exception &e)
772 OPENVPN_THROW(process_server_push_error,
"Problem accepting server-pushed cipher '" << new_cipher <<
"': " << e.what());
776 std::string new_digest;
782 new_digest = o->
get(1, 128);
783 if (new_digest !=
"none")
787 catch (
const std::exception &e)
789 OPENVPN_THROW(process_server_push_error,
"Problem accepting server-pushed digest '" << new_digest <<
"': " << e.what());
800 bool status = parse_number_validate<int>(o->
get(1, 16),
810 catch (
const std::exception &e)
812 OPENVPN_THROW(process_server_push_error,
"Problem accepting server-pushed peer-id: " << e.what());
819 std::string key_method;
825 key_method = o->
get(1, 128);
826 if (key_method ==
"tls-ekm")
829 OPENVPN_THROW(process_server_push_error,
"Problem accepting key-derivation method '" << key_method <<
"'");
834 catch (
const std::exception &e)
836 OPENVPN_THROW(process_server_push_error,
"Problem accepting key-derivation method '" << key_method <<
"': " << e.what());
845 for (std::size_t i = 1; i < o->
size(); i++)
847 std::string flag = o->
get(i, 128);
848 if (flag ==
"cc-exit")
852 else if (flag ==
"dyn-tls-crypt")
856 else if (flag ==
"tls-ekm")
861 else if (flag ==
"aead-epoch")
867 OPENVPN_THROW(process_server_push_error,
"unknown flag '" << flag <<
"'");
872 catch (
const std::exception &e)
874 OPENVPN_THROW(process_server_push_error,
"Problem accepting protocol-flags: " << e.what());
880 std::string new_comp;
887 new_comp = o->
get(1, 128);
903 <<
", but client has disabled compression, switching to asymmetric");
913 if (o->
size() == 2 && o->
ref(1) ==
"no")
924 catch (
const std::exception &e)
926 OPENVPN_THROW(process_server_push_error,
"Problem accepting server-pushed compressor '" << new_comp <<
"': " << e.what());
932 os <<
" data channel:";
940 os <<
", aead-epoch";
949 os <<
" control channel: tls-auth enabled" << std::endl;
953 os <<
" control channel: tls-crypt v2 enabled" << std::endl;
957 os <<
" control channel: tls-crypt enabled" << std::endl;
961 os <<
" control channel: dynamic tls-crypt enabled" << std::endl;
967 std::ostringstream os;
968 os <<
"PROTOCOL OPTIONS:" << std::endl;
971 os <<
" compress: " <<
comp_ctx.
str() << std::endl;
1004 throw proto_option_error(ERR_INVALID_OPTION_CRYPTO,
"missing support for tls-crypt algorithms");
1044 std::ostringstream
out;
1059 out <<
',' << compstr;
1077 out <<
",key-method 2";
1080 out <<
",tls-server";
1082 out <<
",tls-client";
1103 if (!hwaddr.empty())
1113 std::ostringstream
out;
1114 const char *compstr =
nullptr;
1129 if (SSLLib::SSLAPI::support_key_material_export())
1136 out <<
"IV_NCP=2\n";
1137 out <<
"IV_TCPNL=1\n";
1138 out <<
"IV_PROTO=" << iv_proto <<
'\n';
1150 out <<
"IV_CIPHERS=";
1159 out.seekp(-1, std::ios_base::cur);
1171 out <<
"IV_BS64DL=1\n";
1173 out <<
"IV_RELAY=1\n";
1176 const std::string
ret =
out.str();
1204 return (
unsigned int)adj;
1319 const unsigned int op = buf[0];
1340 std::memcpy(&opi, buf.
c_data(),
sizeof(opi));
1341 opi = ntohl(opi) & 0x00FFFFFF;
1398 return "CONTROL_SOFT_RESET_V1";
1400 return "CONTROL_V1";
1408 return "CONTROL_HARD_RESET_CLIENT_V2";
1410 return "CONTROL_HARD_RESET_CLIENT_V3";
1412 return "CONTROL_HARD_RESET_SERVER_V2";
1414 return "CONTROL_WKC_V1";
1421 std::ostringstream
out;
1425 const size_t orig_size = b.
size();
1433 return "BAD_PACKET";
1442 const unsigned int peer_id = (p1 << 16) + (p2 << 8) + p3;
1443 if (peer_id != 0xFFFFFF)
1444 out <<
" PEER_ID=" << peer_id;
1446 out <<
" SIZE=" << b.
size() <<
'/' << orig_size;
1452 out <<
" SRC_PSID=" << src_psid.
str();
1459 out <<
" PID=" << pid.
str();
1463 out <<
" TLS-CRYPT ENCRYPTED PAYLOAD=" << b.
size() <<
" bytes";
1474 out <<
" PID=" << pid.
str();
1479 const bool dest_psid_defined = !ack.empty();
1481 while (!ack.empty())
1483 out <<
" " << ack.front();
1488 if (dest_psid_defined)
1491 out <<
" DEST_PSID=" << dest_psid.
str();
1497 out <<
" SIZE=" << b.
size() <<
'/' << orig_size;
1500#ifdef OPENVPN_DEBUG_PROTO_DUMP
1505 catch (
const std::exception &e)
1507 out <<
" EXCEPTION: " << e.what();
1517 throw proto_error(
"auth_string_overflow");
1518 const std::uint16_t net_size = htons(
static_cast<std::uint16_t
>(size));
1519 buf.
write((
const unsigned char *)&net_size,
sizeof(net_size));
1526 std::uint16_t net_size;
1527 buf.
read((
unsigned char *)&net_size,
sizeof(net_size));
1528 return ntohs(net_size);
1534 template <
typename S>
1537 const size_t len = str.length();
1541 buf.
write((
const unsigned char *)str.c_str(), len);
1548 template <
typename S>
1554 const char *data = (
const char *)buf.
read_alloc(len);
1556 return S(data, len - 1);
1561 template <
typename S>
1564 const size_t len = str.length();
1565 buf.
write((
const unsigned char *)str.c_str(), len);
1574 template <
typename S>
1577 size_t size = buf.
size();
1582 while (size > 0 && (buf[size - 1] == 0 || buf[size - 1] ==
'\r' || buf[size - 1] ==
'\n'))
1589 return S{
reinterpret_cast<const char *
>(buf.
c_data()), size};
1595 template <
typename S>
1598 const size_t len = str.length();
1618 :
opcode(opcode_arg),
buf(std::move(buf_arg))
1652 operator bool()
const
1781 return "KEV_ACTIVE";
1783 return "KEV_NEGOTIATE";
1785 return "KEV_BECOME_PRIMARY";
1787 return "KEV_PRIMARY_PENDING";
1789 return "KEV_RENEGOTIATE";
1791 return "KEV_RENEGOTIATE_FORCE";
1793 return "KEV_RENEGOTIATE_QUEUE";
1795 return "KEV_EXPIRE";
1853 if (cookie_psid.defined())
1903 throw proto_error(
"app_send: sent control message is too large");
1960 const unsigned char *op32 = (head_size ==
OP_SIZE_V2) ? buf.
c_data() :
nullptr;
1975 throw proto_option_error(ERR_INVALID_OPTION_CRYPTO,
"Unable to add data limit");
1988 catch (std::exception &)
2100 sizeof(proto_context_private::keepalive_message));
2110 sizeof(proto_context_private::explicit_exit_notify_message));
2126 pkt.
buf->write(data, size);
2189 <<
" " <<
proto.
mode().
str() <<
' ' << dck->key.render());
2213 OPENVPN_LOG(
"mssfix disabled since tun-mtu is non-default ("
2218 auto payload_overhead = size_t(0);
2228 payload_overhead += 1;
2236 payload_overhead += 20 + 20;
2250 : sizeof(struct IPv4Header);
2252 ? sizeof(struct TCPHeader)
2253 : sizeof(struct UDPHeader);
2256 auto target = c.mss_parms.mssfix - overhead;
2257 if (CryptoAlgs::mode(c.dc.cipher()) == CryptoAlgs::CBC_HMAC)
2265 auto block_size = CryptoAlgs::block_size(c.
dc.
cipher());
2266 target += block_size;
2267 target = (target / block_size) * block_size;
2273 OPENVPN_LOG(
"mssfix disabled since computed value is outside type bounds ("
2279 c.
mss_fix =
static_cast<decltype(c.mss_fix)
>(target - payload_overhead);
2282 <<
", overhead=" << overhead
2283 <<
", payload_overhead=" << payload_overhead
2284 <<
", target=" << target <<
")");
2296 bool enable_compress =
true;
2338 if (enable_compress)
2364 const unsigned char *orig_data = recv.
data();
2365 const size_t orig_size = recv.
size();
2412 const unsigned char *orig_data = recv.
data();
2413 const size_t orig_size = recv.
size();
2426 if (orig_size < data_offset)
2501 if (!is_safe_conversion<uint16_t>(
proto.
config->mss_fix))
2523 static_assert(
sizeof(op32) ==
OP_SIZE_V2,
"OP_SIZE_V2 inconsistency");
2526 pid_wrap =
crypto->
encrypt(buf, (
const unsigned char *)&op32);
2529 buf.
prepend((
const unsigned char *)&op32,
sizeof(op32));
2552 <<
" KeyContext[" <<
key_id_ <<
"] "
2560 <<
" KeyContext[" <<
key_id_ <<
"] "
2568 <<
" KeyContext[" <<
key_id_ <<
"] "
2613 if (is_safe_conversion<DataLimit::size_type>(size))
2708 unsigned int initial_op(
const bool sender,
const bool tls_crypt_v2)
const
2740 while (!buf.
empty())
2752 if (buf.
size() < len)
2803 throw proto_error(
"app_recv: received control message is too large");
2869 buf->write(proto_context_private::auth_prefix,
sizeof(proto_context_private::auth_prefix));
2872 const std::string options =
proto.
config->options_string();
2894 const unsigned char *buf_pre = buf->read_alloc(
sizeof(proto_context_private::auth_prefix));
2895 if (std::memcmp(buf_pre, proto_context_private::auth_prefix,
sizeof(proto_context_private::auth_prefix)))
2896 throw proto_error(
"bad_auth_prefix");
2898 const std::string options = read_auth_string<std::string>(*buf);
2901 const std::string username = read_auth_string<std::string>(*buf);
2902 const SafeString password = read_auth_string<SafeString>(*buf);
2903 const std::string peer_info = read_auth_string<std::string>(*buf);
2911 if (!bc.
advance(
sizeof(proto_context_private::auth_prefix)))
2962 throw proto_error(
"peer_psid_undef");
3193 const unsigned char *orig_data = recv.
data();
3194 const size_t orig_size = recv.
size();
3226 auto &recv = *pkt.
buf;
3227 const unsigned char *orig_data = recv.data();
3228 const size_t orig_size = recv.size();
3240 if (orig_size < data_offset)
3343 const unsigned char *orig_data = recv.
data();
3344 const size_t orig_size = recv.
size();
3354 if (orig_size < (tls_frame_size +
hmac_size))
3358 const unsigned char *wkc_raw = orig_data + tls_frame_size;
3359 const size_t wkc_raw_size = orig_size - tls_frame_size -
sizeof(uint16_t);
3363 std::memcpy(&wkc_len, wkc_raw + wkc_raw_size,
sizeof(wkc_len));
3364 wkc_len = ntohs(wkc_len);
3367 const size_t serverkey_id_size =
proto.
config->tls_crypt_v2_serverkey_id ?
sizeof(k_id) : 0;
3371 std::memcpy(&k_id, wkc_raw + wkc_raw_size - serverkey_id_size,
sizeof(k_id));
3376 if ((wkc_len -
sizeof(uint16_t)) != wkc_raw_size)
3382 wkc_len = htons(wkc_len);
3383 plaintext.
write(&wkc_len,
sizeof(wkc_len));
3387 std::stringstream ss;
3388 ss << std::hex << std::setfill(
'0') << std::uppercase << std::setw(8) << k_id;
3390 const std::string serverkey_fn = ss.str() +
".key";
3391 const std::string serverkey_path =
proto.
config->tls_crypt_v2_serverkey_dir +
"/"
3392 + serverkey_fn.substr(0, 2) +
"/" + serverkey_fn;
3396 const std::string serverkey =
read_text(serverkey_path);
3401 tls_crypt_v2_key.
parse(serverkey);
3411 plaintext.
write(&k_id,
sizeof(k_id));
3415 plaintext.
data() + 2 + serverkey_id_size,
3416 plaintext.
max_size() - 2 - serverkey_id_size,
3418 wkc_raw_size -
hmac_size - serverkey_id_size);
3443 plaintext.
advance(
sizeof(wkc_len));
3446 plaintext.
advance(
sizeof(k_id));
3457 int metadata_type = -1;
3458 if (!plaintext.
empty())
3534 return "C_WAIT_RESET_ACK";
3536 return "C_WAIT_AUTH_ACK";
3538 return "S_WAIT_RESET_ACK";
3540 return "S_WAIT_AUTH_ACK";
3544 return "C_WAIT_RESET";
3546 return "C_WAIT_AUTH";
3550 return "S_WAIT_RESET";
3552 return "S_WAIT_AUTH";
3556 return "STATE_UNDEF";
3563 Time::Duration d = next_time - *
now;
3564 if (d.is_infinite())
3567 return numeric_cast<int>(d.to_seconds());
3608 : op_code_(opcode_extract(op_field)), key_id_(key_id_extract(op_field))
3614 return key_id_ == 0 && op_code_ == CONTROL_HARD_RESET_CLIENT_V2;
3619 return key_id_ == 0 && (op_code_ == CONTROL_V1 || op_code_ == ACK_V1);
3624 return op_compose(CONTROL_HARD_RESET_SERVER_V2, 0);
3636 : proto_field_(peer_info.get_num<unsigned int>(
"IV_PROTO", 1, 0))
3642 return proto_field_ & iv_proto_flag::IV_PROTO_TLS_KEY_EXPORT;
3647 return proto_field_ & iv_proto_flag::IV_PROTO_AUTH_FAIL_TEMP;
3652 return proto_field_ & iv_proto_flag::IV_PROTO_DATA_V2;
3657 return proto_field_ & iv_proto_flag::IV_PROTO_AUTH_PENDING_KW;
3662 return proto_field_ & iv_proto_flag::IV_PROTO_PUSH_UPDATE;
3667 return proto_field_ & iv_proto_flag::IV_PROTO_REQUEST_PUSH;
3673 return proto_field_ & iv_proto_flag::IV_PROTO_CC_EXIT_NOTIFY;
3679 return proto_field_ & iv_proto_flag::IV_PROTO_DYN_TLS_CRYPT;
3685 return proto_field_ & iv_proto_flag::IV_PROTO_DNS_OPTION_V2;
3709 throw tls_auth_pre_validate();
3712 reset_op = server ? CONTROL_HARD_RESET_CLIENT_V2 : CONTROL_HARD_RESET_SERVER_V2;
3722 ? OpenVPNStaticKey::INVERSE
3723 : OpenVPNStaticKey::NORMAL;
3724 ta_hmac_recv->init(c.
tls_auth_key.
slice(OpenVPNStaticKey::HMAC | OpenVPNStaticKey::DECRYPT | key_dir));
3737 if (!net_buf.
size())
3740 const unsigned int op = net_buf[0];
3741 if (opcode_extract(op) != reset_op || key_id_extract(op) != 0)
3744 return ta_hmac_recv->ovpn_hmac_cmp(net_buf.
c_data(),
3746 1 + ProtoSessionID::SIZE,
3747 ta_hmac_recv->output_size(),
3748 PacketIDControl::size());
3772 throw tls_crypt_pre_validate();
3775 reset_op = CONTROL_HARD_RESET_SERVER_V2;
3787 reset_op = tls_crypt_v2_enabled
3788 ? CONTROL_HARD_RESET_CLIENT_V3
3789 : CONTROL_HARD_RESET_CLIENT_V2;
3795 const unsigned int key_dir = server ? OpenVPNStaticKey::NORMAL : OpenVPNStaticKey::INVERSE;
3798 c.
tls_crypt_key.
slice(OpenVPNStaticKey::CIPHER | OpenVPNStaticKey::DECRYPT | key_dir));
3811 if (!net_buf.
size())
3814 const unsigned int op = net_buf[0];
3815 if (opcode_extract(op) != reset_op || key_id_extract(op) != 0)
3818 const size_t data_offset = TLSCryptContext::hmac_offset + tls_crypt_recv->output_hmac_size();
3819 if (net_buf.
size() < data_offset)
3825 const size_t decrypt_bytes = tls_crypt_recv->decrypt(net_buf.
c_data() + TLSCryptContext::hmac_offset,
3828 net_buf.
c_data() + data_offset,
3829 net_buf.
size() - data_offset);
3833 work.inc_size(decrypt_bytes);
3836 return tls_crypt_recv->hmac_cmp(net_buf.
c_data(),
3837 TLSCryptContext::hmac_offset,
3854 bool disabled =
false;
3913 return primary->get_tls_warnings();
3915 OPENVPN_LOG(
"TLS: primary key context uninitialized. Can't retrieve TLS warnings");
3943 key_ctx->export_key_material(dyn_key,
"EXPORTER-OpenVPN-dynamic-tls-crypt");
4006 unsigned int key_dir;
4070 if (cookie_psid.defined())
4126 throw proto_error(
"start: no primary key");
4248 throw proto_error(
"data_encrypt: no primary key");
4270 if (proto_context_private::is_keepalive(in_out))
4291#ifndef OPENVPN_DISABLE_EXPLICIT_EXIT
4297 if (
config->cc_exit_notify)
4304 primary->send_explicit_exit_notify();
4343 return primary->invalidation_reason();
4364 config->process_push(opt, pco);
4373 return config->enable_op32 ? 0 : 1;
4379 return config->keepalive_ping.enabled()
4380 ||
config->keepalive_timeout.enabled();
4386 unsigned int &keepalive_timeout)
4388 keepalive_ping =
config->keepalive_ping.enabled()
4391 keepalive_timeout =
config->keepalive_timeout.enabled()
4406 primary->data_limit_notify(cdl_mode, cdl_status);
4408 secondary->data_limit_notify(cdl_mode, cdl_status);
4426 config->local_peer_id = local_peer_id;
4466 return config->protocol.is_tcp();
4470 return config->protocol.is_udp();
4590 throw select_key_context_error();
4603 throw proto_error(
"select_control_send_context: no primary key");
4631 bool did_work =
false;
4659 <<
" New KeyContext SECONDARY id=" <<
secondary->key_id()
4660 << (initiator ?
" local-triggered" :
" remote-triggered"));
4712 primary->set_next_event_if_unspecified();
4754 secondary->set_next_event_if_unspecified();
4799 if (!
config->wkc.defined())
4800 throw proto_error(
"Client Key Wrapper undefined");
#define OPENVPN_BS64_DATA_LIMIT
void swap(BufferAllocatedType< T_ > &other)
Swaps the contents of this BufferAllocatedType object with another BufferAllocatedType object.
bool advance(size_t size)
report various types of exceptions or errors that may occur when working with buffers
static Type parse_method(const std::string &method)
const char * options_string() const
unsigned int extra_payload_bytes() const
static Type stub(const Type t)
const char * peer_info_string() const
static bool is_any_stub(const Type t)
virtual void decompress(BufferAllocated &buf)=0
virtual void compress(BufferAllocated &buf, const bool hint)=0
const T * c_data() const
Returns a const pointer to the start of the buffer.
T * prepend_alloc(const size_t size)
Allocate space for prepending data to the buffer.
void append(const B &other)
Append data from another buffer to this buffer.
void inc_size(const size_t delta)
Increment the size of the array (usually used in a similar context to set_size such as after mutable_...
size_t max_size() const
Return the maximum allowable size value in T objects given the current offset (without considering re...
void prepend(const T *data, const size_t size)
Prepend data to the buffer.
size_t size() const
Returns the size of the buffer in T objects.
T * data()
Get a mutable pointer to the start of the array.
void advance(const size_t delta)
Advances the buffer by the specified delta.
bool empty() const
Returns true if the buffer is empty.
void write(const T *data, const size_t size)
Write data to the buffer.
auto * read_alloc(const size_t size)
Allocate memory and read data from the buffer into the allocated memory.
T pop_front()
Removes and returns the first element from the buffer.
void push_front(const T &value)
Append a T object to the array, with possible resize.
void set_size(const size_t size)
After an external method, operating on the array as a mutable unsigned char buffer,...
void null_terminate()
Null-terminate the array.
void reset_size()
Resets the size of the buffer to zero.
void read(NCT *data, const size_t size)
Read data from the buffer into the specified memory location.
const char * name() const
virtual CryptoDCInstance::Ptr new_obj(const unsigned int key_id)=0
virtual size_t encap_overhead() const =0
virtual void explicit_exit_notify()
virtual void init_pid(const char *recv_name, const int recv_unit, const SessionStats::Ptr &recv_stats_arg)=0
virtual unsigned int defined() const =0
virtual void init_remote_peer_id(const int remote_peer_id)
virtual void init_hmac(StaticKey &&encrypt_key, StaticKey &&decrypt_key)=0
virtual void rekey(const RekeyType type)=0
virtual bool encrypt(BufferAllocated &buf, const unsigned char *op32)=0
virtual Error::Type decrypt(BufferAllocated &buf, std::time_t now, const unsigned char *op32)=0
virtual bool consider_compression(const CompressContext &comp_ctx)=0
@ EXPLICIT_EXIT_NOTIFY_DEFINED
virtual void init_cipher(StaticKey &&encrypt_key, StaticKey &&decrypt_key)=0
CryptoAlgs::Type cipher() const
bool useEpochKeys() const
CryptoAlgs::KeyDerivation key_derivation() const
CryptoAlgs::Type digest() const
void set_key_derivation(CryptoAlgs::KeyDerivation method)
CryptoDCContext & context()
void set_use_epoch_keys(bool at_the_end)
void set_digest(const CryptoAlgs::Type new_digest)
void set_cipher(const CryptoAlgs::Type new_cipher)
static const char * mode_str(const Mode m)
static const char * state_str(const State s)
size_t prepare(const unsigned int context, Buffer &buf) const
const char * dev_type() const
static void mssfix(BufferAllocated &buf, uint16_t mss_fix)
void XOR(const OpenVPNStaticKey &other)
unsigned char * raw_alloc()
void parse(const std::string &key_text)
StaticKey slice(unsigned int key_specifier) const
const Option * get_ptr(const std::string &name) const
bool exists(const std::string &name) const
const std::string & get(const size_t index, const size_t max_len) const
T get_num(const size_t idx) const
void min_args(const size_t n) const
const std::string & ref(const size_t i) const
virtual OvpnHMACInstance::Ptr new_obj()=0
virtual size_t size() const =0
virtual OvpnHMACContext::Ptr new_obj(const CryptoAlgs::Type digest_type)=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
void init(const char *name_arg, const int unit_arg, const SessionStats::Ptr &stats_arg)
PacketIDControl read_next(Buffer &buf) const
bool test_add(const PacketIDControl &pin, const PacketIDControl::time_t now, const bool mod)
void init(PacketIDControl::id_t start_at=0)
void write_next(Buffer &buf, const bool prepend, const PacketIDControl::time_t now)
virtual void control_net_send(const Buffer &net_buf)=0
static void write_empty_string(Buffer &buf)
virtual void client_auth(Buffer &buf)
virtual void control_recv(BufferPtr &&app_bp)=0
virtual void server_auth(const std::string &username, const SafeString &password, const std::string &peer_info, const AuthCert::Ptr &auth_cert)
virtual void active(bool primary)=0
Called when KeyContext transitions to ACTIVE state.
virtual ~ProtoContextCallbackInterface()=default
virtual bool supports_proto_v3()=0
unsigned int proto_field_
bool client_supports_dns_option() const
Checks if the client can handle dns (as opposed to dhcp-option).
bool client_supports_ekm_key_method() const
bool client_supports_push_update() const
bool client_supports_data_v2() const
bool client_supports_request_push() const
bool client_supports_auth_pending_kwargs() const
IvProtoHelper(const OptionList &peer_info)
bool client_supports_temp_auth_failed() const
bool client_supports_exit_notify() const
Checks if the client is able to send an explicit EXIT message before exiting.
bool client_supports_dynamic_tls_crypt() const
Checks if the client can handle dynamic TLS-crypt.
Time data_limit_expire() const
void encapsulate(id_t id, Packet &pkt)
static const char * event_type_string(const EventType et)
bool decapsulate_post_process(Packet &pkt, ProtoSessionID &src_psid, const PacketIDControl pid)
Time reached_active() const
void kev_error(const EventType ev, const Error::Type reason)
Time reached_active_time_
static BufferAllocated static_work
static bool validate(const Buffer &net_buf, ProtoContext &proto, TimePtr now)
void set_protocol(const Protocol &p)
void prepend_dest_psid_and_acks(Buffer &buf, unsigned int opcode)
void set_next_event_if_unspecified()
TLSPRFInstance::Ptr tlsprf
Time next_retransmit() const
bool net_recv(Packet &&pkt)
void invalidate_callback()
void set_state(const int newstate)
BufferComposed app_recv_buf
std::deque< BufferPtr > app_pre_write_queue
void recv_auth(BufferPtr buf)
bool decapsulate_tls_plain(Packet &pkt)
EventType get_event() const
static bool validate_tls_plain(Buffer &recv, ProtoContext &proto, TimePtr now)
void app_recv(BufferPtr &&to_app_buf)
ProtoStackBase< Packet, KeyContext > Base
void net_send(const Packet &net_pkt, const Base::NetSendType nstype)
void app_send(BufferPtr &&bp)
void set_event(const EventType current)
void raw_recv(Packet &&raw_pkt)
void gen_head(const unsigned int opcode, BufferAllocated &buf)
unsigned int crypto_flags
std::unique_ptr< DataLimit > data_limit
void prepare_expire(const EventType current_ev=KeyContext::KEV_NONE)
void decrypt(BufferAllocated &buf)
Time become_primary_time()
void send_data_channel_message(const unsigned char *data, const size_t size)
void gen_head_tls_crypt(const unsigned int opcode, BufferAllocated &buf)
void gen_head_tls_plain(const unsigned int opcode, Buffer &buf)
void encrypt(BufferAllocated &buf)
bool data_limit_defer() const
bool recv_auth_complete(BufferComplete &bc) const
bool data_channel_ready() const
bool verify_src_psid(const ProtoSessionID &src_psid)
void generate_ack(Packet &pkt)
bool verify_dest_psid(Buffer &buf)
Error::Type invalidation_reason() const
bool parse_early_negotiation(const Packet &pkt)
void calculate_mssfix(ProtoConfig &c)
bool decapsulate_tls_crypt(Packet &pkt)
static bool validate_tls_crypt(Buffer &recv, ProtoContext &proto, TimePtr now)
void start(const ProtoSessionID cookie_psid=ProtoSessionID())
Initialize the state machine and start protocol negotiation.
void invalidate(const Error::Type reason)
uint32_t get_tls_warnings() const
void generate_datachannel_keys()
void gen_head_tls_auth(const unsigned int opcode, Buffer &buf)
void process_next_event()
bool unwrap_tls_crypt_wkc(Buffer &recv)
Extract and process the TLS crypt WKc information.
Base::ReliableSend ReliableSend
void app_send_validate(BufferPtr &&bp)
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_unwrap_wkc_error)
Base::ReliableRecv ReliableRecv
void data_limit_event(const DataLimit::Mode mode, const DataLimit::State state)
CryptoDCInstance::Ptr crypto
bool key_limit_renegotiation_fired
KeyContext(ProtoContext &p, const bool initiator, bool psid_cookie_mode=false)
void send_explicit_exit_notify()
unsigned int key_id() const
static bool validate_tls_auth(Buffer &recv, ProtoContext &proto, TimePtr now)
unsigned int initial_op(const bool sender, const bool tls_crypt_v2) const
int seconds_until(const Time &next_time)
static const char * state_string(const int s)
void data_limit_notify(const DataLimit::Mode cdl_mode, const DataLimit::State cdl_status)
bool do_encrypt(BufferAllocated &buf, const bool compress_hint)
std::unique_ptr< DataChannelKey > data_channel_key
bool data_limit_add(const DataLimit::Mode mode, const size_t size)
void set_event(const EventType current, const EventType next, const Time &next_time)
void schedule_key_limit_renegotiation()
void rekey(const CryptoDCInstance::RekeyType type)
bool decapsulate(Packet &pkt)
void key_limit_reneg(const EventType ev, const Time &t)
bool decapsulate_tls_auth(Packet &pkt)
PacketType(const Buffer &buf, class ProtoContext &proto)
bool is_soft_reset() const
bool contains_tls_ciphertext() const
Packet(BufferPtr &&buf_arg, const unsigned int opcode_arg=CONTROL_V1)
void frame_prepare(const Frame &frame, const unsigned int context)
const Buffer & buffer() const
const BufferPtr & buffer_ptr()
void parse_pushed_peer_id(const OptionList &opt)
PeerInfo::Set::Ptr extra_peer_info
extra peer info key/value pairs generated by client app
Time::Duration keepalive_ping
void build_connect_time_peer_info_string(TransportClient::Ptr transport)
std::string relay_prefix(const char *optname) const
void enable_dynamic_tls_crypt()
void load_common(const OptionList &opt, const ProtoContextCompressionOptions &pco, const LoadCommonType type)
SSLFactoryAPI::Ptr ssl_factory
bool tls_crypt_enabled() const
void set_protocol(const Protocol &p)
std::string initial_options
unsigned int link_mtu_adjust()
std::string peer_info_string(bool proto_v3_support) const
void set_tls_crypt_algs()
TLSCryptContext::Ptr tls_crypt_context
TLSCryptFactory::Ptr tls_crypt_factory
TLSCryptMetadataFactory::Ptr tls_crypt_metadata_factory
Time::Duration become_primary
bool tls_crypt_v2_serverkey_id
do we expect keys to contain a server key ID?
Time::Duration tls_timeout
std::string tls_crypt_v2_serverkey_dir
server keys location, if tls_crypt_v2_serverkey_id is true
void show_cc_enc_option(std::ostringstream &os) const
BufferAllocated wkc
leave this undefined to disable tls-crypt-v2 on client
void set_tls_auth_digest(const CryptoAlgs::Type digest)
void parse_pushed_data_channel_options(const OptionList &opt)
bool tls_auth_enabled() const
AppControlMessageReceiver app_control_recv
void get_data_channel_options(std::ostringstream &os) const
void set_xmit_creds(const bool xmit_creds_arg)
Time::Duration handshake_window
void process_push(const OptionList &opt, const ProtoContextCompressionOptions &pco)
AppControlMessageConfig app_control_config
OpenVPNStaticKey tls_crypt_key
leave this undefined to disable tls-crypt/tls-crypt-v2
void load(const OptionList &opt, const ProtoContextCompressionOptions &pco, const int default_key_direction, const bool server)
bool dynamic_tls_crypt_enabled() const
void parse_pushed_protocol_flags(const OptionList &opt)
OpenVPNStaticKey tls_auth_key
leave this undefined to disable tls_auth
PeerInfo::Set::Ptr extra_peer_info_transport
std::string options_string()
std::string show_options() const
Time::Duration keepalive_timeout_early
unsigned tls_crypt_
needed to distinguish between tls-crypt and tls-crypt-v2 server mode
void parse_custom_app_control(const OptionList &opt)
void parse_pushed_compression(const OptionList &opt, const ProtoContextCompressionOptions &pco)
OvpnHMACContext::Ptr tls_auth_context
@ LOAD_COMMON_CLIENT_PUSHED
bool extra_peer_info_push_peerinfo
TLSPRFFactory::Ptr tlsprf_factory
bool tls_crypt_v2_enabled() const
Time::Duration renegotiate
Time::Duration keepalive_timeout
OvpnHMACFactory::Ptr tls_auth_factory
const unsigned int key_id_
static unsigned char get_server_hard_reset_opfield()
const unsigned int op_code_
PsidCookieHelper(unsigned int op_field)
bool is_clients_server_reset_ack() const
bool is_clients_initial_reset() const
OvpnHMACInstance::Ptr ta_hmac_recv
TLSAuthPreValidate(const ProtoConfig &c, const bool server)
OPENVPN_SIMPLE_EXCEPTION(tls_auth_pre_validate)
bool validate(const BufferAllocated &net_buf)
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_pre_validate)
TLSCryptPreValidate(const ProtoConfig &c, const bool server)
bool validate(const BufferAllocated &net_buf)
TLSCryptInstance::Ptr tls_crypt_recv
virtual bool validate(const BufferAllocated &net_buf)=0
RCPtr< TLSWrapPreValidate > Ptr
void data_limit_notify(const unsigned int key_id, const DataLimit::Mode cdl_mode, const DataLimit::State cdl_status)
bool control_net_recv(const PacketType &type, BufferPtr &&net_bp)
void set_local_peer_id(const int local_peer_id)
uint32_t get_tls_warnings() const
void send_explicit_exit_notify()
OPENVPN_UNTAGGED_EXCEPTION_INHERIT(option_error, process_server_push_error)
void net_send(const unsigned int key_id, const Packet &net_pkt)
const Time::Duration & slowest_handshake()
CryptoDCSettings & dc_settings()
void flush(const bool control_channel)
void set_dynamic_tls_crypt(const ProtoConfig &c, const KeyContext::Ptr &key_ctx)
OPENVPN_SIMPLE_EXCEPTION(select_key_context_error)
void control_send(BufferPtr &&app_bp)
KeyContext & select_control_send_context()
bool uses_bs64_cipher() const
void process_secondary_event()
void reset_tls_crypt(const ProtoConfig &c, const OpenVPNStaticKey &key)
PacketType packet_type(const Buffer &buf)
TLSCryptMetadata::Ptr tls_crypt_metadata
void data_encrypt(BufferAllocated &in_out)
void reset_tls_crypt_server(const ProtoConfig &c)
@ EARLY_NEG_FLAG_RESEND_WKC
TLSCryptInstance::Ptr tls_crypt_recv
bool is_keepalive_enabled() const
TLSCryptInstance::Ptr tls_crypt_server
const Frame & frame() const
OPENVPN_UNTAGGED_EXCEPTION_INHERIT(option_error, proto_error)
static unsigned char op_compose(const unsigned int opcode, const unsigned int key_id)
static S read_auth_string(Buffer &buf)
ProtoConfig::Ptr conf_ptr() const
OPENVPN_UNTAGGED_EXCEPTION_INHERIT(option_error, proto_option_error)
void process_primary_event()
@ CONTROL_HARD_RESET_CLIENT_V3
@ CONTROL_HARD_RESET_CLIENT_V2
@ CONTROL_HARD_RESET_SERVER_V2
const Mode & mode() const
TLSCryptInstance::Ptr tls_crypt_send
void process_push(const OptionList &opt, const ProtoContextCompressionOptions &pco)
static void write_auth_string(const S &str, Buffer &buf)
void client_auth(Buffer &buf)
static const char * opcode_name(const unsigned int opcode)
static unsigned int opcode_extract(const unsigned int op)
void set_protocol(const Protocol &p)
static unsigned int key_id_extract(const unsigned int op)
static S read_control_string(const Buffer &buf)
void write_control_string(const S &str)
bool data_channel_ready() const
void keepalive_housekeeping()
Time::Duration slowest_handshake_
unsigned int upcoming_key_id
static unsigned int op32_compose(const unsigned int opcode, const unsigned int key_id, const int op_peer_id)
size_t align_adjust_hint() const
PacketIDControlReceive ta_pid_recv
ProtoContextCallbackInterface * proto_callback
void reset_tls_wrap_mode(const ProtoConfig &c)
SessionStats & stat() const
OvpnHMACInstance::Ptr ta_hmac_recv
std::string dump_packet(const Buffer &buf)
void disconnect(const Error::Type reason)
static uint16_t read_uint16_length(Buffer &buf)
bool control_net_validate(const PacketType &type, const Buffer &net_buf)
KeyContext & select_key_context(const PacketType &type, const bool control)
static void write_empty_string(Buffer &buf)
@ IV_PROTO_TLS_KEY_EXPORT
@ IV_PROTO_AUTH_PENDING_KW
@ IV_PROTO_AUTH_FAIL_TEMP
@ IV_PROTO_CC_EXIT_NOTIFY
TLSWrapMode tls_wrap_mode
void app_recv(const unsigned int key_id, BufferPtr &&to_app_buf)
void keepalive_parms_modified()
int primary_state() const
static void write_control_string(const S &str, Buffer &buf)
void control_send(BufferAllocated &&app_buf)
bool data_decrypt(const PacketType &type, BufferAllocated &in_out)
void disable_keepalive(unsigned int &keepalive_ping, unsigned int &keepalive_timeout)
static constexpr PacketIDControl::id_t EARLY_NEG_START
Error::Type invalidation_reason() const
static size_t op_head_size(const unsigned int op)
void new_secondary_key(const bool initiator)
void update_last_received()
void promote_secondary_to_primary()
bool is_state_client_wait_reset_ack() const
unsigned int negotiations() const
PacketIDControlSend ta_pid_send
Time next_housekeeping() const
ProtoContext(ProtoContextCallbackInterface *cb_arg, const ProtoConfig::Ptr &config_arg, const SessionStats::Ptr &stats_arg)
static void write_uint16_length(const size_t size, Buffer &buf)
void tls_crypt_append_wkc(BufferAllocated &dst)
bool control_net_recv(const PacketType &type, BufferAllocated &&net_buf)
virtual ~ProtoContext()=default
std::string debug_prefix()
static constexpr size_t APP_MSG_MAX
const Frame::Ptr & frameptr() const
void reset(const ProtoSessionID cookie_psid=ProtoSessionID())
Resets ProtoContext *this to it's initial state.
void start(const ProtoSessionID cookie_psid=ProtoSessionID())
Initialize the state machine and start protocol negotiation.
bool renegotiate_request(Packet &pkt)
KeyContext::Ptr secondary
unsigned int next_key_id()
OvpnHMACInstance::Ptr ta_hmac_send
const ProtoConfig & conf() const
bool match(const ProtoSessionID &other) const
constexpr bool defined() const
void randomize(StrongRandomAPI &rng)
void prepend(Buffer &buf) const
bool net_recv(Packet &&pkt)
uint32_t get_tls_warnings() const
void raw_send(Packet &&pkt)
Error::Type invalidation_reason() const
const AuthCert::Ptr & auth_cert() const
void app_send(BufferPtr &&buf)
void export_key_material(OpenVPNStaticKey &key, const std::string &label) const
const Time::Duration tls_timeout
Time next_retransmit() const
void invalidate(const Error::Type reason)
std::string ssl_handshake_details() const
const char * occ_str(const bool server) const
unsigned int extra_transport_bytes() const
Reference count base class for objects tracked by RCPtr. Allows copying and assignment.
void reset() noexcept
Points this RCPtr<T> to nullptr safely.
void swap(RCPtr &rhs) noexcept
swaps the contents of two RCPtr<T>
Reference count base class for objects tracked by RCPtr. Disallows copying and assignment.
static Ptr Create(ArgsT &&...args)
Creates a new instance of RcEnable with the given arguments.
static void prepend_id(Buffer &buf, const id_t id)
void push_back(id_t value)
void prepend(Buffer &buf, bool ackv1)
static id_t read_id(Buffer &buf)
static size_t ack_skip(Buffer &buf)
static size_t ack(REL_SEND &rel_send, Buffer &buf, const bool live)
unsigned int receive(const PACKET &packet, const id_t id)
virtual SSLLib::Ctx libctx()=0
virtual const Mode & mode() const =0
A string-like type that clears the buffer contents on delete.
virtual void error(const size_t type, const std::string *text=nullptr)
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 TLSCryptContext::Ptr new_obj(SSLLib::Ctx libctx, const CryptoAlgs::Type digest_type, const CryptoAlgs::Type cipher_type)=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
void parse(const std::string &key_text)
void extract_wkc(BufferAllocated &wkc_out) const
void extract_key(OpenVPNStaticKey &tls_key)
void extract_key(OpenVPNStaticKey &tls_key)
void parse(const std::string &key_text)
virtual void self_write(Buffer &buf)=0
virtual void peer_read(Buffer &buf)=0
virtual void self_randomize(StrongRandomAPI &rng)=0
virtual void generate_key_expansion(OpenVPNStaticKey &dest, const ProtoSessionID &psid_self, const ProtoSessionID &psid_peer) const =0
virtual bool peer_read_complete(BufferComplete &bc)=0
static TimeType infinite()
base_type seconds_since_epoch() const
#define OPENVPN_THROW_ARG1(exc, arg, stuff)
#define OPENVPN_THROW(exc, stuff)
#define OPENVPN_LOG(args)
#define OVPN_LOG_DEBUG(args)
#define OVPN_LOG_INFO(args)
#define OVPN_LOG_VERBOSE(args)
void work(openvpn_io::io_context &io_context, ThreadCommon &tc, MyRunContext &runctx, const unsigned int unit)
Mode mode(const Type type)
Type lookup(const std::string &name)
size_t key_length(const Type type)
const char * name(const KeyDerivation kd)
size_t size(const Type type)
std::size_t for_each(std::function< bool(Type, const Alg &)> fn)
bool is_safe_conversion(InT inVal)
Returns true if the given value can be contained by the out type.
OutT clamp_to_typerange(InT inVal)
Clamps the input value to the legal range for the output type.
bool starts_with(const STRING &str, const std::string &prefix)
std::vector< T > split(const T &str, const typename T::value_type sep, const int maxsplit=-1)
std::string trim_crlf_copy(std::string str)
Support deferred server-side state creation when client connects.
std::string to_string(T value)
const Option * load_duration_parm(Time::Duration &dur, const std::string &name, const OptionList &opt, const unsigned int min_value, const bool x2, const bool allow_ms)
void set_duration_parm(Time::Duration &dur, const std::string &name, const std::string &valstr, const unsigned int min_value, const bool x2, const bool ms)
std::string read_text(const std::string &filename, const std::uint64_t max_size=0)
const char * platform_name()
std::string render_hex(const unsigned char *data, size_t size, const bool caps=false)
unsigned int parse_tun_mtu_max(const OptionList &opt, unsigned int default_value)
bool is_bs64_cipher(const CryptoAlgs::Type cipher)
unsigned int parse_tun_mtu(const OptionList &opt, unsigned int default_value)
std::string get_hwaddr(IP::Addr server_addr)
std::string dump_hex(const unsigned char *data, size_t size)
Implementation of the base classes for random number generators.
std::vector< std::string > supported_protocols
List of supported protocols.
int max_msg_size
Maximum size of each individual message/message fragment.
void parse_flags(const std::string &flags)
@ DESTRUCT_ZERO
if enabled, destructor will zero data before deletion
@ CONSTRUCT_ZERO
if enabled, constructors/init will zero allocated space
size_type decrypt_red_limit
size_type encrypt_red_limit
void parse(const OptionList &opt, bool nothrow=false)
static constexpr size_t size()
constexpr std::size_t size() const
bool is_comp_asym() const
std::optional< CryptoDCInstance::RekeyType > rekey_type
virtual IP::Addr server_endpoint_addr() const =0
if(flags &RedirectGatewayFlags::RG_ENABLE) ret+
static std::stringstream out
const std::string optname