dtlsv1listentest.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /*
  2. * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <string.h>
  10. #include <openssl/ssl.h>
  11. #include <openssl/bio.h>
  12. #include <openssl/err.h>
  13. #include <openssl/conf.h>
  14. #include "internal/nelem.h"
  15. #include "testutil.h"
  16. #ifndef OPENSSL_NO_SOCK
  17. /* Just a ClientHello without a cookie */
  18. static const unsigned char clienthello_nocookie[] = {
  19. 0x16, /* Handshake */
  20. 0xFE, 0xFF, /* DTLSv1.0 */
  21. 0x00, 0x00, /* Epoch */
  22. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
  23. 0x00, 0x3A, /* Record Length */
  24. 0x01, /* ClientHello */
  25. 0x00, 0x00, 0x2E, /* Message length */
  26. 0x00, 0x00, /* Message sequence */
  27. 0x00, 0x00, 0x00, /* Fragment offset */
  28. 0x00, 0x00, 0x2E, /* Fragment length */
  29. 0xFE, 0xFD, /* DTLSv1.2 */
  30. 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
  31. 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
  32. 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
  33. 0x00, /* Session id len */
  34. 0x00, /* Cookie len */
  35. 0x00, 0x04, /* Ciphersuites len */
  36. 0x00, 0x2f, /* AES128-SHA */
  37. 0x00, 0xff, /* Empty reneg info SCSV */
  38. 0x01, /* Compression methods len */
  39. 0x00, /* Null compression */
  40. 0x00, 0x00 /* Extensions len */
  41. };
  42. /* First fragment of a ClientHello without a cookie */
  43. static const unsigned char clienthello_nocookie_frag[] = {
  44. 0x16, /* Handshake */
  45. 0xFE, 0xFF, /* DTLSv1.0 */
  46. 0x00, 0x00, /* Epoch */
  47. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
  48. 0x00, 0x30, /* Record Length */
  49. 0x01, /* ClientHello */
  50. 0x00, 0x00, 0x2E, /* Message length */
  51. 0x00, 0x00, /* Message sequence */
  52. 0x00, 0x00, 0x00, /* Fragment offset */
  53. 0x00, 0x00, 0x24, /* Fragment length */
  54. 0xFE, 0xFD, /* DTLSv1.2 */
  55. 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
  56. 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
  57. 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
  58. 0x00, /* Session id len */
  59. 0x00 /* Cookie len */
  60. };
  61. /* First fragment of a ClientHello which is too short */
  62. static const unsigned char clienthello_nocookie_short[] = {
  63. 0x16, /* Handshake */
  64. 0xFE, 0xFF, /* DTLSv1.0 */
  65. 0x00, 0x00, /* Epoch */
  66. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
  67. 0x00, 0x2F, /* Record Length */
  68. 0x01, /* ClientHello */
  69. 0x00, 0x00, 0x2E, /* Message length */
  70. 0x00, 0x00, /* Message sequence */
  71. 0x00, 0x00, 0x00, /* Fragment offset */
  72. 0x00, 0x00, 0x23, /* Fragment length */
  73. 0xFE, 0xFD, /* DTLSv1.2 */
  74. 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
  75. 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
  76. 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
  77. 0x00 /* Session id len */
  78. };
  79. /* Second fragment of a ClientHello */
  80. static const unsigned char clienthello_2ndfrag[] = {
  81. 0x16, /* Handshake */
  82. 0xFE, 0xFF, /* DTLSv1.0 */
  83. 0x00, 0x00, /* Epoch */
  84. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
  85. 0x00, 0x38, /* Record Length */
  86. 0x01, /* ClientHello */
  87. 0x00, 0x00, 0x2E, /* Message length */
  88. 0x00, 0x00, /* Message sequence */
  89. 0x00, 0x00, 0x02, /* Fragment offset */
  90. 0x00, 0x00, 0x2C, /* Fragment length */
  91. /* Version skipped - sent in first fragment */
  92. 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
  93. 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
  94. 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
  95. 0x00, /* Session id len */
  96. 0x00, /* Cookie len */
  97. 0x00, 0x04, /* Ciphersuites len */
  98. 0x00, 0x2f, /* AES128-SHA */
  99. 0x00, 0xff, /* Empty reneg info SCSV */
  100. 0x01, /* Compression methods len */
  101. 0x00, /* Null compression */
  102. 0x00, 0x00 /* Extensions len */
  103. };
  104. /* A ClientHello with a good cookie */
  105. static const unsigned char clienthello_cookie[] = {
  106. 0x16, /* Handshake */
  107. 0xFE, 0xFF, /* DTLSv1.0 */
  108. 0x00, 0x00, /* Epoch */
  109. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
  110. 0x00, 0x4E, /* Record Length */
  111. 0x01, /* ClientHello */
  112. 0x00, 0x00, 0x42, /* Message length */
  113. 0x00, 0x00, /* Message sequence */
  114. 0x00, 0x00, 0x00, /* Fragment offset */
  115. 0x00, 0x00, 0x42, /* Fragment length */
  116. 0xFE, 0xFD, /* DTLSv1.2 */
  117. 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
  118. 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
  119. 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
  120. 0x00, /* Session id len */
  121. 0x14, /* Cookie len */
  122. 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
  123. 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
  124. 0x00, 0x04, /* Ciphersuites len */
  125. 0x00, 0x2f, /* AES128-SHA */
  126. 0x00, 0xff, /* Empty reneg info SCSV */
  127. 0x01, /* Compression methods len */
  128. 0x00, /* Null compression */
  129. 0x00, 0x00 /* Extensions len */
  130. };
  131. /* A fragmented ClientHello with a good cookie */
  132. static const unsigned char clienthello_cookie_frag[] = {
  133. 0x16, /* Handshake */
  134. 0xFE, 0xFF, /* DTLSv1.0 */
  135. 0x00, 0x00, /* Epoch */
  136. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
  137. 0x00, 0x44, /* Record Length */
  138. 0x01, /* ClientHello */
  139. 0x00, 0x00, 0x42, /* Message length */
  140. 0x00, 0x00, /* Message sequence */
  141. 0x00, 0x00, 0x00, /* Fragment offset */
  142. 0x00, 0x00, 0x38, /* Fragment length */
  143. 0xFE, 0xFD, /* DTLSv1.2 */
  144. 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
  145. 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
  146. 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
  147. 0x00, /* Session id len */
  148. 0x14, /* Cookie len */
  149. 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
  150. 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
  151. };
  152. /* A ClientHello with a bad cookie */
  153. static const unsigned char clienthello_badcookie[] = {
  154. 0x16, /* Handshake */
  155. 0xFE, 0xFF, /* DTLSv1.0 */
  156. 0x00, 0x00, /* Epoch */
  157. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
  158. 0x00, 0x4E, /* Record Length */
  159. 0x01, /* ClientHello */
  160. 0x00, 0x00, 0x42, /* Message length */
  161. 0x00, 0x00, /* Message sequence */
  162. 0x00, 0x00, 0x00, /* Fragment offset */
  163. 0x00, 0x00, 0x42, /* Fragment length */
  164. 0xFE, 0xFD, /* DTLSv1.2 */
  165. 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
  166. 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
  167. 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
  168. 0x00, /* Session id len */
  169. 0x14, /* Cookie len */
  170. 0x01, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
  171. 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
  172. 0x00, 0x04, /* Ciphersuites len */
  173. 0x00, 0x2f, /* AES128-SHA */
  174. 0x00, 0xff, /* Empty reneg info SCSV */
  175. 0x01, /* Compression methods len */
  176. 0x00, /* Null compression */
  177. 0x00, 0x00 /* Extensions len */
  178. };
  179. /* A fragmented ClientHello with the fragment boundary mid cookie */
  180. static const unsigned char clienthello_cookie_short[] = {
  181. 0x16, /* Handshake */
  182. 0xFE, 0xFF, /* DTLSv1.0 */
  183. 0x00, 0x00, /* Epoch */
  184. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
  185. 0x00, 0x43, /* Record Length */
  186. 0x01, /* ClientHello */
  187. 0x00, 0x00, 0x42, /* Message length */
  188. 0x00, 0x00, /* Message sequence */
  189. 0x00, 0x00, 0x00, /* Fragment offset */
  190. 0x00, 0x00, 0x37, /* Fragment length */
  191. 0xFE, 0xFD, /* DTLSv1.2 */
  192. 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
  193. 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
  194. 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
  195. 0x00, /* Session id len */
  196. 0x14, /* Cookie len */
  197. 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
  198. 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12 /* Cookie */
  199. };
  200. /* Bad record - too short */
  201. static const unsigned char record_short[] = {
  202. 0x16, /* Handshake */
  203. 0xFE, 0xFF, /* DTLSv1.0 */
  204. 0x00, 0x00, /* Epoch */
  205. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* Record sequence number */
  206. };
  207. static const unsigned char verify[] = {
  208. 0x16, /* Handshake */
  209. 0xFE, 0xFF, /* DTLSv1.0 */
  210. 0x00, 0x00, /* Epoch */
  211. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
  212. 0x00, 0x23, /* Record Length */
  213. 0x03, /* HelloVerifyRequest */
  214. 0x00, 0x00, 0x17, /* Message length */
  215. 0x00, 0x00, /* Message sequence */
  216. 0x00, 0x00, 0x00, /* Fragment offset */
  217. 0x00, 0x00, 0x17, /* Fragment length */
  218. 0xFE, 0xFF, /* DTLSv1.0 */
  219. 0x14, /* Cookie len */
  220. 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
  221. 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
  222. };
  223. typedef struct {
  224. const unsigned char *in;
  225. unsigned int inlen;
  226. /*
  227. * GOOD == positive return value from DTLSv1_listen, no output yet
  228. * VERIFY == 0 return value, HelloVerifyRequest sent
  229. * DROP == 0 return value, no output
  230. */
  231. enum {GOOD, VERIFY, DROP} outtype;
  232. } tests;
  233. static tests testpackets[9] = {
  234. { clienthello_nocookie, sizeof(clienthello_nocookie), VERIFY },
  235. { clienthello_nocookie_frag, sizeof(clienthello_nocookie_frag), VERIFY },
  236. { clienthello_nocookie_short, sizeof(clienthello_nocookie_short), DROP },
  237. { clienthello_2ndfrag, sizeof(clienthello_2ndfrag), DROP },
  238. { clienthello_cookie, sizeof(clienthello_cookie), GOOD },
  239. { clienthello_cookie_frag, sizeof(clienthello_cookie_frag), GOOD },
  240. { clienthello_badcookie, sizeof(clienthello_badcookie), VERIFY },
  241. { clienthello_cookie_short, sizeof(clienthello_cookie_short), DROP },
  242. { record_short, sizeof(record_short), DROP }
  243. };
  244. # define COOKIE_LEN 20
  245. static int cookie_gen(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
  246. {
  247. unsigned int i;
  248. for (i = 0; i < COOKIE_LEN; i++, cookie++)
  249. *cookie = i;
  250. *cookie_len = COOKIE_LEN;
  251. return 1;
  252. }
  253. static int cookie_verify(SSL *ssl, const unsigned char *cookie,
  254. unsigned int cookie_len)
  255. {
  256. unsigned int i;
  257. if (cookie_len != COOKIE_LEN)
  258. return 0;
  259. for (i = 0; i < COOKIE_LEN; i++, cookie++) {
  260. if (*cookie != i)
  261. return 0;
  262. }
  263. return 1;
  264. }
  265. static int dtls_listen_test(int i)
  266. {
  267. SSL_CTX *ctx = NULL;
  268. SSL *ssl = NULL;
  269. BIO *outbio = NULL;
  270. BIO *inbio = NULL;
  271. BIO_ADDR *peer = NULL;
  272. tests *tp = &testpackets[i];
  273. char *data;
  274. long datalen;
  275. int ret, success = 0;
  276. if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))
  277. || !TEST_ptr(peer = BIO_ADDR_new()))
  278. goto err;
  279. SSL_CTX_set_cookie_generate_cb(ctx, cookie_gen);
  280. SSL_CTX_set_cookie_verify_cb(ctx, cookie_verify);
  281. /* Create an SSL object and set the BIO */
  282. if (!TEST_ptr(ssl = SSL_new(ctx))
  283. || !TEST_ptr(outbio = BIO_new(BIO_s_mem())))
  284. goto err;
  285. SSL_set0_wbio(ssl, outbio);
  286. /* Set Non-blocking IO behaviour */
  287. if (!TEST_ptr(inbio = BIO_new_mem_buf((char *)tp->in, tp->inlen)))
  288. goto err;
  289. BIO_set_mem_eof_return(inbio, -1);
  290. SSL_set0_rbio(ssl, inbio);
  291. /* Process the incoming packet */
  292. if (!TEST_int_ge(ret = DTLSv1_listen(ssl, peer), 0))
  293. goto err;
  294. datalen = BIO_get_mem_data(outbio, &data);
  295. if (tp->outtype == VERIFY) {
  296. if (!TEST_int_eq(ret, 0)
  297. || !TEST_mem_eq(data, datalen, verify, sizeof(verify)))
  298. goto err;
  299. } else if (datalen == 0) {
  300. if (!TEST_true((ret == 0 && tp->outtype == DROP)
  301. || (ret == 1 && tp->outtype == GOOD)))
  302. goto err;
  303. } else {
  304. TEST_info("Test %d: unexpected data output", i);
  305. goto err;
  306. }
  307. (void)BIO_reset(outbio);
  308. inbio = NULL;
  309. SSL_set0_rbio(ssl, NULL);
  310. success = 1;
  311. err:
  312. /* Also frees up outbio */
  313. SSL_free(ssl);
  314. SSL_CTX_free(ctx);
  315. BIO_free(inbio);
  316. OPENSSL_free(peer);
  317. return success;
  318. }
  319. #endif
  320. int setup_tests()
  321. {
  322. #ifndef OPENSSL_NO_SOCK
  323. ADD_ALL_TESTS(dtls_listen_test, (int)OSSL_NELEM(testpackets));
  324. #endif
  325. return 1;
  326. }