2020#include "crypto/s2n_ecc_evp.h"
2121#include "stuffer/s2n_stuffer.h"
2222#include "testlib/s2n_testlib.h"
23+ #include "tls/s2n_connection.h"
24+ #include "tls/s2n_security_policies.h"
2325#include "utils/s2n_mem.h"
2426
2527#define ECDHE_PARAMS_LEGACY_FORM 4
2628
29+ extern const struct s2n_ecc_named_curve s2n_unsupported_curve ;
30+
2731int main (int argc , char * * argv ) {
2832 BEGIN_TEST ();
2933 EXPECT_SUCCESS (s2n_disable_tls13_in_test ());
@@ -89,7 +93,7 @@ int main(int argc, char **argv) {
8993 }
9094 {
9195 /* Test failure case for computing shared key for all supported curves when the server
92- and client curves donot match */
96+ and client curves do not match */
9397 for (int i = 0 ; i < s2n_all_supported_curves_list_len ; i ++ ) {
9498 for (int j = 0 ; j < s2n_all_supported_curves_list_len ; j ++ ) {
9599 struct s2n_ecc_evp_params server_params = {0 };
@@ -216,6 +220,10 @@ int main(int argc, char **argv) {
216220 }
217221 }
218222 {
223+ DEFER_CLEANUP (struct s2n_connection * conn = s2n_connection_new (S2N_CLIENT ),
224+ s2n_connection_ptr_free );
225+ EXPECT_NOT_NULL (conn );
226+ EXPECT_SUCCESS (s2n_connection_set_cipher_preferences (conn , "test_all" ));
219227 /* Test read/write/parse params for all supported curves */
220228 for (int i = 0 ; i < s2n_all_supported_curves_list_len ; i ++ ) {
221229 struct s2n_ecc_evp_params write_params = {0 };
@@ -238,23 +246,26 @@ int main(int argc, char **argv) {
238246
239247 /* Read params points from the wire */
240248 EXPECT_SUCCESS (s2n_ecc_evp_read_params (& wire , & ecdh_params_received , & ecdhe_data ));
241- EXPECT_SUCCESS (s2n_ecc_evp_parse_params (& ecdhe_data , & read_params ));
249+ EXPECT_SUCCESS (s2n_ecc_evp_parse_params (conn , & ecdhe_data , & read_params ));
242250
243251 /* Check that the point we read is the same we wrote */
244252 EXPECT_TRUE (EVP_PKEY_cmp (write_params .evp_pkey , read_params .evp_pkey ));
245253
246- /* Clean up */
254+ /* Clean up */
247255 EXPECT_SUCCESS (s2n_stuffer_free (& wire ));
248256 EXPECT_SUCCESS (s2n_ecc_evp_params_free (& write_params ));
249257 EXPECT_SUCCESS (s2n_ecc_evp_params_free (& read_params ));
250258 }
251259 }
252260 {
261+ DEFER_CLEANUP (struct s2n_connection * conn = s2n_connection_new (S2N_CLIENT ), s2n_connection_ptr_free );
262+ EXPECT_NOT_NULL (conn );
263+ EXPECT_SUCCESS (s2n_connection_set_cipher_preferences (conn , "test_all" ));
253264 /* Test generate/read/write/parse and compute shared secrets for all supported curves */
254265 for (int i = 0 ; i < s2n_all_supported_curves_list_len ; i ++ ) {
255266 struct s2n_ecc_evp_params server_params = {0 };
256267 struct s2n_ecc_evp_params read_params = {0 };
257- struct s2n_ecc_evp_params client_params = {0 };
268+ struct s2n_ecc_evp_params client_params = {0 };
258269 struct s2n_stuffer wire ;
259270 struct s2n_blob ecdh_params_sent , ecdh_params_received ;
260271 struct s2n_blob server_shared_secret , client_shared_secret ;
@@ -274,7 +285,7 @@ int main(int argc, char **argv) {
274285 /* Client reads the public */
275286 struct s2n_ecdhe_raw_server_params ecdhe_data = {0 };
276287 EXPECT_SUCCESS (s2n_ecc_evp_read_params (& wire , & ecdh_params_received , & ecdhe_data ));
277- EXPECT_SUCCESS (s2n_ecc_evp_parse_params (& ecdhe_data , & read_params ));
288+ EXPECT_SUCCESS (s2n_ecc_evp_parse_params (conn , & ecdhe_data , & read_params ));
278289
279290 /* Verify if the client correctly read the server public */
280291 EXPECT_TRUE (EVP_PKEY_cmp (server_params .evp_pkey , read_params .evp_pkey ));
@@ -283,11 +294,11 @@ int main(int argc, char **argv) {
283294 client_params .negotiated_curve = s2n_all_supported_curves_list [i ];
284295 EXPECT_SUCCESS (s2n_ecc_evp_generate_ephemeral_key (& client_params ));
285296 EXPECT_NOT_NULL (client_params .evp_pkey );
286-
297+
287298 /* Compute shared secret for the server */
288299 EXPECT_SUCCESS (
289300 s2n_ecc_evp_compute_shared_secret_from_params (& server_params , & client_params , & server_shared_secret ));
290-
301+
291302 /* Compute shared secret for the client */
292303 EXPECT_SUCCESS (
293304 s2n_ecc_evp_compute_shared_secret_from_params (& client_params , & read_params , & client_shared_secret ));
@@ -299,15 +310,18 @@ int main(int argc, char **argv) {
299310 /* Clean up */
300311 EXPECT_SUCCESS (s2n_stuffer_free (& wire ));
301312 EXPECT_SUCCESS (s2n_free (& server_shared_secret ));
302- EXPECT_SUCCESS (s2n_free (& client_shared_secret ));
313+ EXPECT_SUCCESS (s2n_free (& client_shared_secret ));
303314 EXPECT_SUCCESS (s2n_ecc_evp_params_free (& server_params ));
304315 EXPECT_SUCCESS (s2n_ecc_evp_params_free (& read_params ));
305316 EXPECT_SUCCESS (s2n_ecc_evp_params_free (& client_params ));
306317 }
307318 }
308319 {
320+ DEFER_CLEANUP (struct s2n_connection * conn = s2n_connection_new (S2N_CLIENT ), s2n_connection_ptr_free );
321+ EXPECT_NOT_NULL (conn );
322+ EXPECT_SUCCESS (s2n_connection_set_cipher_preferences (conn , "test_all" ));
309323 /* Test generate->write->read->compute_shared with all supported curves */
310- for (int i = 0 ; i < s2n_all_supported_curves_list_len ; i ++ ) {
324+ for (int i = 0 ; i < s2n_all_supported_curves_list_len ; i ++ ) {
311325 struct s2n_ecc_evp_params server_params = {0 }, client_params = {0 };
312326 struct s2n_stuffer wire ;
313327 struct s2n_blob server_shared , client_shared , ecdh_params_sent , ecdh_params_received ;
@@ -323,7 +337,7 @@ int main(int argc, char **argv) {
323337 /* Client reads the public */
324338 struct s2n_ecdhe_raw_server_params ecdhe_data = {0 };
325339 EXPECT_SUCCESS (s2n_ecc_evp_read_params (& wire , & ecdh_params_received , & ecdhe_data ));
326- EXPECT_SUCCESS (s2n_ecc_evp_parse_params (& ecdhe_data , & client_params ));
340+ EXPECT_SUCCESS (s2n_ecc_evp_parse_params (conn , & ecdhe_data , & client_params ));
327341
328342 /* The client got the curve */
329343 EXPECT_EQUAL (client_params .negotiated_curve , server_params .negotiated_curve );
@@ -345,5 +359,52 @@ int main(int argc, char **argv) {
345359 }
346360 }
347361
362+ /* Test that the client does not negotiate a group that was not
363+ * offered in EC preferences */
364+ {
365+ const struct s2n_security_policy * security_policy = NULL ;
366+ DEFER_CLEANUP (struct s2n_connection * conn = s2n_connection_new (S2N_CLIENT ), s2n_connection_ptr_free );
367+ EXPECT_NOT_NULL (conn );
368+ /* Version does not include the unsupported curve and secp521r1, which will be used by a malicious server */
369+ EXPECT_SUCCESS (s2n_connection_set_cipher_preferences (conn , "20190802" ));
370+ EXPECT_SUCCESS (s2n_connection_get_security_policy (conn , & security_policy ));
371+
372+ /* Setup & verify invalid curves, which will be selected by a malicious server */
373+ const struct s2n_ecc_named_curve * const unrequested_curves [] = {
374+ & s2n_unsupported_curve ,
375+ & s2n_ecc_curve_secp521r1 ,
376+ };
377+
378+ /* Verify that the client errors when the server attempts to
379+ * negotiate a curve that was never offered */
380+ for (size_t i = 0 ; i < s2n_array_len (unrequested_curves ); i ++ ) {
381+ struct s2n_ecc_evp_params server_params = {0 };
382+ struct s2n_ecc_evp_params client_params = {0 };
383+ struct s2n_stuffer wire = {0 };
384+ struct s2n_blob ecdh_params_sent = {0 }, ecdh_params_received = {0 };
385+
386+ EXPECT_SUCCESS (s2n_stuffer_growable_alloc (& wire , 1024 ));
387+
388+ /* Server maliciously chooses an unsupported curve */
389+ server_params .negotiated_curve = unrequested_curves [i ];
390+ EXPECT_SUCCESS (s2n_ecc_evp_generate_ephemeral_key (& server_params ));
391+ EXPECT_NOT_NULL (server_params .evp_pkey );
392+ /* Server sends the public */
393+ EXPECT_SUCCESS (s2n_ecc_evp_write_params (& server_params , & wire , & ecdh_params_sent ));
394+ /* Client reads the public */
395+ struct s2n_ecdhe_raw_server_params ecdhe_data = {0 };
396+ EXPECT_SUCCESS (s2n_ecc_evp_read_params (& wire , & ecdh_params_received , & ecdhe_data ));
397+ EXPECT_FAILURE_WITH_ERRNO (
398+ s2n_ecc_evp_parse_params (conn , & ecdhe_data , & client_params ), S2N_ERR_ECDHE_UNSUPPORTED_CURVE );
399+
400+ /* The client didn't agree on a curve */
401+ EXPECT_NULL (client_params .negotiated_curve );
402+
403+ /* Clean up */
404+ EXPECT_SUCCESS (s2n_stuffer_free (& wire ));
405+ EXPECT_SUCCESS (s2n_ecc_evp_params_free (& server_params ));
406+ EXPECT_SUCCESS (s2n_ecc_evp_params_free (& client_params ));
407+ }
408+ }
348409 END_TEST ();
349410}
0 commit comments