dtls.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. /* dtls.c
  2. *
  3. * Copyright (C) 2006-2022 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <wolfssl/wolfcrypt/settings.h>
  25. #if defined(WOLFSSL_DTLS_CID)
  26. #include <wolfssl/error-ssl.h>
  27. #include <wolfssl/internal.h>
  28. #include <wolfssl/ssl.h>
  29. typedef struct ConnectionID {
  30. byte length;
  31. byte id[];
  32. } ConnectionID;
  33. typedef struct CIDInfo {
  34. ConnectionID* tx;
  35. ConnectionID* rx;
  36. byte negotiated : 1;
  37. } CIDInfo;
  38. static ConnectionID* DtlsCidNew(const byte* cid, byte size, void* heap)
  39. {
  40. ConnectionID* ret;
  41. ret = (ConnectionID*)XMALLOC(sizeof(ConnectionID) + size, heap,
  42. DYNAMIC_TYPE_TLSX);
  43. if (ret == NULL)
  44. return NULL;
  45. ret->length = size;
  46. XMEMCPY(ret->id, cid, size);
  47. return ret;
  48. }
  49. static WC_INLINE CIDInfo* DtlsCidGetInfo(WOLFSSL* ssl)
  50. {
  51. return ssl->dtlsCidInfo;
  52. }
  53. static int DtlsCidGetSize(WOLFSSL* ssl, unsigned int* size, int rx)
  54. {
  55. ConnectionID* id;
  56. CIDInfo* info;
  57. if (ssl == NULL || size == NULL)
  58. return BAD_FUNC_ARG;
  59. info = DtlsCidGetInfo(ssl);
  60. if (info == NULL)
  61. return WOLFSSL_FAILURE;
  62. id = rx ? info->rx : info->tx;
  63. if (id == NULL) {
  64. *size = 0;
  65. return WOLFSSL_SUCCESS;
  66. }
  67. *size = id->length;
  68. return WOLFSSL_SUCCESS;
  69. }
  70. static int DtlsCidGet(WOLFSSL* ssl, unsigned char* buf, int bufferSz, int rx)
  71. {
  72. ConnectionID* id;
  73. CIDInfo* info;
  74. if (ssl == NULL || buf == NULL)
  75. return BAD_FUNC_ARG;
  76. info = DtlsCidGetInfo(ssl);
  77. if (info == NULL)
  78. return WOLFSSL_FAILURE;
  79. id = rx ? info->rx : info->tx;
  80. if (id == NULL || id->length == 0)
  81. return WOLFSSL_SUCCESS;
  82. if (id->length > bufferSz)
  83. return LENGTH_ERROR;
  84. XMEMCPY(buf, id->id, id->length);
  85. return WOLFSSL_SUCCESS;
  86. }
  87. static CIDInfo* DtlsCidGetInfoFromExt(byte* ext)
  88. {
  89. WOLFSSL** sslPtr;
  90. WOLFSSL* ssl;
  91. if (ext == NULL)
  92. return NULL;
  93. sslPtr = (WOLFSSL**)ext;
  94. ssl = *sslPtr;
  95. if (ssl == NULL)
  96. return NULL;
  97. return ssl->dtlsCidInfo;
  98. }
  99. static void DtlsCidUnsetInfoFromExt(byte* ext)
  100. {
  101. WOLFSSL** sslPtr;
  102. WOLFSSL* ssl;
  103. if (ext == NULL)
  104. return;
  105. sslPtr = (WOLFSSL**)ext;
  106. ssl = *sslPtr;
  107. if (ssl == NULL)
  108. return;
  109. ssl->dtlsCidInfo = NULL;
  110. }
  111. void TLSX_ConnectionID_Free(byte* ext, void* heap)
  112. {
  113. CIDInfo* info;
  114. (void)heap;
  115. info = DtlsCidGetInfoFromExt(ext);
  116. if (info == NULL)
  117. return;
  118. if (info->rx != NULL)
  119. XFREE(info->rx, heap, DYNAMIC_TYPE_TLSX);
  120. if (info->tx != NULL)
  121. XFREE(info->tx, heap, DYNAMIC_TYPE_TLSX);
  122. XFREE(info, heap, DYNAMIC_TYPE_TLSX);
  123. DtlsCidUnsetInfoFromExt(ext);
  124. XFREE(ext, heap, DYANMIC_TYPE_TLSX);
  125. }
  126. word16 TLSX_ConnectionID_Write(byte* ext, byte* output)
  127. {
  128. CIDInfo* info;
  129. info = DtlsCidGetInfoFromExt(ext);
  130. if (info == NULL)
  131. return 0;
  132. /* empty CID */
  133. if (info->rx == NULL) {
  134. *output = 0;
  135. return OPAQUE8_LEN;
  136. }
  137. *output = info->rx->length;
  138. XMEMCPY(output + OPAQUE8_LEN, info->rx->id, info->rx->length);
  139. return OPAQUE8_LEN + info->rx->length;
  140. }
  141. word16 TLSX_ConnectionID_GetSize(byte* ext)
  142. {
  143. CIDInfo* info = DtlsCidGetInfoFromExt(ext);
  144. if (info == NULL)
  145. return 0;
  146. return info->rx == NULL ? OPAQUE8_LEN : OPAQUE8_LEN + info->rx->length;
  147. }
  148. int TLSX_ConnectionID_Use(WOLFSSL* ssl)
  149. {
  150. CIDInfo* info;
  151. WOLFSSL** ext;
  152. int ret;
  153. ext = (WOLFSSL**)TLSX_Find(ssl->extensions, TLSX_CONNECTION_ID);
  154. if (ext != NULL)
  155. return 0;
  156. info = (CIDInfo*)XMALLOC(sizeof(CIDInfo), ssl->heap, DYNAMIC_TYPE_TLSX);
  157. if (info == NULL)
  158. return MEMORY_ERROR;
  159. ext = (WOLFSSL**)XMALLOC(sizeof(WOLFSSL**), ssl->heap, DYNAMIC_TYPE_TLSX);
  160. if (ext == NULL) {
  161. XFREE(info, ssl->heap, DYNAMIC_TYPE_TLSX);
  162. return MEMORY_ERROR;
  163. }
  164. XMEMSET(info, 0, sizeof(CIDInfo));
  165. /* CIDInfo needs to be accessed every time we send or receive a record. To
  166. * avoid the cost of the extension lookup save a pointer to the structure
  167. * inside the SSL object itself, and save a pointer to the SSL object in the
  168. * extension. The extension freeing routine uses te pointer to the SSL
  169. * object to find the structure and to set ssl->dtlsCidInfo pointer to NULL
  170. * after freeing the structure. */
  171. ssl->dtlsCidInfo = info;
  172. *ext = ssl;
  173. ret =
  174. TLSX_Push(&ssl->extensions, TLSX_CONNECTION_ID, (void*)ext, ssl->heap);
  175. if (ret != 0) {
  176. XFREE(info, ssl->heap, DYNAMIC_TYPE_TLSX);
  177. XFREE(ext, ssl->heap, DYNAMIC_TYPE_TLSX);
  178. ssl->dtlsCidInfo = NULL;
  179. return ret;
  180. }
  181. return 0;
  182. }
  183. int TLSX_ConnectionID_Parse(WOLFSSL* ssl, const byte* input, word16 length,
  184. byte isRequest)
  185. {
  186. ConnectionID* id;
  187. CIDInfo* info;
  188. byte cidSize;
  189. TLSX* ext;
  190. ext = TLSX_Find(ssl->extensions, TLSX_CONNECTION_ID);
  191. if (ext == NULL) {
  192. /* CID not enabled */
  193. if (isRequest) {
  194. WOLFSSL_MSG("Received CID ext but it's not enabled, ignoring");
  195. return 0;
  196. }
  197. else {
  198. WOLFSSL_MSG("CID ext not requested by the Client, aborting");
  199. return UNSUPPORTED_EXTENSION;
  200. }
  201. }
  202. info = DtlsCidGetInfo(ssl);
  203. if (info == NULL || info->tx != NULL)
  204. return BAD_STATE_E;
  205. if (length < OPAQUE8_LEN)
  206. return BUFFER_ERROR;
  207. cidSize = *input;
  208. if (cidSize + OPAQUE8_LEN > length)
  209. return BUFFER_ERROR;
  210. if (cidSize > 0) {
  211. id = (ConnectionID*)XMALLOC(sizeof(*id) + cidSize, ssl->heap,
  212. DYNAMIC_TYPE_TLSX);
  213. if (id == NULL)
  214. return MEMORY_ERROR;
  215. XMEMCPY(id->id, input + OPAQUE8_LEN, cidSize);
  216. id->length = cidSize;
  217. info->tx = id;
  218. }
  219. info->negotiated = 1;
  220. if (isRequest)
  221. ext->resp = 1;
  222. return 0;
  223. }
  224. void DtlsCIDOnExtensionsParsed(WOLFSSL* ssl)
  225. {
  226. CIDInfo* info;
  227. info = DtlsCidGetInfo(ssl);
  228. if (info == NULL)
  229. return;
  230. if (!info->negotiated) {
  231. TLSX_Remove(&ssl->extensions, TLSX_CONNECTION_ID, ssl->heap);
  232. return;
  233. }
  234. }
  235. byte DtlsCIDCheck(WOLFSSL* ssl, const byte* input, word16 inputSize)
  236. {
  237. CIDInfo* info;
  238. info = DtlsCidGetInfo(ssl);
  239. if (info == NULL || info->rx == NULL || info->rx->length == 0)
  240. return 0;
  241. if (inputSize < info->rx->length)
  242. return 0;
  243. return XMEMCMP(input, info->rx->id, info->rx->length) == 0;
  244. }
  245. int wolfSSL_dtls_cid_use(WOLFSSL* ssl)
  246. {
  247. int ret;
  248. /* CID is supported on DTLSv1.3 only */
  249. if (!IsAtLeastTLSv1_3(ssl->version))
  250. return WOLFSSL_FAILURE;
  251. ssl->options.useDtlsCID = 1;
  252. ret = TLSX_ConnectionID_Use(ssl);
  253. if (ret != 0)
  254. return ret;
  255. return WOLFSSL_SUCCESS;
  256. }
  257. int wolfSSL_dtls_cid_is_enabled(WOLFSSL* ssl)
  258. {
  259. return DtlsCidGetInfo(ssl) != NULL;
  260. }
  261. int wolfSSL_dtls_cid_set(WOLFSSL* ssl, unsigned char* cid, unsigned int size)
  262. {
  263. ConnectionID* newCid;
  264. CIDInfo* cidInfo;
  265. if (!ssl->options.useDtlsCID)
  266. return WOLFSSL_FAILURE;
  267. cidInfo = DtlsCidGetInfo(ssl);
  268. if (cidInfo == NULL)
  269. return WOLFSSL_FAILURE;
  270. if (cidInfo->rx != NULL) {
  271. XFREE(cidInfo->rx, ssl->heap, DYNAMIC_TYPE_TLSX);
  272. cidInfo->rx = NULL;
  273. }
  274. /* empty CID */
  275. if (size == 0)
  276. return WOLFSSL_SUCCESS;
  277. if (size > DTLS_CID_MAX_SIZE)
  278. return LENGTH_ERROR;
  279. newCid = DtlsCidNew(cid, (byte)size, ssl->heap);
  280. if (newCid == NULL)
  281. return MEMORY_ERROR;
  282. cidInfo->rx = newCid;
  283. return WOLFSSL_SUCCESS;
  284. }
  285. int wolfSSL_dtls_cid_get_rx_size(WOLFSSL* ssl, unsigned int* size)
  286. {
  287. return DtlsCidGetSize(ssl, size, 1);
  288. }
  289. int wolfSSL_dtls_cid_get_rx(WOLFSSL* ssl, unsigned char* buf,
  290. unsigned int bufferSz)
  291. {
  292. return DtlsCidGet(ssl, buf, bufferSz, 1);
  293. }
  294. int wolfSSL_dtls_cid_get_tx_size(WOLFSSL* ssl, unsigned int* size)
  295. {
  296. return DtlsCidGetSize(ssl, size, 0);
  297. }
  298. int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buf,
  299. unsigned int bufferSz)
  300. {
  301. return DtlsCidGet(ssl, buf, bufferSz, 0);
  302. }
  303. #endif /* WOLFSSL_DTLS_CID */