From: plaisthos (C. Review) <ge...@op...> - 2025-06-25 12:38:18
|
Attention is currently required from: flichtenheld. Hello flichtenheld, I'd like you to do a code review. Please visit http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email to review the following change. Change subject: Check message-id too when doing sessionid cookie ...................................................................... Check message-id too when doing sessionid cookie This fixes that control packets on a floating client can trigger creating a new session in rare instances. Change-Id: I6752dcd5aff3e5cea2b439366479e86751a1c403 --- M src/openvpn/mudp.c M src/openvpn/ssl_pkt.c M src/openvpn/ssl_pkt.h M tests/unit_tests/openvpn/test_pkt.c 4 files changed, 96 insertions(+), 6 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/67/1067/1 diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c index 93e65e0..9cd667c 100644 --- a/src/openvpn/mudp.c +++ b/src/openvpn/mudp.c @@ -63,7 +63,6 @@ msg(D_MULTI_DEBUG, "Reset packet from client, sending HMAC based reset challenge"); } - /* Returns true if this packet should create a new session */ static bool do_pre_decrypt_check(struct multi_context *m, @@ -155,7 +154,8 @@ * need to contain the peer id */ struct gc_arena gc = gc_new(); - bool ret = check_session_id_hmac(state, from, hmac, handwindow); + bool pkt_is_ack = (verdict == VERDICT_VALID_ACK_V1); + bool ret = check_session_id_hmac(state, from, hmac, handwindow, pkt_is_ack); const char *peer = print_link_socket_actual(&m->top.c2.from, &gc); uint8_t pkt_firstbyte = *BPTR( &m->top.c2.buf); @@ -171,6 +171,7 @@ msg(D_MULTI_DEBUG, "Valid packet (%s) with HMAC challenge from peer (%s), " "accepting new connection.", packet_opcode_name(op), peer); } + gc_free(&gc); return ret; diff --git a/src/openvpn/ssl_pkt.c b/src/openvpn/ssl_pkt.c index bfd405f..4b28798 100644 --- a/src/openvpn/ssl_pkt.c +++ b/src/openvpn/ssl_pkt.c @@ -293,6 +293,7 @@ } } + /* * This function is similar to tls_pre_decrypt, except it is called * when we are in server mode and receive an initial incoming @@ -530,7 +531,8 @@ check_session_id_hmac(struct tls_pre_decrypt_state *state, const struct openvpn_sockaddr *from, hmac_ctx_t *hmac, - int handwindow) + int handwindow, + bool pkt_is_ack) { if (!from) { @@ -545,6 +547,36 @@ return false; } + /* Check if the packet ID of the packet or ACKED packet is <= 1 */ + for (int i = 0; i < ack.len; i++) + { + /* This packet ACKs a packet that has a higher packet id than the + * ones expected in the three-way handshake, consider it as invalid + * for the session */ + if (ack.packet_id[i] > 1) + { + return false; + } + } + + if (!pkt_is_ack) + { + packet_id_type message_id; + /* Extract the packet ID from the packet */ + if (!reliable_ack_read_packet_id(&buf, &message_id)) + { + return false; + } + + /* same check. Anything larger than 1 is not considered part of the + * three-way handshake */ + if (message_id > 1) + { + return false; + } + } + + /* check adjacent timestamps too */ for (int offset = -2; offset <= 1; offset++) { diff --git a/src/openvpn/ssl_pkt.h b/src/openvpn/ssl_pkt.h index 98a39d3..53c1a5c 100644 --- a/src/openvpn/ssl_pkt.h +++ b/src/openvpn/ssl_pkt.h @@ -94,6 +94,9 @@ VERDICT_VALID_ACK_V1, /** The packet is a valid control packet with appended wrapped client key */ VERDICT_VALID_WKC_V1, + /** the packet is valid but failed the check of being belong to the packets + * that could be in the three-handshake */ + VERDICT_INVALID_PKTID, /** the packet failed on of the various checks */ VERDICT_INVALID }; @@ -180,17 +183,24 @@ /** * Checks if a control packet has a correct HMAC server session id * + * This will also consider packets that have a packet id higher + * than 1 to be invalid as they are not part of the initial + * three way handshake of OpenVPN and should not create a new + * connection. + * * @param state session information * @param from link_socket from the client * @param hmac the hmac context to use for the calculation * @param handwindow the quantisation of the current time + * @param pkt_is_ack the packet being checked is a P_ACK_V1 * @return the expected server session id */ bool check_session_id_hmac(struct tls_pre_decrypt_state *state, const struct openvpn_sockaddr *from, hmac_ctx_t *hmac, - int handwindow); + int handwindow, + bool check_session_id_hmac); /* * Write a control channel authentication record. diff --git a/tests/unit_tests/openvpn/test_pkt.c b/tests/unit_tests/openvpn/test_pkt.c index ebffabe..09fba8c 100644 --- a/tests/unit_tests/openvpn/test_pkt.c +++ b/tests/unit_tests/openvpn/test_pkt.c @@ -170,6 +170,17 @@ 0x85, 0xdb, 0x53, 0x56, 0x23, 0xb0, 0x2e }; +/* no tls-auth, P_ACK_V1, acks 0,1, and 2 */ +const uint8_t client_ack_123_none_random_id[] = { + 0x28, + 0xae, 0xb9, 0xaf, 0xe1, 0xf0, 0x1d, 0x79, 0xc8, + 0x03, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x02, + 0xdd, 0x85, 0xdb, 0x53, 0x56, 0x23, 0xb0, 0x2e +}; + struct tls_auth_standalone init_tas_auth(int key_direction) { @@ -439,7 +450,7 @@ assert_int_equal(verdict, VERDICT_VALID_CONTROL_V1); /* This is a valid packet but containing a random id instead of an HMAC id*/ - bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30); + bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30, false); assert_false(valid); free_tls_pre_decrypt_state(&state); @@ -470,7 +481,7 @@ verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); assert_int_equal(verdict, VERDICT_VALID_ACK_V1); - bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30); + bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30, true); assert_true(valid); free_tls_pre_decrypt_state(&state); @@ -479,6 +490,41 @@ hmac_ctx_free(hmac); } +static void +test_verify_hmac_none_out_of_range_ack(void **ut_state) +{ + hmac_ctx_t *hmac = session_id_hmac_init(); + + struct link_socket_actual from = { 0 }; + from.dest.addr.sa.sa_family = AF_INET; + + struct tls_auth_standalone tas = { 0 }; + struct tls_pre_decrypt_state state = { 0 }; + + struct buffer buf = alloc_buf(1024); + enum first_packet_verdict verdict; + + tas.tls_wrap.mode = TLS_WRAP_NONE; + + buf_reset_len(&buf); + buf_write(&buf, client_ack_123_none_random_id, sizeof(client_ack_123_none_random_id)); + + + verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); + assert_int_equal(verdict, VERDICT_VALID_ACK_V1); + + /* should fail because it acks 2 */ + bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30, true); + assert_false(valid); + + free_tls_pre_decrypt_state(&state); + free_buf(&buf); + hmac_ctx_cleanup(hmac); + hmac_ctx_free(hmac); +} + + + static hmac_ctx_t * init_static_hmac(void) { @@ -667,6 +713,7 @@ cmocka_unit_test(test_calc_session_id_hmac_static), cmocka_unit_test(test_verify_hmac_none), cmocka_unit_test(test_verify_hmac_tls_auth), + cmocka_unit_test(test_verify_hmac_none_out_of_range_ack), cmocka_unit_test(test_generate_reset_packet_plain), cmocka_unit_test(test_generate_reset_packet_tls_auth), cmocka_unit_test(test_extract_control_message) -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I6752dcd5aff3e5cea2b439366479e86751a1c403 Gerrit-Change-Number: 1067 Gerrit-PatchSet: 1 Gerrit-Owner: plaisthos <arn...@rf...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-MessageType: newchange |
From: plaisthos (C. Review) <ge...@op...> - 2025-06-26 08:11:49
|
Attention is currently required from: flichtenheld. plaisthos has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email ) Change subject: Check message id/acked ids too when doing sessionid cookie checks ...................................................................... Set Ready For Review -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I6752dcd5aff3e5cea2b439366479e86751a1c403 Gerrit-Change-Number: 1067 Gerrit-PatchSet: 2 Gerrit-Owner: plaisthos <arn...@rf...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-Comment-Date: Thu, 26 Jun 2025 08:11:35 +0000 Gerrit-HasComments: No Gerrit-Has-Labels: No Gerrit-MessageType: comment |
From: plaisthos (C. Review) <ge...@op...> - 2025-06-26 08:14:39
|
Attention is currently required from: flichtenheld. Hello flichtenheld, I'd like you to reexamine a change. Please visit http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email to look at the new patch set (#3). Change subject: Check message id/acked ids too when doing sessionid cookie checks ...................................................................... Check message id/acked ids too when doing sessionid cookie checks This fixes that control packets on a floating client can trigger creating a new session in special circumstances: To trigger this circumstance a connection needs to - starts on IP A - successfully floats to IP B by data packet - then has a control packet from IP A before any data packet can trigger the float back to IP A and all of this needs to happen in the 60s time that hmac cookie is valid in the default configuration. In this scenario we would trigger a new connection as the HMAC session id would be valid. This patch adds checking also of the message-id and acked ids to discern packet from the initial three-way handshake where these ids 0 or 1 from any later packet. This will now trigger (at verb 4 or higher) a messaged like: Packet (P_ACK_V1) with invalid or missing SID instead. Reported-By: Walter Doekes <wal...@wj...> Tested-By: Walter Doekes <wal...@wj...> Change-Id: I6752dcd5aff3e5cea2b439366479e86751a1c403 Signed-off-by: Arne Schwabe <ar...@rf...> --- M src/openvpn/mudp.c M src/openvpn/ssl_pkt.c M src/openvpn/ssl_pkt.h M tests/unit_tests/openvpn/test_pkt.c 4 files changed, 112 insertions(+), 6 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/67/1067/3 diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c index 93e65e0..9cd667c 100644 --- a/src/openvpn/mudp.c +++ b/src/openvpn/mudp.c @@ -63,7 +63,6 @@ msg(D_MULTI_DEBUG, "Reset packet from client, sending HMAC based reset challenge"); } - /* Returns true if this packet should create a new session */ static bool do_pre_decrypt_check(struct multi_context *m, @@ -155,7 +154,8 @@ * need to contain the peer id */ struct gc_arena gc = gc_new(); - bool ret = check_session_id_hmac(state, from, hmac, handwindow); + bool pkt_is_ack = (verdict == VERDICT_VALID_ACK_V1); + bool ret = check_session_id_hmac(state, from, hmac, handwindow, pkt_is_ack); const char *peer = print_link_socket_actual(&m->top.c2.from, &gc); uint8_t pkt_firstbyte = *BPTR( &m->top.c2.buf); @@ -171,6 +171,7 @@ msg(D_MULTI_DEBUG, "Valid packet (%s) with HMAC challenge from peer (%s), " "accepting new connection.", packet_opcode_name(op), peer); } + gc_free(&gc); return ret; diff --git a/src/openvpn/ssl_pkt.c b/src/openvpn/ssl_pkt.c index bfd405f..0bbc465 100644 --- a/src/openvpn/ssl_pkt.c +++ b/src/openvpn/ssl_pkt.c @@ -293,6 +293,7 @@ } } + /* * This function is similar to tls_pre_decrypt, except it is called * when we are in server mode and receive an initial incoming @@ -530,7 +531,8 @@ check_session_id_hmac(struct tls_pre_decrypt_state *state, const struct openvpn_sockaddr *from, hmac_ctx_t *hmac, - int handwindow) + int handwindow, + bool pkt_is_ack) { if (!from) { @@ -545,6 +547,36 @@ return false; } + /* Check if the packet ID of the packet or ACKED packet is <= 1 */ + for (int i = 0; i < ack.len; i++) + { + /* This packet ACKs a packet that has a higher packet id than the + * ones expected in the three-way handshake, consider it as invalid + * for the session */ + if (ack.packet_id[i] > 1) + { + return false; + } + } + + if (!pkt_is_ack) + { + packet_id_type message_id; + /* Extract the packet ID from the packet */ + if (!reliable_ack_read_packet_id(&buf, &message_id)) + { + return false; + } + + /* similar check. Anything larger than 1 is not considered part of the + * three-way handshake */ + if (message_id > 1) + { + return false; + } + } + + /* check adjacent timestamps too */ for (int offset = -2; offset <= 1; offset++) { diff --git a/src/openvpn/ssl_pkt.h b/src/openvpn/ssl_pkt.h index 98a39d3..1b6bcc0 100644 --- a/src/openvpn/ssl_pkt.h +++ b/src/openvpn/ssl_pkt.h @@ -180,17 +180,24 @@ /** * Checks if a control packet has a correct HMAC server session id * + * This will also consider packets that have a packet id higher + * than 1 or ack packets higher than 1 to be invalid as they are + * not part of the initial three way handshake of OpenVPN and should + * not create a new connection. + * * @param state session information * @param from link_socket from the client * @param hmac the hmac context to use for the calculation * @param handwindow the quantisation of the current time + * @param pkt_is_ack the packet being checked is a P_ACK_V1 * @return the expected server session id */ bool check_session_id_hmac(struct tls_pre_decrypt_state *state, const struct openvpn_sockaddr *from, hmac_ctx_t *hmac, - int handwindow); + int handwindow, + bool pkt_is_ack); /* * Write a control channel authentication record. diff --git a/tests/unit_tests/openvpn/test_pkt.c b/tests/unit_tests/openvpn/test_pkt.c index ebffabe..56ed842 100644 --- a/tests/unit_tests/openvpn/test_pkt.c +++ b/tests/unit_tests/openvpn/test_pkt.c @@ -170,6 +170,27 @@ 0x85, 0xdb, 0x53, 0x56, 0x23, 0xb0, 0x2e }; +/* no tls-auth, P_ACK_V1, acks 0,1, and 2 */ +const uint8_t client_ack_123_none_random_id[] = { + 0x28, + 0xae, 0xb9, 0xaf, 0xe1, 0xf0, 0x1d, 0x79, 0xc8, + 0x03, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x02, + 0xdd, 0x85, 0xdb, 0x53, 0x56, 0x23, 0xb0, 0x2e +}; + +/* no tls-auth, P_CONTROL_V1, acks 0, msg-id 2 */ +const uint8_t client_control_none_random_id[] = { + 0x20, + 0xae, 0xb9, 0xaf, 0xe1, 0xf0, 0x1d, 0x79, 0xc8, + 0x01, + 0x00, 0x00, 0x00, 0x00, + 0x02 +}; + + struct tls_auth_standalone init_tas_auth(int key_direction) { @@ -439,7 +460,7 @@ assert_int_equal(verdict, VERDICT_VALID_CONTROL_V1); /* This is a valid packet but containing a random id instead of an HMAC id*/ - bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30); + bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30, false); assert_false(valid); free_tls_pre_decrypt_state(&state); @@ -470,7 +491,7 @@ verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); assert_int_equal(verdict, VERDICT_VALID_ACK_V1); - bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30); + bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30, true); assert_true(valid); free_tls_pre_decrypt_state(&state); @@ -479,6 +500,50 @@ hmac_ctx_free(hmac); } +static void +test_verify_hmac_none_out_of_range_ack(void **ut_state) +{ + hmac_ctx_t *hmac = session_id_hmac_init(); + + struct link_socket_actual from = { 0 }; + from.dest.addr.sa.sa_family = AF_INET; + + struct tls_auth_standalone tas = { 0 }; + struct tls_pre_decrypt_state state = { 0 }; + + struct buffer buf = alloc_buf(1024); + enum first_packet_verdict verdict; + + tas.tls_wrap.mode = TLS_WRAP_NONE; + + buf_reset_len(&buf); + buf_write(&buf, client_ack_123_none_random_id, sizeof(client_ack_123_none_random_id)); + + + verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); + assert_int_equal(verdict, VERDICT_VALID_ACK_V1); + + /* should fail because it acks 2 */ + bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30, true); + assert_false(valid); + + /* Try test with the control with a too high message id now */ + buf_reset_len(&buf); + buf_write(&buf, client_control_none_random_id, sizeof(client_control_none_random_id)); + + verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); + assert_int_equal(verdict, VERDICT_VALID_CONTROL_V1); + + /* should fail because it has message id 2 */ + valid = check_session_id_hmac(&state, &from.dest, hmac, 30, true); + assert_false(valid); + + free_tls_pre_decrypt_state(&state); + free_buf(&buf); + hmac_ctx_cleanup(hmac); + hmac_ctx_free(hmac); +} + static hmac_ctx_t * init_static_hmac(void) { @@ -667,6 +732,7 @@ cmocka_unit_test(test_calc_session_id_hmac_static), cmocka_unit_test(test_verify_hmac_none), cmocka_unit_test(test_verify_hmac_tls_auth), + cmocka_unit_test(test_verify_hmac_none_out_of_range_ack), cmocka_unit_test(test_generate_reset_packet_plain), cmocka_unit_test(test_generate_reset_packet_tls_auth), cmocka_unit_test(test_extract_control_message) -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I6752dcd5aff3e5cea2b439366479e86751a1c403 Gerrit-Change-Number: 1067 Gerrit-PatchSet: 3 Gerrit-Owner: plaisthos <arn...@rf...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-MessageType: newpatchset |
From: Walter D. <wal...@wj...> - 2025-07-22 11:12:17
|
Anything I can do to get this moving along? Cheers, Walter On 26-06-2025 10:14, plaisthos (Code Review) wrote: > Attention is currently required from: flichtenheld. > > plaisthos *uploaded patch set #3* to this change. > > View Change <http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email> > > Check message id/acked ids too when doing sessionid cookie checks > > This fixes that control packets on a floating client can trigger > creating a new session in special circumstances: > > To trigger this circumstance a connection needs to > > - starts on IP A > - successfully floats to IP B by data packet > - then has a control packet from IP A before any > data packet can trigger the float back to IP A > > and all of this needs to happen in the 60s time > that hmac cookie is valid in the default > configuration. > > In this scenario we would trigger a new connection as the HMAC > session id would be valid. > > This patch adds checking also of the message-id and acked ids to > discern packet from the initial three-way handshake where these > ids 0 or 1 from any later packet. > > This will now trigger (at verb 4 or higher) a messaged like: > > Packet (P_ACK_V1) with invalid or missing SID > > instead. > > Reported-By: Walter Doekes <wal...@wj...> > Tested-By: Walter Doekes <wal...@wj...> > > Change-Id: I6752dcd5aff3e5cea2b439366479e86751a1c403 > Signed-off-by: Arne Schwabe <ar...@rf...> > --- > M src/openvpn/mudp.c > M src/openvpn/ssl_pkt.c > M src/openvpn/ssl_pkt.h > M tests/unit_tests/openvpn/test_pkt.c > 4 files changed, 112 insertions(+), 6 deletions(-) > > git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/67/1067/3 > > diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c > index 93e65e0..9cd667c 100644 > --- a/src/openvpn/mudp.c > +++ b/src/openvpn/mudp.c > @@ -63,7 +63,6 @@ > msg(D_MULTI_DEBUG, "Reset packet from client, sending HMAC based reset > challenge"); > } > > - > /* Returns true if this packet should create a new session */ > static bool > do_pre_decrypt_check(struct multi_context *m, > @@ -155,7 +154,8 @@ > * need to contain the peer id */ > struct gc_arena gc = gc_new(); > > - bool ret = check_session_id_hmac(state, from, hmac, handwindow); > + bool pkt_is_ack = (verdict == VERDICT_VALID_ACK_V1); > + bool ret = check_session_id_hmac(state, from, hmac, handwindow, > pkt_is_ack); > > const char *peer = print_link_socket_actual(&m->top.c2.from, &gc); > uint8_t pkt_firstbyte = *BPTR( &m->top.c2.buf); > @@ -171,6 +171,7 @@ > msg(D_MULTI_DEBUG, "Valid packet (%s) with HMAC challenge from peer (%s), " > "accepting new connection.", packet_opcode_name(op), peer); > } > + > gc_free(&gc); > > return ret; > diff --git a/src/openvpn/ssl_pkt.c b/src/openvpn/ssl_pkt.c > index bfd405f..0bbc465 100644 > --- a/src/openvpn/ssl_pkt.c > +++ b/src/openvpn/ssl_pkt.c > @@ -293,6 +293,7 @@ > } > } > > + > /* > * This function is similar to tls_pre_decrypt, except it is called > * when we are in server mode and receive an initial incoming > @@ -530,7 +531,8 @@ > check_session_id_hmac(struct tls_pre_decrypt_state *state, > const struct openvpn_sockaddr *from, > hmac_ctx_t *hmac, > - int handwindow) > + int handwindow, > + bool pkt_is_ack) > { > if (!from) > { > @@ -545,6 +547,36 @@ > return false; > } > > + /* Check if the packet ID of the packet or ACKED packet is <= 1 */ > + for (int i = 0; i < ack.len; i++) > + { > + /* This packet ACKs a packet that has a higher packet id than the > + * ones expected in the three-way handshake, consider it as invalid > + * for the session */ > + if (ack.packet_id[i] > 1) > + { > + return false; > + } > + } > + > + if (!pkt_is_ack) > + { > + packet_id_type message_id; > + /* Extract the packet ID from the packet */ > + if (!reliable_ack_read_packet_id(&buf, &message_id)) > + { > + return false; > + } > + > + /* similar check. Anything larger than 1 is not considered part of the > + * three-way handshake */ > + if (message_id > 1) > + { > + return false; > + } > + } > + > + > /* check adjacent timestamps too */ > for (int offset = -2; offset <= 1; offset++) > { > diff --git a/src/openvpn/ssl_pkt.h b/src/openvpn/ssl_pkt.h > index 98a39d3..1b6bcc0 100644 > --- a/src/openvpn/ssl_pkt.h > +++ b/src/openvpn/ssl_pkt.h > @@ -180,17 +180,24 @@ > /** > * Checks if a control packet has a correct HMAC server session id > * > + * This will also consider packets that have a packet id higher > + * than 1 or ack packets higher than 1 to be invalid as they are > + * not part of the initial three way handshake of OpenVPN and should > + * not create a new connection. > + * > * @param state session information > * @param from link_socket from the client > * @param hmac the hmac context to use for the calculation > * @param handwindow the quantisation of the current time > + * @param pkt_is_ack the packet being checked is a P_ACK_V1 > * @return the expected server session id > */ > bool > check_session_id_hmac(struct tls_pre_decrypt_state *state, > const struct openvpn_sockaddr *from, > hmac_ctx_t *hmac, > - int handwindow); > + int handwindow, > + bool pkt_is_ack); > > /* > * Write a control channel authentication record. > diff --git a/tests/unit_tests/openvpn/test_pkt.c > b/tests/unit_tests/openvpn/test_pkt.c > index ebffabe..56ed842 100644 > --- a/tests/unit_tests/openvpn/test_pkt.c > +++ b/tests/unit_tests/openvpn/test_pkt.c > @@ -170,6 +170,27 @@ > 0x85, 0xdb, 0x53, 0x56, 0x23, 0xb0, 0x2e > }; > > +/* no tls-auth, P_ACK_V1, acks 0,1, and 2 */ > +const uint8_t client_ack_123_none_random_id[] = { > + 0x28, > + 0xae, 0xb9, 0xaf, 0xe1, 0xf0, 0x1d, 0x79, 0xc8, > + 0x03, > + 0x00, 0x00, 0x00, 0x00, > + 0x00, 0x00, 0x00, 0x01, > + 0x00, 0x00, 0x00, 0x02, > + 0xdd, 0x85, 0xdb, 0x53, 0x56, 0x23, 0xb0, 0x2e > +}; > + > +/* no tls-auth, P_CONTROL_V1, acks 0, msg-id 2 */ > +const uint8_t client_control_none_random_id[] = { > + 0x20, > + 0xae, 0xb9, 0xaf, 0xe1, 0xf0, 0x1d, 0x79, 0xc8, > + 0x01, > + 0x00, 0x00, 0x00, 0x00, > + 0x02 > +}; > + > + > struct tls_auth_standalone > init_tas_auth(int key_direction) > { > @@ -439,7 +460,7 @@ > assert_int_equal(verdict, VERDICT_VALID_CONTROL_V1); > > /* This is a valid packet but containing a random id instead of an HMAC id*/ > - bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30); > + bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30, false); > assert_false(valid); > > free_tls_pre_decrypt_state(&state); > @@ -470,7 +491,7 @@ > verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); > assert_int_equal(verdict, VERDICT_VALID_ACK_V1); > > - bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30); > + bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30, true); > assert_true(valid); > > free_tls_pre_decrypt_state(&state); > @@ -479,6 +500,50 @@ > hmac_ctx_free(hmac); > } > > +static void > +test_verify_hmac_none_out_of_range_ack(void **ut_state) > +{ > + hmac_ctx_t *hmac = session_id_hmac_init(); > + > + struct link_socket_actual from = { 0 }; > + from.dest.addr.sa.sa_family = AF_INET; > + > + struct tls_auth_standalone tas = { 0 }; > + struct tls_pre_decrypt_state state = { 0 }; > + > + struct buffer buf = alloc_buf(1024); > + enum first_packet_verdict verdict; > + > + tas.tls_wrap.mode = TLS_WRAP_NONE; > + > + buf_reset_len(&buf); > + buf_write(&buf, client_ack_123_none_random_id, > sizeof(client_ack_123_none_random_id)); > + > + > + verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); > + assert_int_equal(verdict, VERDICT_VALID_ACK_V1); > + > + /* should fail because it acks 2 */ > + bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30, true); > + assert_false(valid); > + > + /* Try test with the control with a too high message id now */ > + buf_reset_len(&buf); > + buf_write(&buf, client_control_none_random_id, > sizeof(client_control_none_random_id)); > + > + verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); > + assert_int_equal(verdict, VERDICT_VALID_CONTROL_V1); > + > + /* should fail because it has message id 2 */ > + valid = check_session_id_hmac(&state, &from.dest, hmac, 30, true); > + assert_false(valid); > + > + free_tls_pre_decrypt_state(&state); > + free_buf(&buf); > + hmac_ctx_cleanup(hmac); > + hmac_ctx_free(hmac); > +} > + > static hmac_ctx_t * > init_static_hmac(void) > { > @@ -667,6 +732,7 @@ > cmocka_unit_test(test_calc_session_id_hmac_static), > cmocka_unit_test(test_verify_hmac_none), > cmocka_unit_test(test_verify_hmac_tls_auth), > + cmocka_unit_test(test_verify_hmac_none_out_of_range_ack), > cmocka_unit_test(test_generate_reset_packet_plain), > cmocka_unit_test(test_generate_reset_packet_tls_auth), > cmocka_unit_test(test_extract_control_message) > > To view, visit change 1067 > <http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email>. To unsubscribe, > or for help writing mail filters, visit settings > <http://gerrit.openvpn.net/settings>. > > Gerrit-Project: openvpn > Gerrit-Branch: master > Gerrit-Change-Id: I6752dcd5aff3e5cea2b439366479e86751a1c403 > Gerrit-Change-Number: 1067 > Gerrit-PatchSet: 3 > Gerrit-Owner: plaisthos <arn...@rf...> > Gerrit-Reviewer: flichtenheld <fr...@li...> > Gerrit-CC: openvpn-devel <ope...@li...> > Gerrit-Attention: flichtenheld <fr...@li...> > Gerrit-MessageType: newpatchset > > > _______________________________________________ > Openvpn-devel mailing list > Ope...@li... > https://lists.sourceforge.net/lists/listinfo/openvpn-devel |
From: flichtenheld (C. Review) <ge...@op...> - 2025-07-22 14:59:16
|
Attention is currently required from: plaisthos. flichtenheld has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email ) Change subject: Check message id/acked ids too when doing sessionid cookie checks ...................................................................... Patch Set 3: Code-Review-1 (1 comment) File tests/unit_tests/openvpn/test_pkt.c: http://gerrit.openvpn.net/c/openvpn/+/1067/comment/69758acd_c7222844 : PS3, Line 533: Looking at the LeakSanitizer failure and the other test cases I think there is a `free_tls_pre_decrypt_state(&state);` missing here. -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I6752dcd5aff3e5cea2b439366479e86751a1c403 Gerrit-Change-Number: 1067 Gerrit-PatchSet: 3 Gerrit-Owner: plaisthos <arn...@rf...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Comment-Date: Tue, 22 Jul 2025 14:59:07 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: Yes Gerrit-MessageType: comment |
From: plaisthos (C. Review) <ge...@op...> - 2025-07-28 11:51:34
|
Attention is currently required from: flichtenheld, plaisthos. Hello flichtenheld, I'd like you to reexamine a change. Please visit http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email to look at the new patch set (#4). The following approvals got outdated and were removed: Code-Review-1 by flichtenheld Change subject: Check message id/acked ids too when doing sessionid cookie checks ...................................................................... Check message id/acked ids too when doing sessionid cookie checks This fixes that control packets on a floating client can trigger creating a new session in special circumstances: To trigger this circumstance a connection needs to - starts on IP A - successfully floats to IP B by data packet - then has a control packet from IP A before any data packet can trigger the float back to IP A and all of this needs to happen in the 60s time that hmac cookie is valid in the default configuration. In this scenario we would trigger a new connection as the HMAC session id would be valid. This patch adds checking also of the message-id and acked ids to discern packet from the initial three-way handshake where these ids 0 or 1 from any later packet. This will now trigger (at verb 4 or higher) a messaged like: Packet (P_ACK_V1) with invalid or missing SID instead. Also remove a few duplicated free_tls_pre_decrypt_state in test_ssl. Reported-By: Walter Doekes <wal...@wj...> Tested-By: Walter Doekes <wal...@wj...> Change-Id: I6752dcd5aff3e5cea2b439366479e86751a1c403 Signed-off-by: Arne Schwabe <ar...@rf...> --- M src/openvpn/mudp.c M src/openvpn/ssl_pkt.c M src/openvpn/ssl_pkt.h M tests/unit_tests/openvpn/test_pkt.c 4 files changed, 113 insertions(+), 12 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/67/1067/4 diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c index 93e65e0..9cd667c 100644 --- a/src/openvpn/mudp.c +++ b/src/openvpn/mudp.c @@ -63,7 +63,6 @@ msg(D_MULTI_DEBUG, "Reset packet from client, sending HMAC based reset challenge"); } - /* Returns true if this packet should create a new session */ static bool do_pre_decrypt_check(struct multi_context *m, @@ -155,7 +154,8 @@ * need to contain the peer id */ struct gc_arena gc = gc_new(); - bool ret = check_session_id_hmac(state, from, hmac, handwindow); + bool pkt_is_ack = (verdict == VERDICT_VALID_ACK_V1); + bool ret = check_session_id_hmac(state, from, hmac, handwindow, pkt_is_ack); const char *peer = print_link_socket_actual(&m->top.c2.from, &gc); uint8_t pkt_firstbyte = *BPTR( &m->top.c2.buf); @@ -171,6 +171,7 @@ msg(D_MULTI_DEBUG, "Valid packet (%s) with HMAC challenge from peer (%s), " "accepting new connection.", packet_opcode_name(op), peer); } + gc_free(&gc); return ret; diff --git a/src/openvpn/ssl_pkt.c b/src/openvpn/ssl_pkt.c index bfd405f..0bbc465 100644 --- a/src/openvpn/ssl_pkt.c +++ b/src/openvpn/ssl_pkt.c @@ -293,6 +293,7 @@ } } + /* * This function is similar to tls_pre_decrypt, except it is called * when we are in server mode and receive an initial incoming @@ -530,7 +531,8 @@ check_session_id_hmac(struct tls_pre_decrypt_state *state, const struct openvpn_sockaddr *from, hmac_ctx_t *hmac, - int handwindow) + int handwindow, + bool pkt_is_ack) { if (!from) { @@ -545,6 +547,36 @@ return false; } + /* Check if the packet ID of the packet or ACKED packet is <= 1 */ + for (int i = 0; i < ack.len; i++) + { + /* This packet ACKs a packet that has a higher packet id than the + * ones expected in the three-way handshake, consider it as invalid + * for the session */ + if (ack.packet_id[i] > 1) + { + return false; + } + } + + if (!pkt_is_ack) + { + packet_id_type message_id; + /* Extract the packet ID from the packet */ + if (!reliable_ack_read_packet_id(&buf, &message_id)) + { + return false; + } + + /* similar check. Anything larger than 1 is not considered part of the + * three-way handshake */ + if (message_id > 1) + { + return false; + } + } + + /* check adjacent timestamps too */ for (int offset = -2; offset <= 1; offset++) { diff --git a/src/openvpn/ssl_pkt.h b/src/openvpn/ssl_pkt.h index 98a39d3..1b6bcc0 100644 --- a/src/openvpn/ssl_pkt.h +++ b/src/openvpn/ssl_pkt.h @@ -180,17 +180,24 @@ /** * Checks if a control packet has a correct HMAC server session id * + * This will also consider packets that have a packet id higher + * than 1 or ack packets higher than 1 to be invalid as they are + * not part of the initial three way handshake of OpenVPN and should + * not create a new connection. + * * @param state session information * @param from link_socket from the client * @param hmac the hmac context to use for the calculation * @param handwindow the quantisation of the current time + * @param pkt_is_ack the packet being checked is a P_ACK_V1 * @return the expected server session id */ bool check_session_id_hmac(struct tls_pre_decrypt_state *state, const struct openvpn_sockaddr *from, hmac_ctx_t *hmac, - int handwindow); + int handwindow, + bool pkt_is_ack); /* * Write a control channel authentication record. diff --git a/tests/unit_tests/openvpn/test_pkt.c b/tests/unit_tests/openvpn/test_pkt.c index ebffabe..f771a10 100644 --- a/tests/unit_tests/openvpn/test_pkt.c +++ b/tests/unit_tests/openvpn/test_pkt.c @@ -170,6 +170,27 @@ 0x85, 0xdb, 0x53, 0x56, 0x23, 0xb0, 0x2e }; +/* no tls-auth, P_ACK_V1, acks 0,1, and 2 */ +const uint8_t client_ack_123_none_random_id[] = { + 0x28, + 0xae, 0xb9, 0xaf, 0xe1, 0xf0, 0x1d, 0x79, 0xc8, + 0x03, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x02, + 0xdd, 0x85, 0xdb, 0x53, 0x56, 0x23, 0xb0, 0x2e +}; + +/* no tls-auth, P_CONTROL_V1, acks 0, msg-id 2 */ +const uint8_t client_control_none_random_id[] = { + 0x20, + 0xae, 0xb9, 0xaf, 0xe1, 0xf0, 0x1d, 0x79, 0xc8, + 0x01, + 0x00, 0x00, 0x00, 0x00, + 0x02 +}; + + struct tls_auth_standalone init_tas_auth(int key_direction) { @@ -290,12 +311,10 @@ assert_int_equal(verdict, VERDICT_VALID_RESET_V2); free_tls_pre_decrypt_state(&state); - free_tls_pre_decrypt_state(&state); /* The pre decrypt function should not modify the buffer, so calling it * again should have the same result */ verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); assert_int_equal(verdict, VERDICT_VALID_RESET_V2); - free_tls_pre_decrypt_state(&state); /* and buf memory should be equal */ assert_memory_equal(BPTR(&buf), client_reset_v2_tls_auth, sizeof(client_reset_v2_tls_auth)); @@ -313,7 +332,6 @@ assert_int_equal(verdict, VERDICT_INVALID); free_tls_pre_decrypt_state(&state); - free_tls_pre_decrypt_state(&state); /* Wrong key direction gives a wrong hmac key and should not validate */ free_key_ctx_bi(&tas.tls_wrap.opt.key_ctx_bi); free_tas(&tas); @@ -353,15 +371,12 @@ assert_int_equal(verdict, VERDICT_VALID_RESET_V2); free_tls_pre_decrypt_state(&state); - free_tls_pre_decrypt_state(&state); buf_reset_len(&buf); buf_write(&buf, client_reset_v2_tls_crypt, sizeof(client_reset_v2_none)); verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); assert_int_equal(verdict, VERDICT_VALID_RESET_V2); free_tls_pre_decrypt_state(&state); - free_tls_pre_decrypt_state(&state); - /* This is not a reset packet and should trigger the other response */ buf_reset_len(&buf); buf_write(&buf, client_ack_tls_auth_randomid, sizeof(client_ack_tls_auth_randomid)); @@ -439,7 +454,7 @@ assert_int_equal(verdict, VERDICT_VALID_CONTROL_V1); /* This is a valid packet but containing a random id instead of an HMAC id*/ - bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30); + bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30, false); assert_false(valid); free_tls_pre_decrypt_state(&state); @@ -470,7 +485,7 @@ verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); assert_int_equal(verdict, VERDICT_VALID_ACK_V1); - bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30); + bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30, true); assert_true(valid); free_tls_pre_decrypt_state(&state); @@ -479,6 +494,51 @@ hmac_ctx_free(hmac); } +static void +test_verify_hmac_none_out_of_range_ack(void **ut_state) +{ + hmac_ctx_t *hmac = session_id_hmac_init(); + + struct link_socket_actual from = { 0 }; + from.dest.addr.sa.sa_family = AF_INET; + + struct tls_auth_standalone tas = { 0 }; + struct tls_pre_decrypt_state state = { 0 }; + + struct buffer buf = alloc_buf(1024); + enum first_packet_verdict verdict; + + tas.tls_wrap.mode = TLS_WRAP_NONE; + + buf_reset_len(&buf); + buf_write(&buf, client_ack_123_none_random_id, sizeof(client_ack_123_none_random_id)); + + + verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); + assert_int_equal(verdict, VERDICT_VALID_ACK_V1); + + /* should fail because it acks 2 */ + bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30, true); + assert_false(valid); + free_tls_pre_decrypt_state(&state); + + /* Try test with the control with a too high message id now */ + buf_reset_len(&buf); + buf_write(&buf, client_control_none_random_id, sizeof(client_control_none_random_id)); + + verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); + assert_int_equal(verdict, VERDICT_VALID_CONTROL_V1); + + /* should fail because it has message id 2 */ + valid = check_session_id_hmac(&state, &from.dest, hmac, 30, true); + assert_false(valid); + + free_tls_pre_decrypt_state(&state); + free_buf(&buf); + hmac_ctx_cleanup(hmac); + hmac_ctx_free(hmac); +} + static hmac_ctx_t * init_static_hmac(void) { @@ -667,6 +727,7 @@ cmocka_unit_test(test_calc_session_id_hmac_static), cmocka_unit_test(test_verify_hmac_none), cmocka_unit_test(test_verify_hmac_tls_auth), + cmocka_unit_test(test_verify_hmac_none_out_of_range_ack), cmocka_unit_test(test_generate_reset_packet_plain), cmocka_unit_test(test_generate_reset_packet_tls_auth), cmocka_unit_test(test_extract_control_message) -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I6752dcd5aff3e5cea2b439366479e86751a1c403 Gerrit-Change-Number: 1067 Gerrit-PatchSet: 4 Gerrit-Owner: plaisthos <arn...@rf...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-MessageType: newpatchset |
From: plaisthos (C. Review) <ge...@op...> - 2025-08-06 12:23:34
|
Attention is currently required from: flichtenheld, plaisthos. Hello flichtenheld, I'd like you to reexamine a change. Please visit http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email to look at the new patch set (#5). Change subject: Check message id/acked ids too when doing sessionid cookie checks ...................................................................... Check message id/acked ids too when doing sessionid cookie checks This fixes that control packets on a floating client can trigger creating a new session in special circumstances: To trigger this circumstance a connection needs to - starts on IP A - successfully floats to IP B by data packet - then has a control packet from IP A before any data packet can trigger the float back to IP A and all of this needs to happen in the 60s time that hmac cookie is valid in the default configuration. In this scenario we would trigger a new connection as the HMAC session id would be valid. This patch adds checking also of the message-id and acked ids to discern packet from the initial three-way handshake where these ids 0 or 1 from any later packet. This will now trigger (at verb 4 or higher) a messaged like: Packet (P_ACK_V1) with invalid or missing SID instead. Also remove a few duplicated free_tls_pre_decrypt_state in test_ssl. Reported-By: Walter Doekes <wal...@wj...> Tested-By: Walter Doekes <wal...@wj...> Change-Id: I6752dcd5aff3e5cea2b439366479e86751a1c403 Signed-off-by: Arne Schwabe <ar...@rf...> --- M src/openvpn/mudp.c M src/openvpn/ssl_pkt.c M src/openvpn/ssl_pkt.h M tests/unit_tests/openvpn/test_pkt.c 4 files changed, 126 insertions(+), 22 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/67/1067/5 diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c index 7259a4b..0f22821 100644 --- a/src/openvpn/mudp.c +++ b/src/openvpn/mudp.c @@ -151,7 +151,8 @@ * need to contain the peer id */ struct gc_arena gc = gc_new(); - bool ret = check_session_id_hmac(state, from, hmac, handwindow); + bool pkt_is_ack = (verdict == VERDICT_VALID_ACK_V1); + bool ret = check_session_id_hmac(state, from, hmac, handwindow, pkt_is_ack); const char *peer = print_link_socket_actual(&m->top.c2.from, &gc); uint8_t pkt_firstbyte = *BPTR(&m->top.c2.buf); diff --git a/src/openvpn/ssl_pkt.c b/src/openvpn/ssl_pkt.c index b901f87..ddb3a15 100644 --- a/src/openvpn/ssl_pkt.c +++ b/src/openvpn/ssl_pkt.c @@ -496,8 +496,11 @@ } bool -check_session_id_hmac(struct tls_pre_decrypt_state *state, const struct openvpn_sockaddr *from, - hmac_ctx_t *hmac, int handwindow) +check_session_id_hmac(struct tls_pre_decrypt_state *state, + const struct openvpn_sockaddr *from, + hmac_ctx_t *hmac, + int handwindow, + bool pkt_is_ack) { if (!from) { @@ -512,6 +515,36 @@ return false; } + /* Check if the packet ID of the packet or ACKED packet is <= 1 */ + for (int i = 0; i < ack.len; i++) + { + /* This packet ACKs a packet that has a higher packet id than the + * ones expected in the three-way handshake, consider it as invalid + * for the session */ + if (ack.packet_id[i] > 1) + { + return false; + } + } + + if (!pkt_is_ack) + { + packet_id_type message_id; + /* Extract the packet ID from the packet */ + if (!reliable_ack_read_packet_id(&buf, &message_id)) + { + return false; + } + + /* similar check. Anything larger than 1 is not considered part of the + * three-way handshake */ + if (message_id > 1) + { + return false; + } + } + + /* check adjacent timestamps too */ for (int offset = -2; offset <= 1; offset++) { diff --git a/src/openvpn/ssl_pkt.h b/src/openvpn/ssl_pkt.h index 8fe4880..2933109 100644 --- a/src/openvpn/ssl_pkt.h +++ b/src/openvpn/ssl_pkt.h @@ -178,14 +178,20 @@ /** * Checks if a control packet has a correct HMAC server session id * + * This will also consider packets that have a packet id higher + * than 1 or ack packets higher than 1 to be invalid as they are + * not part of the initial three way handshake of OpenVPN and should + * not create a new connection. + * * @param state session information * @param from link_socket from the client * @param hmac the hmac context to use for the calculation * @param handwindow the quantisation of the current time + * @param pkt_is_ack the packet being checked is a P_ACK_V1 * @return the expected server session id */ bool check_session_id_hmac(struct tls_pre_decrypt_state *state, const struct openvpn_sockaddr *from, - hmac_ctx_t *hmac, int handwindow); + hmac_ctx_t *hmac, int handwindow, bool pkt_is_ack); /* * Write a control channel authentication record. diff --git a/tests/unit_tests/openvpn/test_pkt.c b/tests/unit_tests/openvpn/test_pkt.c index 65b31e7..a58e121 100644 --- a/tests/unit_tests/openvpn/test_pkt.c +++ b/tests/unit_tests/openvpn/test_pkt.c @@ -139,6 +139,27 @@ 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0xdd, 0x85, 0xdb, 0x53, 0x56, 0x23, 0xb0, 0x2e }; +/* no tls-auth, P_ACK_V1, acks 0,1, and 2 */ +const uint8_t client_ack_123_none_random_id[] = { + 0x28, + 0xae, 0xb9, 0xaf, 0xe1, 0xf0, 0x1d, 0x79, 0xc8, + 0x03, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x02, + 0xdd, 0x85, 0xdb, 0x53, 0x56, 0x23, 0xb0, 0x2e +}; + +/* no tls-auth, P_CONTROL_V1, acks 0, msg-id 2 */ +const uint8_t client_control_none_random_id[] = { + 0x20, + 0xae, 0xb9, 0xaf, 0xe1, 0xf0, 0x1d, 0x79, 0xc8, + 0x01, + 0x00, 0x00, 0x00, 0x00, + 0x02 +}; + + struct tls_auth_standalone init_tas_auth(int key_direction) { @@ -256,12 +277,10 @@ assert_int_equal(verdict, VERDICT_VALID_RESET_V2); free_tls_pre_decrypt_state(&state); - free_tls_pre_decrypt_state(&state); /* The pre decrypt function should not modify the buffer, so calling it * again should have the same result */ verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); assert_int_equal(verdict, VERDICT_VALID_RESET_V2); - free_tls_pre_decrypt_state(&state); /* and buf memory should be equal */ assert_memory_equal(BPTR(&buf), client_reset_v2_tls_auth, sizeof(client_reset_v2_tls_auth)); @@ -279,7 +298,6 @@ assert_int_equal(verdict, VERDICT_INVALID); free_tls_pre_decrypt_state(&state); - free_tls_pre_decrypt_state(&state); /* Wrong key direction gives a wrong hmac key and should not validate */ free_key_ctx_bi(&tas.tls_wrap.opt.key_ctx_bi); free_tas(&tas); @@ -319,15 +337,12 @@ assert_int_equal(verdict, VERDICT_VALID_RESET_V2); free_tls_pre_decrypt_state(&state); - free_tls_pre_decrypt_state(&state); buf_reset_len(&buf); buf_write(&buf, client_reset_v2_tls_crypt, sizeof(client_reset_v2_none)); verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); assert_int_equal(verdict, VERDICT_VALID_RESET_V2); free_tls_pre_decrypt_state(&state); - free_tls_pre_decrypt_state(&state); - /* This is not a reset packet and should trigger the other response */ buf_reset_len(&buf); buf_write(&buf, client_ack_tls_auth_randomid, sizeof(client_ack_tls_auth_randomid)); @@ -405,7 +420,7 @@ assert_int_equal(verdict, VERDICT_VALID_CONTROL_V1); /* This is a valid packet but containing a random id instead of an HMAC id*/ - bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30); + bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30, false); assert_false(valid); free_tls_pre_decrypt_state(&state); @@ -436,7 +451,7 @@ verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); assert_int_equal(verdict, VERDICT_VALID_ACK_V1); - bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30); + bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30, true); assert_true(valid); free_tls_pre_decrypt_state(&state); @@ -445,6 +460,51 @@ hmac_ctx_free(hmac); } +static void +test_verify_hmac_none_out_of_range_ack(void **ut_state) +{ + hmac_ctx_t *hmac = session_id_hmac_init(); + + struct link_socket_actual from = { 0 }; + from.dest.addr.sa.sa_family = AF_INET; + + struct tls_auth_standalone tas = { 0 }; + struct tls_pre_decrypt_state state = { 0 }; + + struct buffer buf = alloc_buf(1024); + enum first_packet_verdict verdict; + + tas.tls_wrap.mode = TLS_WRAP_NONE; + + buf_reset_len(&buf); + buf_write(&buf, client_ack_123_none_random_id, sizeof(client_ack_123_none_random_id)); + + + verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); + assert_int_equal(verdict, VERDICT_VALID_ACK_V1); + + /* should fail because it acks 2 */ + bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30, true); + assert_false(valid); + free_tls_pre_decrypt_state(&state); + + /* Try test with the control with a too high message id now */ + buf_reset_len(&buf); + buf_write(&buf, client_control_none_random_id, sizeof(client_control_none_random_id)); + + verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); + assert_int_equal(verdict, VERDICT_VALID_CONTROL_V1); + + /* should fail because it has message id 2 */ + valid = check_session_id_hmac(&state, &from.dest, hmac, 30, true); + assert_false(valid); + + free_tls_pre_decrypt_state(&state); + free_buf(&buf); + hmac_ctx_cleanup(hmac); + hmac_ctx_free(hmac); +} + static hmac_ctx_t * init_static_hmac(void) { @@ -634,16 +694,20 @@ main(void) { openvpn_unit_test_setup(); - const struct CMUnitTest tests[] = { cmocka_unit_test(test_tls_decrypt_lite_none), - cmocka_unit_test(test_tls_decrypt_lite_auth), - cmocka_unit_test(test_tls_decrypt_lite_crypt), - cmocka_unit_test(test_parse_ack), - cmocka_unit_test(test_calc_session_id_hmac_static), - cmocka_unit_test(test_verify_hmac_none), - cmocka_unit_test(test_verify_hmac_tls_auth), - cmocka_unit_test(test_generate_reset_packet_plain), - cmocka_unit_test(test_generate_reset_packet_tls_auth), - cmocka_unit_test(test_extract_control_message) }; + + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_tls_decrypt_lite_none), + cmocka_unit_test(test_tls_decrypt_lite_auth), + cmocka_unit_test(test_tls_decrypt_lite_crypt), + cmocka_unit_test(test_parse_ack), + cmocka_unit_test(test_calc_session_id_hmac_static), + cmocka_unit_test(test_verify_hmac_none), + cmocka_unit_test(test_verify_hmac_tls_auth), + cmocka_unit_test(test_verify_hmac_none_out_of_range_ack), + cmocka_unit_test(test_generate_reset_packet_plain), + cmocka_unit_test(test_generate_reset_packet_tls_auth), + cmocka_unit_test(test_extract_control_message) + }; #if defined(ENABLE_CRYPTO_OPENSSL) OpenSSL_add_all_algorithms(); -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I6752dcd5aff3e5cea2b439366479e86751a1c403 Gerrit-Change-Number: 1067 Gerrit-PatchSet: 5 Gerrit-Owner: plaisthos <arn...@rf...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-MessageType: newpatchset |
From: plaisthos (C. Review) <ge...@op...> - 2025-08-06 12:26:13
|
Attention is currently required from: flichtenheld. plaisthos has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email ) Change subject: Check message id/acked ids too when doing sessionid cookie checks ...................................................................... Patch Set 5: (1 comment) File tests/unit_tests/openvpn/test_pkt.c: http://gerrit.openvpn.net/c/openvpn/+/1067/comment/95234b5f_2bb8c6f6 : PS3, Line 533: > Looking at the LeakSanitizer failure and the other test cases I think there is a `free_tls_pre_decry […] Done -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I6752dcd5aff3e5cea2b439366479e86751a1c403 Gerrit-Change-Number: 1067 Gerrit-PatchSet: 5 Gerrit-Owner: plaisthos <arn...@rf...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-Comment-Date: Wed, 06 Aug 2025 12:25:58 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: No Comment-In-Reply-To: flichtenheld <fr...@li...> Gerrit-MessageType: comment |
From: MaxF (C. Review) <ge...@op...> - 2025-08-13 14:01:49
|
Attention is currently required from: flichtenheld, plaisthos. MaxF has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email ) Change subject: Check message id/acked ids too when doing sessionid cookie checks ...................................................................... Patch Set 5: (3 comments) Patchset: PS5: The change makes sense to me, just some small nitpicks. If you strongly prefer doing it this way, I'm willing to approve. File src/openvpn/mudp.c: http://gerrit.openvpn.net/c/openvpn/+/1067/comment/b8f6989e_8a8a01d2 : PS5, Line 163: msg(D_MULTI_MEDIUM, "Packet (%s) with invalid or missing SID from %s", : packet_opcode_name(op), peer); This debug message may now be incorrect. The packet might have a valid SID, but a wrong packet ID. File src/openvpn/ssl_pkt.c: http://gerrit.openvpn.net/c/openvpn/+/1067/comment/3d6e4bec_68a33598 : PS5, Line 518: /* Check if the packet ID of the packet or ACKED packet is <= 1 */ : for (int i = 0; i < ack.len; i++) : { : /* This packet ACKs a packet that has a higher packet id than the : * ones expected in the three-way handshake, consider it as invalid : * for the session */ : if (ack.packet_id[i] > 1) : { : return false; : } : } : : if (!pkt_is_ack) : { : packet_id_type message_id; : /* Extract the packet ID from the packet */ : if (!reliable_ack_read_packet_id(&buf, &message_id)) : { : return false; : } : : /* similar check. Anything larger than 1 is not considered part of the : * three-way handshake */ : if (message_id > 1) : { : return false; : } : } Maybe nitpicky, but this seems like scope creep for this function. Now check_session_id_hmac() does more than checking the hmac. I'd prefer to extract this check to its own function, or rename this one. -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I6752dcd5aff3e5cea2b439366479e86751a1c403 Gerrit-Change-Number: 1067 Gerrit-PatchSet: 5 Gerrit-Owner: plaisthos <arn...@rf...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-CC: MaxF <ma...@ma...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-Comment-Date: Wed, 13 Aug 2025 14:01:34 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: No Gerrit-MessageType: comment |
From: plaisthos (C. Review) <ge...@op...> - 2025-08-15 13:59:05
|
Attention is currently required from: flichtenheld, plaisthos. Hello flichtenheld, I'd like you to reexamine a change. Please visit http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email to look at the new patch set (#6). Change subject: Check message id/acked ids too when doing sessionid cookie checks ...................................................................... Check message id/acked ids too when doing sessionid cookie checks This fixes that control packets on a floating client can trigger creating a new session in special circumstances: To trigger this circumstance a connection needs to - starts on IP A - successfully floats to IP B by data packet - then has a control packet from IP A before any data packet can trigger the float back to IP A and all of this needs to happen in the 60s time that hmac cookie is valid in the default configuration. In this scenario we would trigger a new connection as the HMAC session id would be valid. This patch adds checking also of the message-id and acked ids to discern packet from the initial three-way handshake where these ids 0 or 1 from any later packet. This will now trigger (at verb 4 or higher) a messaged like: Packet (P_ACK_V1) with invalid or missing SID instead. Also remove a few duplicated free_tls_pre_decrypt_state in test_ssl. Reported-By: Walter Doekes <wal...@wj...> Tested-By: Walter Doekes <wal...@wj...> Change-Id: I6752dcd5aff3e5cea2b439366479e86751a1c403 Signed-off-by: Arne Schwabe <ar...@rf...> --- M src/openvpn/mudp.c M src/openvpn/ssl_pkt.c M src/openvpn/ssl_pkt.h M tests/unit_tests/openvpn/test_pkt.c 4 files changed, 129 insertions(+), 24 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/67/1067/6 diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c index 7259a4b..31134be 100644 --- a/src/openvpn/mudp.c +++ b/src/openvpn/mudp.c @@ -151,7 +151,8 @@ * need to contain the peer id */ struct gc_arena gc = gc_new(); - bool ret = check_session_id_hmac(state, from, hmac, handwindow); + bool pkt_is_ack = (verdict == VERDICT_VALID_ACK_V1); + bool ret = check_session_hmac_and_pkt_id(state, from, hmac, handwindow, pkt_is_ack); const char *peer = print_link_socket_actual(&m->top.c2.from, &gc); uint8_t pkt_firstbyte = *BPTR(&m->top.c2.buf); @@ -159,7 +160,8 @@ if (!ret) { - msg(D_MULTI_MEDIUM, "Packet (%s) with invalid or missing SID from %s", + msg(D_MULTI_MEDIUM, "Packet (%s) with invalid or missing SID from" + " %s or wrong packet id", packet_opcode_name(op), peer); } else diff --git a/src/openvpn/ssl_pkt.c b/src/openvpn/ssl_pkt.c index b901f87..6ec05a7 100644 --- a/src/openvpn/ssl_pkt.c +++ b/src/openvpn/ssl_pkt.c @@ -496,8 +496,11 @@ } bool -check_session_id_hmac(struct tls_pre_decrypt_state *state, const struct openvpn_sockaddr *from, - hmac_ctx_t *hmac, int handwindow) +check_session_hmac_and_pkt_id(struct tls_pre_decrypt_state *state, + const struct openvpn_sockaddr *from, + hmac_ctx_t *hmac, + int handwindow, + bool pkt_is_ack) { if (!from) { @@ -512,6 +515,36 @@ return false; } + /* Check if the packet ID of the packet or ACKED packet is <= 1 */ + for (int i = 0; i < ack.len; i++) + { + /* This packet ACKs a packet that has a higher packet id than the + * ones expected in the three-way handshake, consider it as invalid + * for the session */ + if (ack.packet_id[i] > 1) + { + return false; + } + } + + if (!pkt_is_ack) + { + packet_id_type message_id; + /* Extract the packet ID from the packet */ + if (!reliable_ack_read_packet_id(&buf, &message_id)) + { + return false; + } + + /* similar check. Anything larger than 1 is not considered part of the + * three-way handshake */ + if (message_id > 1) + { + return false; + } + } + + /* check adjacent timestamps too */ for (int offset = -2; offset <= 1; offset++) { diff --git a/src/openvpn/ssl_pkt.h b/src/openvpn/ssl_pkt.h index 8fe4880..96cdd68 100644 --- a/src/openvpn/ssl_pkt.h +++ b/src/openvpn/ssl_pkt.h @@ -178,14 +178,20 @@ /** * Checks if a control packet has a correct HMAC server session id * + * This will also consider packets that have a packet id higher + * than 1 or ack packets higher than 1 to be invalid as they are + * not part of the initial three way handshake of OpenVPN and should + * not create a new connection. + * * @param state session information * @param from link_socket from the client * @param hmac the hmac context to use for the calculation * @param handwindow the quantisation of the current time + * @param pkt_is_ack the packet being checked is a P_ACK_V1 * @return the expected server session id */ -bool check_session_id_hmac(struct tls_pre_decrypt_state *state, const struct openvpn_sockaddr *from, - hmac_ctx_t *hmac, int handwindow); +bool check_session_hmac_and_pkt_id(struct tls_pre_decrypt_state *state, const struct openvpn_sockaddr *from, + hmac_ctx_t *hmac, int handwindow, bool pkt_is_ack); /* * Write a control channel authentication record. diff --git a/tests/unit_tests/openvpn/test_pkt.c b/tests/unit_tests/openvpn/test_pkt.c index 65b31e7..5122766 100644 --- a/tests/unit_tests/openvpn/test_pkt.c +++ b/tests/unit_tests/openvpn/test_pkt.c @@ -139,6 +139,27 @@ 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0xdd, 0x85, 0xdb, 0x53, 0x56, 0x23, 0xb0, 0x2e }; +/* no tls-auth, P_ACK_V1, acks 0,1, and 2 */ +const uint8_t client_ack_123_none_random_id[] = { + 0x28, + 0xae, 0xb9, 0xaf, 0xe1, 0xf0, 0x1d, 0x79, 0xc8, + 0x03, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x02, + 0xdd, 0x85, 0xdb, 0x53, 0x56, 0x23, 0xb0, 0x2e +}; + +/* no tls-auth, P_CONTROL_V1, acks 0, msg-id 2 */ +const uint8_t client_control_none_random_id[] = { + 0x20, + 0xae, 0xb9, 0xaf, 0xe1, 0xf0, 0x1d, 0x79, 0xc8, + 0x01, + 0x00, 0x00, 0x00, 0x00, + 0x02 +}; + + struct tls_auth_standalone init_tas_auth(int key_direction) { @@ -256,12 +277,10 @@ assert_int_equal(verdict, VERDICT_VALID_RESET_V2); free_tls_pre_decrypt_state(&state); - free_tls_pre_decrypt_state(&state); /* The pre decrypt function should not modify the buffer, so calling it * again should have the same result */ verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); assert_int_equal(verdict, VERDICT_VALID_RESET_V2); - free_tls_pre_decrypt_state(&state); /* and buf memory should be equal */ assert_memory_equal(BPTR(&buf), client_reset_v2_tls_auth, sizeof(client_reset_v2_tls_auth)); @@ -279,7 +298,6 @@ assert_int_equal(verdict, VERDICT_INVALID); free_tls_pre_decrypt_state(&state); - free_tls_pre_decrypt_state(&state); /* Wrong key direction gives a wrong hmac key and should not validate */ free_key_ctx_bi(&tas.tls_wrap.opt.key_ctx_bi); free_tas(&tas); @@ -319,15 +337,12 @@ assert_int_equal(verdict, VERDICT_VALID_RESET_V2); free_tls_pre_decrypt_state(&state); - free_tls_pre_decrypt_state(&state); buf_reset_len(&buf); buf_write(&buf, client_reset_v2_tls_crypt, sizeof(client_reset_v2_none)); verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); assert_int_equal(verdict, VERDICT_VALID_RESET_V2); free_tls_pre_decrypt_state(&state); - free_tls_pre_decrypt_state(&state); - /* This is not a reset packet and should trigger the other response */ buf_reset_len(&buf); buf_write(&buf, client_ack_tls_auth_randomid, sizeof(client_ack_tls_auth_randomid)); @@ -405,7 +420,7 @@ assert_int_equal(verdict, VERDICT_VALID_CONTROL_V1); /* This is a valid packet but containing a random id instead of an HMAC id*/ - bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30); + bool valid = check_session_hmac_and_pkt_id(&state, &from.dest, hmac, 30, false); assert_false(valid); free_tls_pre_decrypt_state(&state); @@ -436,7 +451,7 @@ verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); assert_int_equal(verdict, VERDICT_VALID_ACK_V1); - bool valid = check_session_id_hmac(&state, &from.dest, hmac, 30); + bool valid = check_session_hmac_and_pkt_id(&state, &from.dest, hmac, 30, true); assert_true(valid); free_tls_pre_decrypt_state(&state); @@ -445,6 +460,51 @@ hmac_ctx_free(hmac); } +static void +test_verify_hmac_none_out_of_range_ack(void **ut_state) +{ + hmac_ctx_t *hmac = session_id_hmac_init(); + + struct link_socket_actual from = { 0 }; + from.dest.addr.sa.sa_family = AF_INET; + + struct tls_auth_standalone tas = { 0 }; + struct tls_pre_decrypt_state state = { 0 }; + + struct buffer buf = alloc_buf(1024); + enum first_packet_verdict verdict; + + tas.tls_wrap.mode = TLS_WRAP_NONE; + + buf_reset_len(&buf); + buf_write(&buf, client_ack_123_none_random_id, sizeof(client_ack_123_none_random_id)); + + + verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); + assert_int_equal(verdict, VERDICT_VALID_ACK_V1); + + /* should fail because it acks 2 */ + bool valid = check_session_hmac_and_pkt_id(&state, &from.dest, hmac, 30, true); + assert_false(valid); + free_tls_pre_decrypt_state(&state); + + /* Try test with the control with a too high message id now */ + buf_reset_len(&buf); + buf_write(&buf, client_control_none_random_id, sizeof(client_control_none_random_id)); + + verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); + assert_int_equal(verdict, VERDICT_VALID_CONTROL_V1); + + /* should fail because it has message id 2 */ + valid = check_session_hmac_and_pkt_id(&state, &from.dest, hmac, 30, true); + assert_false(valid); + + free_tls_pre_decrypt_state(&state); + free_buf(&buf); + hmac_ctx_cleanup(hmac); + hmac_ctx_free(hmac); +} + static hmac_ctx_t * init_static_hmac(void) { @@ -634,16 +694,20 @@ main(void) { openvpn_unit_test_setup(); - const struct CMUnitTest tests[] = { cmocka_unit_test(test_tls_decrypt_lite_none), - cmocka_unit_test(test_tls_decrypt_lite_auth), - cmocka_unit_test(test_tls_decrypt_lite_crypt), - cmocka_unit_test(test_parse_ack), - cmocka_unit_test(test_calc_session_id_hmac_static), - cmocka_unit_test(test_verify_hmac_none), - cmocka_unit_test(test_verify_hmac_tls_auth), - cmocka_unit_test(test_generate_reset_packet_plain), - cmocka_unit_test(test_generate_reset_packet_tls_auth), - cmocka_unit_test(test_extract_control_message) }; + + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_tls_decrypt_lite_none), + cmocka_unit_test(test_tls_decrypt_lite_auth), + cmocka_unit_test(test_tls_decrypt_lite_crypt), + cmocka_unit_test(test_parse_ack), + cmocka_unit_test(test_calc_session_id_hmac_static), + cmocka_unit_test(test_verify_hmac_none), + cmocka_unit_test(test_verify_hmac_tls_auth), + cmocka_unit_test(test_verify_hmac_none_out_of_range_ack), + cmocka_unit_test(test_generate_reset_packet_plain), + cmocka_unit_test(test_generate_reset_packet_tls_auth), + cmocka_unit_test(test_extract_control_message) + }; #if defined(ENABLE_CRYPTO_OPENSSL) OpenSSL_add_all_algorithms(); -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1067?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I6752dcd5aff3e5cea2b439366479e86751a1c403 Gerrit-Change-Number: 1067 Gerrit-PatchSet: 6 Gerrit-Owner: plaisthos <arn...@rf...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-CC: MaxF <ma...@ma...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-MessageType: newpatchset |