s2n_protocol_preferences.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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 "error/s2n_errno.h"
  16. #include "tls/s2n_connection.h"
  17. #include "utils/s2n_safety.h"
  18. S2N_RESULT s2n_protocol_preferences_read(struct s2n_stuffer *protocol_preferences, struct s2n_blob *protocol)
  19. {
  20. RESULT_ENSURE_REF(protocol_preferences);
  21. RESULT_ENSURE_REF(protocol);
  22. uint8_t length = 0;
  23. RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(protocol_preferences, &length));
  24. RESULT_ENSURE_GT(length, 0);
  25. uint8_t *data = s2n_stuffer_raw_read(protocol_preferences, length);
  26. RESULT_ENSURE_REF(data);
  27. RESULT_GUARD_POSIX(s2n_blob_init(protocol, data, length));
  28. return S2N_RESULT_OK;
  29. }
  30. S2N_RESULT s2n_protocol_preferences_contain(struct s2n_blob *protocol_preferences, struct s2n_blob *protocol, bool *contains)
  31. {
  32. RESULT_ENSURE_REF(contains);
  33. *contains = false;
  34. RESULT_ENSURE_REF(protocol_preferences);
  35. RESULT_ENSURE_REF(protocol);
  36. struct s2n_stuffer app_protocols_stuffer = { 0 };
  37. RESULT_GUARD_POSIX(s2n_stuffer_init(&app_protocols_stuffer, protocol_preferences));
  38. RESULT_GUARD_POSIX(s2n_stuffer_skip_write(&app_protocols_stuffer, protocol_preferences->size));
  39. while (s2n_stuffer_data_available(&app_protocols_stuffer) > 0) {
  40. struct s2n_blob match_against = { 0 };
  41. RESULT_GUARD(s2n_protocol_preferences_read(&app_protocols_stuffer, &match_against));
  42. if (match_against.size == protocol->size && memcmp(match_against.data, protocol->data, protocol->size) == 0) {
  43. *contains = true;
  44. return S2N_RESULT_OK;
  45. }
  46. }
  47. return S2N_RESULT_OK;
  48. }
  49. S2N_RESULT s2n_protocol_preferences_append(struct s2n_blob *application_protocols, const uint8_t *protocol, uint8_t protocol_len)
  50. {
  51. RESULT_ENSURE_MUT(application_protocols);
  52. RESULT_ENSURE_REF(protocol);
  53. /**
  54. *= https://tools.ietf.org/rfc/rfc7301#section-3.1
  55. *# Empty strings
  56. *# MUST NOT be included and byte strings MUST NOT be truncated.
  57. */
  58. RESULT_ENSURE(protocol_len != 0, S2N_ERR_INVALID_APPLICATION_PROTOCOL);
  59. uint32_t prev_len = application_protocols->size;
  60. uint32_t new_len = prev_len + /* len prefix */ 1 + protocol_len;
  61. RESULT_ENSURE(new_len <= UINT16_MAX, S2N_ERR_INVALID_APPLICATION_PROTOCOL);
  62. RESULT_GUARD_POSIX(s2n_realloc(application_protocols, new_len));
  63. struct s2n_stuffer protocol_stuffer = { 0 };
  64. RESULT_GUARD_POSIX(s2n_stuffer_init(&protocol_stuffer, application_protocols));
  65. RESULT_GUARD_POSIX(s2n_stuffer_skip_write(&protocol_stuffer, prev_len));
  66. RESULT_GUARD_POSIX(s2n_stuffer_write_uint8(&protocol_stuffer, protocol_len));
  67. RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(&protocol_stuffer, protocol, protocol_len));
  68. return S2N_RESULT_OK;
  69. }
  70. S2N_RESULT s2n_protocol_preferences_set(struct s2n_blob *application_protocols, const char *const *protocols, int protocol_count)
  71. {
  72. RESULT_ENSURE_MUT(application_protocols);
  73. /* NULL value indicates no preference so free the previous blob */
  74. if (protocols == NULL || protocol_count == 0) {
  75. RESULT_GUARD_POSIX(s2n_free(application_protocols));
  76. return S2N_RESULT_OK;
  77. }
  78. DEFER_CLEANUP(struct s2n_blob new_protocols = { 0 }, s2n_free);
  79. /* Allocate enough space to avoid a reallocation for every entry
  80. *
  81. * We assume that each protocol is most likely 8 bytes or less.
  82. * If it ends up being larger, we will expand the blob automatically
  83. * in the append method.
  84. */
  85. RESULT_GUARD_POSIX(s2n_realloc(&new_protocols, protocol_count * 8));
  86. /* set the size back to 0 so we start at the beginning.
  87. * s2n_realloc will just update the size field here
  88. */
  89. RESULT_GUARD_POSIX(s2n_realloc(&new_protocols, 0));
  90. RESULT_ENSURE_GTE(protocol_count, 0);
  91. for (size_t i = 0; i < (size_t) protocol_count; i++) {
  92. const uint8_t *protocol = (const uint8_t *) protocols[i];
  93. size_t length = strlen(protocols[i]);
  94. /**
  95. *= https://tools.ietf.org/rfc/rfc7301#section-3.1
  96. *# Empty strings
  97. *# MUST NOT be included and byte strings MUST NOT be truncated.
  98. */
  99. RESULT_ENSURE(length < 256, S2N_ERR_INVALID_APPLICATION_PROTOCOL);
  100. RESULT_GUARD(s2n_protocol_preferences_append(&new_protocols, protocol, (uint8_t) length));
  101. }
  102. /* now we can free the previous list since we've validated all new input */
  103. RESULT_GUARD_POSIX(s2n_free(application_protocols));
  104. /* update the connection/config application_protocols with the newly allocated blob */
  105. *application_protocols = new_protocols;
  106. /* zero out new_protocols so the DEFER_CLEANUP from above doesn't free
  107. * the blob that we created and assigned to application_protocols
  108. */
  109. /* cppcheck-suppress unreadVariable */
  110. new_protocols = (struct s2n_blob){ 0 };
  111. return S2N_RESULT_OK;
  112. }
  113. S2N_RESULT s2n_select_server_preference_protocol(struct s2n_connection *conn, struct s2n_stuffer *server_list,
  114. struct s2n_blob *client_list)
  115. {
  116. RESULT_ENSURE_REF(conn);
  117. RESULT_ENSURE_REF(server_list);
  118. RESULT_ENSURE_REF(client_list);
  119. while (s2n_stuffer_data_available(server_list) > 0) {
  120. struct s2n_blob protocol = { 0 };
  121. RESULT_ENSURE_OK(s2n_protocol_preferences_read(server_list, &protocol), S2N_ERR_BAD_MESSAGE);
  122. bool match_found = false;
  123. RESULT_ENSURE_OK(s2n_protocol_preferences_contain(client_list, &protocol, &match_found), S2N_ERR_BAD_MESSAGE);
  124. if (match_found) {
  125. RESULT_ENSURE_LT(protocol.size, sizeof(conn->application_protocol));
  126. RESULT_CHECKED_MEMCPY(conn->application_protocol, protocol.data, protocol.size);
  127. conn->application_protocol[protocol.size] = '\0';
  128. return S2N_RESULT_OK;
  129. }
  130. }
  131. return S2N_RESULT_OK;
  132. }
  133. int s2n_config_set_protocol_preferences(struct s2n_config *config, const char *const *protocols, int protocol_count)
  134. {
  135. POSIX_GUARD_RESULT(s2n_protocol_preferences_set(&config->application_protocols, protocols, protocol_count));
  136. return S2N_SUCCESS;
  137. }
  138. int s2n_config_append_protocol_preference(struct s2n_config *config, const uint8_t *protocol, uint8_t protocol_len)
  139. {
  140. POSIX_GUARD_RESULT(s2n_protocol_preferences_append(&config->application_protocols, protocol, protocol_len));
  141. return S2N_SUCCESS;
  142. }
  143. int s2n_connection_set_protocol_preferences(struct s2n_connection *conn, const char *const *protocols, int protocol_count)
  144. {
  145. POSIX_GUARD_RESULT(s2n_protocol_preferences_set(&conn->application_protocols_overridden, protocols, protocol_count));
  146. return S2N_SUCCESS;
  147. }
  148. int s2n_connection_append_protocol_preference(struct s2n_connection *conn, const uint8_t *protocol, uint8_t protocol_len)
  149. {
  150. POSIX_GUARD_RESULT(s2n_protocol_preferences_append(&conn->application_protocols_overridden, protocol, protocol_len));
  151. return S2N_SUCCESS;
  152. }