vtls_spack.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
  9. *
  10. * This software is licensed as described in the file COPYING, which
  11. * you should have received as part of this distribution. The terms
  12. * are also available at https://curl.se/docs/copyright.html.
  13. *
  14. * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  15. * copies of the Software, and permit persons to whom the Software is
  16. * furnished to do so, under the terms of the COPYING file.
  17. *
  18. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  19. * KIND, either express or implied.
  20. *
  21. * SPDX-License-Identifier: curl
  22. *
  23. ***************************************************************************/
  24. #include "../curl_setup.h"
  25. #if defined(USE_SSL) && defined(USE_SSLS_EXPORT)
  26. #include "../urldata.h"
  27. #include "../curl_trc.h"
  28. #include "vtls_scache.h"
  29. #include "vtls_spack.h"
  30. #include "../strdup.h"
  31. /* The last #include files should be: */
  32. #include "../curl_memory.h"
  33. #include "../memdebug.h"
  34. #ifdef _MSC_VER
  35. #if _MSC_VER >= 1600
  36. #include <stdint.h>
  37. #else
  38. typedef unsigned char uint8_t;
  39. typedef unsigned __int16 uint16_t;
  40. typedef unsigned __int32 uint32_t;
  41. typedef unsigned __int64 uint64_t;
  42. #endif
  43. #endif /* _MSC_VER */
  44. #ifndef UINT16_MAX
  45. #define UINT16_MAX 0xffff
  46. #endif
  47. #ifndef UINT32_MAX
  48. #define UINT32_MAX 0xffffffff
  49. #endif
  50. #define CURL_SPACK_VERSION 0x01
  51. #define CURL_SPACK_IETF_ID 0x02
  52. #define CURL_SPACK_VALID_UNTIL 0x03
  53. #define CURL_SPACK_TICKET 0x04
  54. #define CURL_SPACK_ALPN 0x05
  55. #define CURL_SPACK_EARLYDATA 0x06
  56. #define CURL_SPACK_QUICTP 0x07
  57. static CURLcode spack_enc8(struct dynbuf *buf, uint8_t b)
  58. {
  59. return curlx_dyn_addn(buf, &b, 1);
  60. }
  61. static CURLcode
  62. spack_dec8(uint8_t *val, const uint8_t **src, const uint8_t *end)
  63. {
  64. if(end - *src < 1)
  65. return CURLE_READ_ERROR;
  66. *val = **src;
  67. *src += 1;
  68. return CURLE_OK;
  69. }
  70. static CURLcode spack_enc16(struct dynbuf *buf, uint16_t val)
  71. {
  72. uint8_t nval[2];
  73. nval[0] = (uint8_t)(val >> 8);
  74. nval[1] = (uint8_t)val;
  75. return curlx_dyn_addn(buf, nval, sizeof(nval));
  76. }
  77. static CURLcode
  78. spack_dec16(uint16_t *val, const uint8_t **src, const uint8_t *end)
  79. {
  80. if(end - *src < 2)
  81. return CURLE_READ_ERROR;
  82. *val = (uint16_t)((*src)[0] << 8 | (*src)[1]);
  83. *src += 2;
  84. return CURLE_OK;
  85. }
  86. static CURLcode spack_enc32(struct dynbuf *buf, uint32_t val)
  87. {
  88. uint8_t nval[4];
  89. nval[0] = (uint8_t)(val >> 24);
  90. nval[1] = (uint8_t)(val >> 16);
  91. nval[2] = (uint8_t)(val >> 8);
  92. nval[3] = (uint8_t)val;
  93. return curlx_dyn_addn(buf, nval, sizeof(nval));
  94. }
  95. static CURLcode
  96. spack_dec32(uint32_t *val, const uint8_t **src, const uint8_t *end)
  97. {
  98. if(end - *src < 4)
  99. return CURLE_READ_ERROR;
  100. *val = (uint32_t)(*src)[0] << 24 | (uint32_t)(*src)[1] << 16 |
  101. (uint32_t)(*src)[2] << 8 | (*src)[3];
  102. *src += 4;
  103. return CURLE_OK;
  104. }
  105. static CURLcode spack_enc64(struct dynbuf *buf, uint64_t val)
  106. {
  107. uint8_t nval[8];
  108. nval[0] = (uint8_t)(val >> 56);
  109. nval[1] = (uint8_t)(val >> 48);
  110. nval[2] = (uint8_t)(val >> 40);
  111. nval[3] = (uint8_t)(val >> 32); \
  112. nval[4] = (uint8_t)(val >> 24);
  113. nval[5] = (uint8_t)(val >> 16);
  114. nval[6] = (uint8_t)(val >> 8);
  115. nval[7] = (uint8_t)val;
  116. return curlx_dyn_addn(buf, nval, sizeof(nval));
  117. }
  118. static CURLcode
  119. spack_dec64(uint64_t *val, const uint8_t **src, const uint8_t *end)
  120. {
  121. if(end - *src < 8)
  122. return CURLE_READ_ERROR;
  123. *val = (uint64_t)(*src)[0] << 56 | (uint64_t)(*src)[1] << 48 |
  124. (uint64_t)(*src)[2] << 40 | (uint64_t)(*src)[3] << 32 |
  125. (uint64_t)(*src)[4] << 24 | (uint64_t)(*src)[5] << 16 |
  126. (uint64_t)(*src)[6] << 8 | (*src)[7];
  127. *src += 8;
  128. return CURLE_OK;
  129. }
  130. static CURLcode spack_encstr16(struct dynbuf *buf, const char *s)
  131. {
  132. size_t slen = strlen(s);
  133. CURLcode r;
  134. if(slen > UINT16_MAX)
  135. return CURLE_BAD_FUNCTION_ARGUMENT;
  136. r = spack_enc16(buf, (uint16_t)slen);
  137. if(!r) {
  138. r = curlx_dyn_addn(buf, s, slen);
  139. }
  140. return r;
  141. }
  142. static CURLcode
  143. spack_decstr16(char **val, const uint8_t **src, const uint8_t *end)
  144. {
  145. uint16_t slen;
  146. CURLcode r;
  147. *val = NULL;
  148. r = spack_dec16(&slen, src, end);
  149. if(r)
  150. return r;
  151. if(end - *src < slen)
  152. return CURLE_READ_ERROR;
  153. *val = Curl_memdup0((const char *)(*src), slen);
  154. *src += slen;
  155. return *val ? CURLE_OK : CURLE_OUT_OF_MEMORY;
  156. }
  157. static CURLcode spack_encdata16(struct dynbuf *buf,
  158. const uint8_t *data, size_t data_len)
  159. {
  160. CURLcode r;
  161. if(data_len > UINT16_MAX)
  162. return CURLE_BAD_FUNCTION_ARGUMENT;
  163. r = spack_enc16(buf, (uint16_t)data_len);
  164. if(!r) {
  165. r = curlx_dyn_addn(buf, data, data_len);
  166. }
  167. return r;
  168. }
  169. static CURLcode
  170. spack_decdata16(uint8_t **val, size_t *val_len,
  171. const uint8_t **src, const uint8_t *end)
  172. {
  173. uint16_t data_len;
  174. CURLcode r;
  175. *val = NULL;
  176. r = spack_dec16(&data_len, src, end);
  177. if(r)
  178. return r;
  179. if(end - *src < data_len)
  180. return CURLE_READ_ERROR;
  181. *val = Curl_memdup0((const char *)(*src), data_len);
  182. *val_len = data_len;
  183. *src += data_len;
  184. return *val ? CURLE_OK : CURLE_OUT_OF_MEMORY;
  185. }
  186. CURLcode Curl_ssl_session_pack(struct Curl_easy *data,
  187. struct Curl_ssl_session *s,
  188. struct dynbuf *buf)
  189. {
  190. CURLcode r;
  191. DEBUGASSERT(s->sdata);
  192. DEBUGASSERT(s->sdata_len);
  193. if(s->valid_until < 0)
  194. return CURLE_BAD_FUNCTION_ARGUMENT;
  195. r = spack_enc8(buf, CURL_SPACK_VERSION);
  196. if(!r)
  197. r = spack_enc8(buf, CURL_SPACK_TICKET);
  198. if(!r)
  199. r = spack_encdata16(buf, s->sdata, s->sdata_len);
  200. if(!r)
  201. r = spack_enc8(buf, CURL_SPACK_IETF_ID);
  202. if(!r)
  203. r = spack_enc16(buf, (uint16_t)s->ietf_tls_id);
  204. if(!r)
  205. r = spack_enc8(buf, CURL_SPACK_VALID_UNTIL);
  206. if(!r)
  207. r = spack_enc64(buf, (uint64_t)s->valid_until);
  208. if(!r && s->alpn) {
  209. r = spack_enc8(buf, CURL_SPACK_ALPN);
  210. if(!r)
  211. r = spack_encstr16(buf, s->alpn);
  212. }
  213. if(!r && s->earlydata_max) {
  214. if(s->earlydata_max > UINT32_MAX)
  215. r = CURLE_BAD_FUNCTION_ARGUMENT;
  216. if(!r)
  217. r = spack_enc8(buf, CURL_SPACK_EARLYDATA);
  218. if(!r)
  219. r = spack_enc32(buf, (uint32_t)s->earlydata_max);
  220. }
  221. if(!r && s->quic_tp && s->quic_tp_len) {
  222. r = spack_enc8(buf, CURL_SPACK_QUICTP);
  223. if(!r)
  224. r = spack_encdata16(buf, s->quic_tp, s->quic_tp_len);
  225. }
  226. if(r)
  227. CURL_TRC_SSLS(data, "error packing data: %d", r);
  228. return r;
  229. }
  230. CURLcode Curl_ssl_session_unpack(struct Curl_easy *data,
  231. const void *bufv, size_t buflen,
  232. struct Curl_ssl_session **ps)
  233. {
  234. struct Curl_ssl_session *s = NULL;
  235. const unsigned char *buf = (const unsigned char *)bufv;
  236. const unsigned char *end = buf + buflen;
  237. uint8_t val8, *pval8;
  238. uint16_t val16;
  239. uint32_t val32;
  240. uint64_t val64;
  241. CURLcode r;
  242. DEBUGASSERT(buf);
  243. DEBUGASSERT(buflen);
  244. *ps = NULL;
  245. r = spack_dec8(&val8, &buf, end);
  246. if(r)
  247. goto out;
  248. if(val8 != CURL_SPACK_VERSION) {
  249. r = CURLE_READ_ERROR;
  250. goto out;
  251. }
  252. s = calloc(1, sizeof(*s));
  253. if(!s) {
  254. r = CURLE_OUT_OF_MEMORY;
  255. goto out;
  256. }
  257. while(buf < end) {
  258. r = spack_dec8(&val8, &buf, end);
  259. if(r)
  260. goto out;
  261. switch(val8) {
  262. case CURL_SPACK_ALPN:
  263. r = spack_decstr16(&s->alpn, &buf, end);
  264. if(r)
  265. goto out;
  266. break;
  267. case CURL_SPACK_EARLYDATA:
  268. r = spack_dec32(&val32, &buf, end);
  269. if(r)
  270. goto out;
  271. s->earlydata_max = val32;
  272. break;
  273. case CURL_SPACK_IETF_ID:
  274. r = spack_dec16(&val16, &buf, end);
  275. if(r)
  276. goto out;
  277. s->ietf_tls_id = val16;
  278. break;
  279. case CURL_SPACK_QUICTP: {
  280. r = spack_decdata16(&pval8, &s->quic_tp_len, &buf, end);
  281. if(r)
  282. goto out;
  283. s->quic_tp = pval8;
  284. break;
  285. }
  286. case CURL_SPACK_TICKET: {
  287. r = spack_decdata16(&pval8, &s->sdata_len, &buf, end);
  288. if(r)
  289. goto out;
  290. s->sdata = pval8;
  291. break;
  292. }
  293. case CURL_SPACK_VALID_UNTIL:
  294. r = spack_dec64(&val64, &buf, end);
  295. if(r)
  296. goto out;
  297. s->valid_until = (curl_off_t)val64;
  298. break;
  299. default: /* unknown tag */
  300. r = CURLE_READ_ERROR;
  301. goto out;
  302. }
  303. }
  304. out:
  305. if(r) {
  306. CURL_TRC_SSLS(data, "error unpacking data: %d", r);
  307. Curl_ssl_session_destroy(s);
  308. }
  309. else
  310. *ps = s;
  311. return r;
  312. }
  313. #endif /* USE_SSL && USE_SSLS_EXPORT */