dtls.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. /* dtls.c
  2. *
  3. * Copyright (C) 2006-2023 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. /*
  22. * WOLFSSL_DTLS_NO_HVR_ON_RESUME
  23. * If defined, a DTLS server will not do a cookie exchange on successful
  24. * client resumption: the resumption will be faster (one RTT less) and
  25. * will consume less bandwidth (one ClientHello and one HelloVerifyRequest
  26. * less). On the other hand, if a valid SessionID is collected, forged
  27. * clientHello messages will consume resources on the server.
  28. */
  29. #ifdef HAVE_CONFIG_H
  30. #include <config.h>
  31. #endif
  32. #include <wolfssl/wolfcrypt/settings.h>
  33. #ifndef WOLFCRYPT_ONLY
  34. #include <wolfssl/error-ssl.h>
  35. #include <wolfssl/internal.h>
  36. #include <wolfssl/ssl.h>
  37. #ifdef NO_INLINE
  38. #include <wolfssl/wolfcrypt/misc.h>
  39. #else
  40. #define WOLFSSL_MISC_INCLUDED
  41. #include <wolfcrypt/src/misc.c>
  42. #endif
  43. #ifdef WOLFSSL_DTLS
  44. void DtlsResetState(WOLFSSL* ssl)
  45. {
  46. /* Reset the state so that we can statelessly await the
  47. * ClientHello that contains the cookie. Don't gate on IsAtLeastTLSv1_3
  48. * to handle the edge case when the peer wants a lower version. */
  49. #ifdef WOLFSSL_SEND_HRR_COOKIE
  50. /* Remove cookie so that it will get computed again */
  51. TLSX_Remove(&ssl->extensions, TLSX_COOKIE, ssl->heap);
  52. #endif
  53. /* Reset DTLS window */
  54. #ifdef WOLFSSL_DTLS13
  55. w64Zero(&ssl->dtls13Epochs[0].nextSeqNumber);
  56. w64Zero(&ssl->dtls13Epochs[0].nextPeerSeqNumber);
  57. XMEMSET(ssl->dtls13Epochs[0].window, 0,
  58. sizeof(ssl->dtls13Epochs[0].window));
  59. Dtls13FreeFsmResources(ssl);
  60. #endif
  61. ssl->keys.dtls_expected_peer_handshake_number = 0;
  62. ssl->keys.dtls_handshake_number = 0;
  63. /* Reset states */
  64. ssl->options.serverState = NULL_STATE;
  65. ssl->options.clientState = NULL_STATE;
  66. ssl->options.connectState = CONNECT_BEGIN;
  67. ssl->options.acceptState = ACCEPT_BEGIN;
  68. ssl->options.handShakeState = NULL_STATE;
  69. ssl->msgsReceived.got_client_hello = 0;
  70. ssl->keys.dtls_handshake_number = 0;
  71. ssl->keys.dtls_expected_peer_handshake_number = 0;
  72. ssl->options.clientState = 0;
  73. XMEMSET(ssl->keys.peerSeq->window, 0, sizeof(ssl->keys.peerSeq->window));
  74. XMEMSET(ssl->keys.peerSeq->prevWindow, 0,
  75. sizeof(ssl->keys.peerSeq->prevWindow));
  76. }
  77. #if !defined(NO_WOLFSSL_SERVER)
  78. #if defined(NO_SHA) && defined(NO_SHA256)
  79. #error "DTLS needs either SHA or SHA-256"
  80. #endif /* NO_SHA && NO_SHA256 */
  81. #if !defined(NO_SHA) && defined(NO_SHA256)
  82. #define DTLS_COOKIE_TYPE WC_SHA
  83. #define DTLS_COOKIE_SZ WC_SHA_DIGEST_SIZE
  84. #endif /* !NO_SHA && NO_SHA256 */
  85. #ifndef NO_SHA256
  86. #define DTLS_COOKIE_TYPE WC_SHA256
  87. #define DTLS_COOKIE_SZ WC_SHA256_DIGEST_SIZE
  88. #endif /* !NO_SHA256 */
  89. typedef struct WolfSSL_ConstVector {
  90. word32 size;
  91. const byte* elements;
  92. } WolfSSL_ConstVector;
  93. typedef struct WolfSSL_CH {
  94. ProtocolVersion* pv;
  95. const byte* random;
  96. WolfSSL_ConstVector sessionId;
  97. WolfSSL_ConstVector cookie;
  98. WolfSSL_ConstVector cipherSuite;
  99. WolfSSL_ConstVector compression;
  100. WolfSSL_ConstVector extension;
  101. word32 length;
  102. } WolfSSL_CH;
  103. static int ReadVector8(const byte* input, WolfSSL_ConstVector* v)
  104. {
  105. v->size = *input;
  106. v->elements = input + OPAQUE8_LEN;
  107. return v->size + OPAQUE8_LEN;
  108. }
  109. static int ReadVector16(const byte* input, WolfSSL_ConstVector* v)
  110. {
  111. word16 size16;
  112. ato16(input, &size16);
  113. v->size = (word32)size16;
  114. v->elements = input + OPAQUE16_LEN;
  115. return v->size + OPAQUE16_LEN;
  116. }
  117. static int CreateDtlsCookie(WOLFSSL* ssl, const WolfSSL_CH* ch, byte* cookie)
  118. {
  119. Hmac cookieHmac;
  120. int ret;
  121. ret = wc_HmacInit(&cookieHmac, ssl->heap, ssl->devId);
  122. if (ret != 0)
  123. return ret;
  124. ret = wc_HmacSetKey(&cookieHmac, DTLS_COOKIE_TYPE,
  125. ssl->buffers.dtlsCookieSecret.buffer,
  126. ssl->buffers.dtlsCookieSecret.length);
  127. if (ret != 0)
  128. goto out;
  129. ret = wc_HmacUpdate(&cookieHmac, (const byte*)ssl->buffers.dtlsCtx.peer.sa,
  130. ssl->buffers.dtlsCtx.peer.sz);
  131. if (ret != 0)
  132. goto out;
  133. ret = wc_HmacUpdate(&cookieHmac, (byte*)ch->pv, OPAQUE16_LEN);
  134. if (ret != 0)
  135. goto out;
  136. ret = wc_HmacUpdate(&cookieHmac, (byte*)ch->random, RAN_LEN);
  137. if (ret != 0)
  138. goto out;
  139. ret = wc_HmacUpdate(&cookieHmac, (byte*)ch->sessionId.elements,
  140. ch->sessionId.size);
  141. if (ret != 0)
  142. goto out;
  143. ret = wc_HmacUpdate(&cookieHmac, (byte*)ch->cipherSuite.elements,
  144. ch->cipherSuite.size);
  145. if (ret != 0)
  146. goto out;
  147. ret = wc_HmacUpdate(&cookieHmac, (byte*)ch->compression.elements,
  148. ch->compression.size);
  149. if (ret != 0)
  150. goto out;
  151. ret = wc_HmacFinal(&cookieHmac, cookie);
  152. out:
  153. wc_HmacFree(&cookieHmac);
  154. return ret;
  155. }
  156. static int ParseClientHello(const byte* input, word32 helloSz, WolfSSL_CH* ch)
  157. {
  158. word32 idx = 0;
  159. /* protocol version, random and session id length check */
  160. if (OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
  161. return BUFFER_ERROR;
  162. ch->pv = (ProtocolVersion*)(input + idx);
  163. idx += OPAQUE16_LEN;
  164. ch->random = (byte*)(input + idx);
  165. idx += RAN_LEN;
  166. idx += ReadVector8(input + idx, &ch->sessionId);
  167. if (idx > helloSz - OPAQUE8_LEN)
  168. return BUFFER_ERROR;
  169. idx += ReadVector8(input + idx, &ch->cookie);
  170. if (idx > helloSz - OPAQUE16_LEN)
  171. return BUFFER_ERROR;
  172. idx += ReadVector16(input + idx, &ch->cipherSuite);
  173. if (idx > helloSz - OPAQUE8_LEN)
  174. return BUFFER_ERROR;
  175. idx += ReadVector8(input + idx, &ch->compression);
  176. if (idx > helloSz - OPAQUE16_LEN)
  177. return BUFFER_ERROR;
  178. idx += ReadVector16(input + idx, &ch->extension);
  179. if (idx > helloSz)
  180. return BUFFER_ERROR;
  181. ch->length = idx;
  182. return 0;
  183. }
  184. #ifdef WOLFSSL_DTLS_NO_HVR_ON_RESUME
  185. #ifdef HAVE_SESSION_TICKET
  186. static int TlsxFindByType(WolfSSL_ConstVector* ret, word16 extType,
  187. WolfSSL_ConstVector exts)
  188. {
  189. word32 len, idx = 0;
  190. word16 type;
  191. WolfSSL_ConstVector ext;
  192. XMEMSET(ret, 0, sizeof(*ret));
  193. len = exts.size;
  194. /* type + len */
  195. while (len >= OPAQUE16_LEN + OPAQUE16_LEN) {
  196. ato16(exts.elements + idx, &type);
  197. idx += OPAQUE16_LEN;
  198. idx += ReadVector16(exts.elements + idx, &ext);
  199. if (idx > exts.size)
  200. return BUFFER_ERROR;
  201. if (type == extType) {
  202. XMEMCPY(ret, &ext, sizeof(ext));
  203. return 0;
  204. }
  205. len = exts.size - idx;
  206. }
  207. return 0;
  208. }
  209. static int TlsTicketIsValid(WOLFSSL* ssl, WolfSSL_ConstVector exts,
  210. byte* isValid)
  211. {
  212. WolfSSL_ConstVector tlsxSessionTicket;
  213. byte tempTicket[SESSION_TICKET_LEN];
  214. InternalTicket* it;
  215. int ret;
  216. *isValid = 0;
  217. ret = TlsxFindByType(&tlsxSessionTicket, TLSX_SESSION_TICKET, exts);
  218. if (ret != 0)
  219. return ret;
  220. if (tlsxSessionTicket.size == 0)
  221. return 0;
  222. if (tlsxSessionTicket.size > SESSION_TICKET_LEN)
  223. return 0;
  224. XMEMCPY(tempTicket, tlsxSessionTicket.elements, tlsxSessionTicket.size);
  225. ret = DoDecryptTicket(ssl, tempTicket, (word32)tlsxSessionTicket.size, &it);
  226. if (ret != WOLFSSL_TICKET_RET_OK && ret != WOLFSSL_TICKET_RET_CREATE)
  227. return 0;
  228. ForceZero(it, sizeof(InternalTicket));
  229. *isValid = 1;
  230. return 0;
  231. }
  232. #endif /* HAVE_SESSION_TICKET */
  233. static int TlsSessionIdIsValid(WOLFSSL* ssl, WolfSSL_ConstVector sessionID,
  234. byte* isValid)
  235. {
  236. WOLFSSL_SESSION* sess;
  237. word32 sessRow;
  238. int ret;
  239. *isValid = 0;
  240. if (ssl->options.sessionCacheOff)
  241. return 0;
  242. if (sessionID.size != ID_LEN)
  243. return 0;
  244. #ifdef HAVE_EXT_CACHE
  245. {
  246. if (ssl->ctx->get_sess_cb != NULL) {
  247. int unused;
  248. sess =
  249. ssl->ctx->get_sess_cb(ssl, sessionID.elements, ID_LEN, &unused);
  250. if (sess != NULL) {
  251. *isValid = 1;
  252. wolfSSL_FreeSession(ssl->ctx, sess);
  253. return 0;
  254. }
  255. }
  256. if (ssl->ctx->internalCacheLookupOff)
  257. return 0;
  258. }
  259. #endif
  260. ret = TlsSessionCacheGetAndLock(sessionID.elements, &sess, &sessRow);
  261. if (ret == 0 && sess != NULL) {
  262. *isValid = 1;
  263. TlsSessionCacheUnlockRow(sessRow);
  264. }
  265. return 0;
  266. }
  267. static int TlsResumptionIsValid(WOLFSSL* ssl, WolfSSL_CH* ch, byte* isValid)
  268. {
  269. int ret;
  270. *isValid = 0;
  271. #ifdef HAVE_SESSION_TICKET
  272. ret = TlsTicketIsValid(ssl, ch->extension, isValid);
  273. if (ret != 0)
  274. return ret;
  275. if (*isValid)
  276. return 0;
  277. #endif /* HAVE_SESSION_TICKET */
  278. ret = TlsSessionIdIsValid(ssl, ch->sessionId, isValid);
  279. return ret;
  280. }
  281. #endif /* WOLFSSL_DTLS_NO_HVR_ON_RESUME */
  282. int DoClientHelloStateless(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
  283. word32 helloSz, byte* process)
  284. {
  285. byte cookie[DTLS_COOKIE_SZ];
  286. int ret;
  287. WolfSSL_CH ch;
  288. *process = 1;
  289. ret = ParseClientHello(input + *inOutIdx, helloSz, &ch);
  290. if (ret != 0)
  291. return ret;
  292. #ifdef WOLFSSL_DTLS_NO_HVR_ON_RESUME
  293. {
  294. byte isValid = 0;
  295. ret = TlsResumptionIsValid(ssl, &ch, &isValid);
  296. if (ret != 0)
  297. return ret;
  298. if (isValid)
  299. return 0;
  300. }
  301. #endif /* WOLFSSL_DTLS_NO_HVR_ON_RESUME */
  302. ret = CreateDtlsCookie(ssl, &ch, cookie);
  303. if (ret != 0)
  304. return ret;
  305. if (ch.cookie.size != DTLS_COOKIE_SZ ||
  306. XMEMCMP(ch.cookie.elements, cookie, DTLS_COOKIE_SZ) != 0) {
  307. *process = 0;
  308. ret = SendHelloVerifyRequest(ssl, cookie, DTLS_COOKIE_SZ);
  309. }
  310. return ret;
  311. }
  312. #endif /* !defined(NO_WOLFSSL_SERVER) */
  313. #if defined(WOLFSSL_DTLS_CID)
  314. typedef struct ConnectionID {
  315. byte length;
  316. /* Ignore "nonstandard extension used : zero-sized array in struct/union"
  317. * MSVC warning */
  318. #ifdef _MSC_VER
  319. #pragma warning(disable: 4200)
  320. #endif
  321. byte id[];
  322. } ConnectionID;
  323. typedef struct CIDInfo {
  324. ConnectionID* tx;
  325. ConnectionID* rx;
  326. byte negotiated : 1;
  327. } CIDInfo;
  328. static ConnectionID* DtlsCidNew(const byte* cid, byte size, void* heap)
  329. {
  330. ConnectionID* ret;
  331. ret = (ConnectionID*)XMALLOC(sizeof(ConnectionID) + size, heap,
  332. DYNAMIC_TYPE_TLSX);
  333. if (ret == NULL)
  334. return NULL;
  335. ret->length = size;
  336. XMEMCPY(ret->id, cid, size);
  337. return ret;
  338. }
  339. static WC_INLINE CIDInfo* DtlsCidGetInfo(WOLFSSL* ssl)
  340. {
  341. return ssl->dtlsCidInfo;
  342. }
  343. static int DtlsCidGetSize(WOLFSSL* ssl, unsigned int* size, int rx)
  344. {
  345. ConnectionID* id;
  346. CIDInfo* info;
  347. if (ssl == NULL || size == NULL)
  348. return BAD_FUNC_ARG;
  349. info = DtlsCidGetInfo(ssl);
  350. if (info == NULL)
  351. return WOLFSSL_FAILURE;
  352. id = rx ? info->rx : info->tx;
  353. if (id == NULL) {
  354. *size = 0;
  355. return WOLFSSL_SUCCESS;
  356. }
  357. *size = id->length;
  358. return WOLFSSL_SUCCESS;
  359. }
  360. static int DtlsCidGet(WOLFSSL* ssl, unsigned char* buf, int bufferSz, int rx)
  361. {
  362. ConnectionID* id;
  363. CIDInfo* info;
  364. if (ssl == NULL || buf == NULL)
  365. return BAD_FUNC_ARG;
  366. info = DtlsCidGetInfo(ssl);
  367. if (info == NULL)
  368. return WOLFSSL_FAILURE;
  369. id = rx ? info->rx : info->tx;
  370. if (id == NULL || id->length == 0)
  371. return WOLFSSL_SUCCESS;
  372. if (id->length > bufferSz)
  373. return LENGTH_ERROR;
  374. XMEMCPY(buf, id->id, id->length);
  375. return WOLFSSL_SUCCESS;
  376. }
  377. static CIDInfo* DtlsCidGetInfoFromExt(byte* ext)
  378. {
  379. WOLFSSL** sslPtr;
  380. WOLFSSL* ssl;
  381. if (ext == NULL)
  382. return NULL;
  383. sslPtr = (WOLFSSL**)ext;
  384. ssl = *sslPtr;
  385. if (ssl == NULL)
  386. return NULL;
  387. return ssl->dtlsCidInfo;
  388. }
  389. static void DtlsCidUnsetInfoFromExt(byte* ext)
  390. {
  391. WOLFSSL** sslPtr;
  392. WOLFSSL* ssl;
  393. if (ext == NULL)
  394. return;
  395. sslPtr = (WOLFSSL**)ext;
  396. ssl = *sslPtr;
  397. if (ssl == NULL)
  398. return;
  399. ssl->dtlsCidInfo = NULL;
  400. }
  401. void TLSX_ConnectionID_Free(byte* ext, void* heap)
  402. {
  403. CIDInfo* info;
  404. (void)heap;
  405. info = DtlsCidGetInfoFromExt(ext);
  406. if (info == NULL)
  407. return;
  408. if (info->rx != NULL)
  409. XFREE(info->rx, heap, DYNAMIC_TYPE_TLSX);
  410. if (info->tx != NULL)
  411. XFREE(info->tx, heap, DYNAMIC_TYPE_TLSX);
  412. XFREE(info, heap, DYNAMIC_TYPE_TLSX);
  413. DtlsCidUnsetInfoFromExt(ext);
  414. XFREE(ext, heap, DYNAMIC_TYPE_TLSX);
  415. }
  416. word16 TLSX_ConnectionID_Write(byte* ext, byte* output)
  417. {
  418. CIDInfo* info;
  419. info = DtlsCidGetInfoFromExt(ext);
  420. if (info == NULL)
  421. return 0;
  422. /* empty CID */
  423. if (info->rx == NULL) {
  424. *output = 0;
  425. return OPAQUE8_LEN;
  426. }
  427. *output = info->rx->length;
  428. XMEMCPY(output + OPAQUE8_LEN, info->rx->id, info->rx->length);
  429. return OPAQUE8_LEN + info->rx->length;
  430. }
  431. word16 TLSX_ConnectionID_GetSize(byte* ext)
  432. {
  433. CIDInfo* info = DtlsCidGetInfoFromExt(ext);
  434. if (info == NULL)
  435. return 0;
  436. return info->rx == NULL ? OPAQUE8_LEN : OPAQUE8_LEN + info->rx->length;
  437. }
  438. int TLSX_ConnectionID_Use(WOLFSSL* ssl)
  439. {
  440. CIDInfo* info;
  441. WOLFSSL** ext;
  442. int ret;
  443. ext = (WOLFSSL**)TLSX_Find(ssl->extensions, TLSX_CONNECTION_ID);
  444. if (ext != NULL)
  445. return 0;
  446. info = (CIDInfo*)XMALLOC(sizeof(CIDInfo), ssl->heap, DYNAMIC_TYPE_TLSX);
  447. if (info == NULL)
  448. return MEMORY_ERROR;
  449. ext = (WOLFSSL**)XMALLOC(sizeof(WOLFSSL**), ssl->heap, DYNAMIC_TYPE_TLSX);
  450. if (ext == NULL) {
  451. XFREE(info, ssl->heap, DYNAMIC_TYPE_TLSX);
  452. return MEMORY_ERROR;
  453. }
  454. XMEMSET(info, 0, sizeof(CIDInfo));
  455. /* CIDInfo needs to be accessed every time we send or receive a record. To
  456. * avoid the cost of the extension lookup save a pointer to the structure
  457. * inside the SSL object itself, and save a pointer to the SSL object in the
  458. * extension. The extension freeing routine uses te pointer to the SSL
  459. * object to find the structure and to set ssl->dtlsCidInfo pointer to NULL
  460. * after freeing the structure. */
  461. ssl->dtlsCidInfo = info;
  462. *ext = ssl;
  463. ret =
  464. TLSX_Push(&ssl->extensions, TLSX_CONNECTION_ID, (void*)ext, ssl->heap);
  465. if (ret != 0) {
  466. XFREE(info, ssl->heap, DYNAMIC_TYPE_TLSX);
  467. XFREE(ext, ssl->heap, DYNAMIC_TYPE_TLSX);
  468. ssl->dtlsCidInfo = NULL;
  469. return ret;
  470. }
  471. return 0;
  472. }
  473. int TLSX_ConnectionID_Parse(WOLFSSL* ssl, const byte* input, word16 length,
  474. byte isRequest)
  475. {
  476. ConnectionID* id;
  477. CIDInfo* info;
  478. byte cidSize;
  479. TLSX* ext;
  480. ext = TLSX_Find(ssl->extensions, TLSX_CONNECTION_ID);
  481. if (ext == NULL) {
  482. /* CID not enabled */
  483. if (isRequest) {
  484. WOLFSSL_MSG("Received CID ext but it's not enabled, ignoring");
  485. return 0;
  486. }
  487. else {
  488. WOLFSSL_MSG("CID ext not requested by the Client, aborting");
  489. return UNSUPPORTED_EXTENSION;
  490. }
  491. }
  492. info = DtlsCidGetInfo(ssl);
  493. if (info == NULL)
  494. return BAD_STATE_E;
  495. /* it may happen if we process two ClientHello because the server sent an
  496. * HRR request */
  497. if (info->tx != NULL) {
  498. if (ssl->options.side != WOLFSSL_SERVER_END &&
  499. ssl->options.serverState != SERVER_HELLO_RETRY_REQUEST_COMPLETE)
  500. return BAD_STATE_E;
  501. XFREE(info->tx, ssl->heap, DYNAMIC_TYPE_TLSX);
  502. info->tx = NULL;
  503. }
  504. if (length < OPAQUE8_LEN)
  505. return BUFFER_ERROR;
  506. cidSize = *input;
  507. if (cidSize + OPAQUE8_LEN > length)
  508. return BUFFER_ERROR;
  509. if (cidSize > 0) {
  510. id = (ConnectionID*)XMALLOC(sizeof(*id) + cidSize, ssl->heap,
  511. DYNAMIC_TYPE_TLSX);
  512. if (id == NULL)
  513. return MEMORY_ERROR;
  514. XMEMCPY(id->id, input + OPAQUE8_LEN, cidSize);
  515. id->length = cidSize;
  516. info->tx = id;
  517. }
  518. info->negotiated = 1;
  519. if (isRequest)
  520. ext->resp = 1;
  521. return 0;
  522. }
  523. void DtlsCIDOnExtensionsParsed(WOLFSSL* ssl)
  524. {
  525. CIDInfo* info;
  526. info = DtlsCidGetInfo(ssl);
  527. if (info == NULL)
  528. return;
  529. if (!info->negotiated) {
  530. TLSX_Remove(&ssl->extensions, TLSX_CONNECTION_ID, ssl->heap);
  531. return;
  532. }
  533. }
  534. byte DtlsCIDCheck(WOLFSSL* ssl, const byte* input, word16 inputSize)
  535. {
  536. CIDInfo* info;
  537. info = DtlsCidGetInfo(ssl);
  538. if (info == NULL || info->rx == NULL || info->rx->length == 0)
  539. return 0;
  540. if (inputSize < info->rx->length)
  541. return 0;
  542. return XMEMCMP(input, info->rx->id, info->rx->length) == 0;
  543. }
  544. int wolfSSL_dtls_cid_use(WOLFSSL* ssl)
  545. {
  546. int ret;
  547. /* CID is supported on DTLSv1.3 only */
  548. if (!IsAtLeastTLSv1_3(ssl->version))
  549. return WOLFSSL_FAILURE;
  550. ssl->options.useDtlsCID = 1;
  551. ret = TLSX_ConnectionID_Use(ssl);
  552. if (ret != 0)
  553. return ret;
  554. return WOLFSSL_SUCCESS;
  555. }
  556. int wolfSSL_dtls_cid_is_enabled(WOLFSSL* ssl)
  557. {
  558. return DtlsCidGetInfo(ssl) != NULL;
  559. }
  560. int wolfSSL_dtls_cid_set(WOLFSSL* ssl, unsigned char* cid, unsigned int size)
  561. {
  562. ConnectionID* newCid;
  563. CIDInfo* cidInfo;
  564. if (!ssl->options.useDtlsCID)
  565. return WOLFSSL_FAILURE;
  566. cidInfo = DtlsCidGetInfo(ssl);
  567. if (cidInfo == NULL)
  568. return WOLFSSL_FAILURE;
  569. if (cidInfo->rx != NULL) {
  570. XFREE(cidInfo->rx, ssl->heap, DYNAMIC_TYPE_TLSX);
  571. cidInfo->rx = NULL;
  572. }
  573. /* empty CID */
  574. if (size == 0)
  575. return WOLFSSL_SUCCESS;
  576. if (size > DTLS_CID_MAX_SIZE)
  577. return LENGTH_ERROR;
  578. newCid = DtlsCidNew(cid, (byte)size, ssl->heap);
  579. if (newCid == NULL)
  580. return MEMORY_ERROR;
  581. cidInfo->rx = newCid;
  582. return WOLFSSL_SUCCESS;
  583. }
  584. int wolfSSL_dtls_cid_get_rx_size(WOLFSSL* ssl, unsigned int* size)
  585. {
  586. return DtlsCidGetSize(ssl, size, 1);
  587. }
  588. int wolfSSL_dtls_cid_get_rx(WOLFSSL* ssl, unsigned char* buf,
  589. unsigned int bufferSz)
  590. {
  591. return DtlsCidGet(ssl, buf, bufferSz, 1);
  592. }
  593. int wolfSSL_dtls_cid_get_tx_size(WOLFSSL* ssl, unsigned int* size)
  594. {
  595. return DtlsCidGetSize(ssl, size, 0);
  596. }
  597. int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buf,
  598. unsigned int bufferSz)
  599. {
  600. return DtlsCidGet(ssl, buf, bufferSz, 0);
  601. }
  602. #endif /* WOLFSSL_DTLS_CID */
  603. #endif /* WOLFSSL_DTLS */
  604. #endif /* WOLFCRYPT_ONLY */