s2n_client_server_name.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License").
  5. * You may not use this file except in compliance with the License.
  6. * A copy of the License is located at
  7. *
  8. * http://aws.amazon.com/apache2.0
  9. *
  10. * or in the "license" file accompanying this file. This file is distributed
  11. * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  12. * express or implied. See the License for the specific language governing
  13. * permissions and limitations under the License.
  14. */
  15. #include "tls/extensions/s2n_client_server_name.h"
  16. #include <stdint.h>
  17. #include <sys/param.h>
  18. #include "tls/s2n_tls.h"
  19. #include "tls/s2n_tls_parameters.h"
  20. #include "utils/s2n_safety.h"
  21. #define S2N_NAME_TYPE_HOST_NAME 0
  22. static bool s2n_client_server_name_should_send(struct s2n_connection *conn);
  23. static int s2n_client_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out);
  24. static int s2n_client_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension);
  25. const s2n_extension_type s2n_client_server_name_extension = {
  26. .iana_value = TLS_EXTENSION_SERVER_NAME,
  27. .is_response = false,
  28. .send = s2n_client_server_name_send,
  29. .recv = s2n_client_server_name_recv,
  30. .should_send = s2n_client_server_name_should_send,
  31. .if_missing = s2n_extension_noop_if_missing,
  32. };
  33. static bool s2n_client_server_name_should_send(struct s2n_connection *conn)
  34. {
  35. return conn && conn->server_name[0] != '\0';
  36. }
  37. static int s2n_client_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out)
  38. {
  39. struct s2n_stuffer_reservation server_name_list_size = { 0 };
  40. POSIX_GUARD(s2n_stuffer_reserve_uint16(out, &server_name_list_size));
  41. /* NameType, as described by RFC6066.
  42. * host_name is currently the only possible NameType defined. */
  43. POSIX_GUARD(s2n_stuffer_write_uint8(out, S2N_NAME_TYPE_HOST_NAME));
  44. POSIX_GUARD(s2n_stuffer_write_uint16(out, strlen(conn->server_name)));
  45. POSIX_GUARD(s2n_stuffer_write_bytes(out, (const uint8_t *) conn->server_name, strlen(conn->server_name)));
  46. POSIX_GUARD(s2n_stuffer_write_vector_size(&server_name_list_size));
  47. return S2N_SUCCESS;
  48. }
  49. /* Read the extension up to the first item in ServerNameList. Store the first entry's length in server_name_len.
  50. * For now s2n ignores all subsequent items in ServerNameList.
  51. */
  52. static int s2n_client_server_name_check(struct s2n_connection *conn, struct s2n_stuffer *extension, uint16_t *server_name_len)
  53. {
  54. POSIX_ENSURE_REF(conn);
  55. uint16_t size_of_all;
  56. POSIX_GUARD(s2n_stuffer_read_uint16(extension, &size_of_all));
  57. POSIX_ENSURE_LTE(size_of_all, s2n_stuffer_data_available(extension));
  58. uint8_t server_name_type;
  59. POSIX_GUARD(s2n_stuffer_read_uint8(extension, &server_name_type));
  60. POSIX_ENSURE_EQ(server_name_type, S2N_NAME_TYPE_HOST_NAME);
  61. POSIX_GUARD(s2n_stuffer_read_uint16(extension, server_name_len));
  62. POSIX_ENSURE_LT(*server_name_len, sizeof(conn->server_name));
  63. POSIX_ENSURE_LTE(*server_name_len, s2n_stuffer_data_available(extension));
  64. return S2N_SUCCESS;
  65. }
  66. static int s2n_client_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension)
  67. {
  68. POSIX_ENSURE_REF(conn);
  69. /* Exit early if we've already parsed the server name */
  70. if (conn->server_name[0]) {
  71. return S2N_SUCCESS;
  72. }
  73. /* Ignore if malformed. We just won't use the server name. */
  74. uint16_t server_name_len;
  75. if (s2n_client_server_name_check(conn, extension, &server_name_len) != S2N_SUCCESS) {
  76. return S2N_SUCCESS;
  77. }
  78. uint8_t *server_name;
  79. POSIX_ENSURE_REF(server_name = s2n_stuffer_raw_read(extension, server_name_len));
  80. POSIX_CHECKED_MEMCPY(conn->server_name, server_name, server_name_len);
  81. return S2N_SUCCESS;
  82. }