d1_pkt.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /* DTLS implementation written by Nagendra Modadugu
  2. * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. */
  3. /* ====================================================================
  4. * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. *
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in
  15. * the documentation and/or other materials provided with the
  16. * distribution.
  17. *
  18. * 3. All advertising materials mentioning features or use of this
  19. * software must display the following acknowledgment:
  20. * "This product includes software developed by the OpenSSL Project
  21. * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
  22. *
  23. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  24. * endorse or promote products derived from this software without
  25. * prior written permission. For written permission, please contact
  26. * openssl-core@openssl.org.
  27. *
  28. * 5. Products derived from this software may not be called "OpenSSL"
  29. * nor may "OpenSSL" appear in their names without prior written
  30. * permission of the OpenSSL Project.
  31. *
  32. * 6. Redistributions of any form whatsoever must retain the following
  33. * acknowledgment:
  34. * "This product includes software developed by the OpenSSL Project
  35. * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
  36. *
  37. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  38. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  39. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  40. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  41. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  42. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  43. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  44. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  45. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  46. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  47. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  48. * OF THE POSSIBILITY OF SUCH DAMAGE.
  49. * ====================================================================
  50. *
  51. * This product includes cryptographic software written by Eric Young
  52. * (eay@cryptsoft.com). This product includes software written by Tim
  53. * Hudson (tjh@cryptsoft.com).
  54. *
  55. */
  56. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  57. * All rights reserved.
  58. *
  59. * This package is an SSL implementation written
  60. * by Eric Young (eay@cryptsoft.com).
  61. * The implementation was written so as to conform with Netscapes SSL.
  62. *
  63. * This library is free for commercial and non-commercial use as long as
  64. * the following conditions are aheared to. The following conditions
  65. * apply to all code found in this distribution, be it the RC4, RSA,
  66. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  67. * included with this distribution is covered by the same copyright terms
  68. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  69. *
  70. * Copyright remains Eric Young's, and as such any Copyright notices in
  71. * the code are not to be removed.
  72. * If this package is used in a product, Eric Young should be given attribution
  73. * as the author of the parts of the library used.
  74. * This can be in the form of a textual message at program startup or
  75. * in documentation (online or textual) provided with the package.
  76. *
  77. * Redistribution and use in source and binary forms, with or without
  78. * modification, are permitted provided that the following conditions
  79. * are met:
  80. * 1. Redistributions of source code must retain the copyright
  81. * notice, this list of conditions and the following disclaimer.
  82. * 2. Redistributions in binary form must reproduce the above copyright
  83. * notice, this list of conditions and the following disclaimer in the
  84. * documentation and/or other materials provided with the distribution.
  85. * 3. All advertising materials mentioning features or use of this software
  86. * must display the following acknowledgement:
  87. * "This product includes cryptographic software written by
  88. * Eric Young (eay@cryptsoft.com)"
  89. * The word 'cryptographic' can be left out if the rouines from the library
  90. * being used are not cryptographic related :-).
  91. * 4. If you include any Windows specific code (or a derivative thereof) from
  92. * the apps directory (application code) you must include an acknowledgement:
  93. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  94. *
  95. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  96. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  97. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  98. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  99. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  100. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  101. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  102. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  103. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  104. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  105. * SUCH DAMAGE.
  106. *
  107. * The licence and distribution terms for any publically available version or
  108. * derivative of this code cannot be changed. i.e. this code cannot simply be
  109. * copied and put under another distribution licence
  110. * [including the GNU Public Licence.] */
  111. #include <openssl/ssl.h>
  112. #include <assert.h>
  113. #include <string.h>
  114. #include <openssl/bio.h>
  115. #include <openssl/buf.h>
  116. #include <openssl/bytestring.h>
  117. #include <openssl/mem.h>
  118. #include <openssl/evp.h>
  119. #include <openssl/err.h>
  120. #include <openssl/rand.h>
  121. #include "../crypto/internal.h"
  122. #include "internal.h"
  123. BSSL_NAMESPACE_BEGIN
  124. ssl_open_record_t dtls1_open_app_data(SSL *ssl, Span<uint8_t> *out,
  125. size_t *out_consumed, uint8_t *out_alert,
  126. Span<uint8_t> in) {
  127. assert(!SSL_in_init(ssl));
  128. uint8_t type;
  129. Span<uint8_t> record;
  130. auto ret = dtls_open_record(ssl, &type, &record, out_consumed, out_alert, in);
  131. if (ret != ssl_open_record_success) {
  132. return ret;
  133. }
  134. if (type == SSL3_RT_HANDSHAKE) {
  135. // Parse the first fragment header to determine if this is a pre-CCS or
  136. // post-CCS handshake record. DTLS resets handshake message numbers on each
  137. // handshake, so renegotiations and retransmissions are ambiguous.
  138. CBS cbs, body;
  139. struct hm_header_st msg_hdr;
  140. CBS_init(&cbs, record.data(), record.size());
  141. if (!dtls1_parse_fragment(&cbs, &msg_hdr, &body)) {
  142. OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HANDSHAKE_RECORD);
  143. *out_alert = SSL_AD_DECODE_ERROR;
  144. return ssl_open_record_error;
  145. }
  146. if (msg_hdr.type == SSL3_MT_FINISHED &&
  147. msg_hdr.seq == ssl->d1->handshake_read_seq - 1) {
  148. if (msg_hdr.frag_off == 0) {
  149. // Retransmit our last flight of messages. If the peer sends the second
  150. // Finished, they may not have received ours. Only do this for the
  151. // first fragment, in case the Finished was fragmented.
  152. if (!dtls1_check_timeout_num(ssl)) {
  153. *out_alert = 0; // TODO(davidben): Send an alert?
  154. return ssl_open_record_error;
  155. }
  156. dtls1_retransmit_outgoing_messages(ssl);
  157. }
  158. return ssl_open_record_discard;
  159. }
  160. // Otherwise, this is a pre-CCS handshake message from an unsupported
  161. // renegotiation attempt. Fall through to the error path.
  162. }
  163. if (type != SSL3_RT_APPLICATION_DATA) {
  164. OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
  165. *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
  166. return ssl_open_record_error;
  167. }
  168. if (record.empty()) {
  169. return ssl_open_record_discard;
  170. }
  171. *out = record;
  172. return ssl_open_record_success;
  173. }
  174. int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *in,
  175. int len) {
  176. assert(!SSL_in_init(ssl));
  177. *out_needs_handshake = false;
  178. if (ssl->s3->write_shutdown != ssl_shutdown_none) {
  179. OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
  180. return -1;
  181. }
  182. if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
  183. OPENSSL_PUT_ERROR(SSL, SSL_R_DTLS_MESSAGE_TOO_BIG);
  184. return -1;
  185. }
  186. if (len < 0) {
  187. OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH);
  188. return -1;
  189. }
  190. if (len == 0) {
  191. return 0;
  192. }
  193. int ret = dtls1_write_record(ssl, SSL3_RT_APPLICATION_DATA, in, (size_t)len,
  194. dtls1_use_current_epoch);
  195. if (ret <= 0) {
  196. return ret;
  197. }
  198. return len;
  199. }
  200. int dtls1_write_record(SSL *ssl, int type, const uint8_t *in, size_t len,
  201. enum dtls1_use_epoch_t use_epoch) {
  202. SSLBuffer *buf = &ssl->s3->write_buffer;
  203. assert(len <= SSL3_RT_MAX_PLAIN_LENGTH);
  204. // There should never be a pending write buffer in DTLS. One can't write half
  205. // a datagram, so the write buffer is always dropped in
  206. // |ssl_write_buffer_flush|.
  207. assert(buf->empty());
  208. if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
  209. OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
  210. return -1;
  211. }
  212. size_t ciphertext_len;
  213. if (!buf->EnsureCap(ssl_seal_align_prefix_len(ssl),
  214. len + SSL_max_seal_overhead(ssl)) ||
  215. !dtls_seal_record(ssl, buf->remaining().data(), &ciphertext_len,
  216. buf->remaining().size(), type, in, len, use_epoch)) {
  217. buf->Clear();
  218. return -1;
  219. }
  220. buf->DidWrite(ciphertext_len);
  221. int ret = ssl_write_buffer_flush(ssl);
  222. if (ret <= 0) {
  223. return ret;
  224. }
  225. return 1;
  226. }
  227. int dtls1_dispatch_alert(SSL *ssl) {
  228. int ret = dtls1_write_record(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2,
  229. dtls1_use_current_epoch);
  230. if (ret <= 0) {
  231. return ret;
  232. }
  233. ssl->s3->alert_dispatch = false;
  234. // If the alert is fatal, flush the BIO now.
  235. if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) {
  236. BIO_flush(ssl->wbio.get());
  237. }
  238. ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, ssl->s3->send_alert);
  239. int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1];
  240. ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, alert);
  241. return 1;
  242. }
  243. BSSL_NAMESPACE_END