quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

vtls_spack.c (8672B)


      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, 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 
     25 #include "../curl_setup.h"
     26 
     27 #ifdef USE_SSLS_EXPORT
     28 
     29 #include "../urldata.h"
     30 #include "../curl_trc.h"
     31 #include "vtls_scache.h"
     32 #include "vtls_spack.h"
     33 #include "../strdup.h"
     34 
     35 /* The last #include files should be: */
     36 #include "../curl_memory.h"
     37 #include "../memdebug.h"
     38 
     39 #ifdef _MSC_VER
     40 #if _MSC_VER >= 1600
     41 #include <stdint.h>
     42 #else
     43 typedef unsigned char uint8_t;
     44 typedef unsigned __int16 uint16_t;
     45 typedef unsigned __int32 uint32_t;
     46 typedef unsigned __int64 uint64_t;
     47 #endif
     48 #endif /* _MSC_VER */
     49 
     50 #ifndef UINT16_MAX
     51 #define UINT16_MAX    0xffff
     52 #endif
     53 #ifndef UINT32_MAX
     54 #define UINT32_MAX    0xffffffff
     55 #endif
     56 
     57 #define CURL_SPACK_VERSION       0x01
     58 #define CURL_SPACK_IETF_ID       0x02
     59 #define CURL_SPACK_VALID_UNTIL   0x03
     60 #define CURL_SPACK_TICKET        0x04
     61 #define CURL_SPACK_ALPN          0x05
     62 #define CURL_SPACK_EARLYDATA     0x06
     63 #define CURL_SPACK_QUICTP        0x07
     64 
     65 static CURLcode spack_enc8(struct dynbuf *buf, uint8_t b)
     66 {
     67   return curlx_dyn_addn(buf, &b, 1);
     68 }
     69 
     70 static CURLcode
     71 spack_dec8(uint8_t *val, const uint8_t **src, const uint8_t *end)
     72 {
     73   if(end - *src < 1)
     74     return CURLE_READ_ERROR;
     75   *val = **src;
     76   *src += 1;
     77   return CURLE_OK;
     78 }
     79 
     80 static CURLcode spack_enc16(struct dynbuf *buf, uint16_t val)
     81 {
     82   uint8_t nval[2];
     83   nval[0] = (uint8_t)(val >> 8);
     84   nval[1] = (uint8_t)val;
     85   return curlx_dyn_addn(buf, nval, sizeof(nval));
     86 }
     87 
     88 static CURLcode
     89 spack_dec16(uint16_t *val, const uint8_t **src, const uint8_t *end)
     90 {
     91   if(end - *src < 2)
     92     return CURLE_READ_ERROR;
     93   *val = (uint16_t)((*src)[0] << 8 | (*src)[1]);
     94   *src += 2;
     95   return CURLE_OK;
     96 }
     97 
     98 static CURLcode spack_enc32(struct dynbuf *buf, uint32_t val)
     99 {
    100   uint8_t nval[4];
    101   nval[0] = (uint8_t)(val >> 24);
    102   nval[1] = (uint8_t)(val >> 16);
    103   nval[2] = (uint8_t)(val >> 8);
    104   nval[3] = (uint8_t)val;
    105   return curlx_dyn_addn(buf, nval, sizeof(nval));
    106 }
    107 
    108 static CURLcode
    109 spack_dec32(uint32_t *val, const uint8_t **src, const uint8_t *end)
    110 {
    111   if(end - *src < 4)
    112     return CURLE_READ_ERROR;
    113   *val = (uint32_t)(*src)[0] << 24 | (uint32_t)(*src)[1] << 16 |
    114          (uint32_t)(*src)[2] << 8 | (*src)[3];
    115   *src += 4;
    116   return CURLE_OK;
    117 }
    118 
    119 static CURLcode spack_enc64(struct dynbuf *buf, uint64_t val)
    120 {
    121   uint8_t nval[8];
    122   nval[0] = (uint8_t)(val >> 56);
    123   nval[1] = (uint8_t)(val >> 48);
    124   nval[2] = (uint8_t)(val >> 40);
    125   nval[3] = (uint8_t)(val >> 32);                  \
    126   nval[4] = (uint8_t)(val >> 24);
    127   nval[5] = (uint8_t)(val >> 16);
    128   nval[6] = (uint8_t)(val >> 8);
    129   nval[7] = (uint8_t)val;
    130   return curlx_dyn_addn(buf, nval, sizeof(nval));
    131 }
    132 
    133 static CURLcode
    134 spack_dec64(uint64_t *val, const uint8_t **src, const uint8_t *end)
    135 {
    136   if(end - *src < 8)
    137     return CURLE_READ_ERROR;
    138   *val = (uint64_t)(*src)[0] << 56 | (uint64_t)(*src)[1] << 48 |
    139          (uint64_t)(*src)[2] << 40 | (uint64_t)(*src)[3] << 32 |
    140          (uint64_t)(*src)[4] << 24 | (uint64_t)(*src)[5] << 16 |
    141          (uint64_t)(*src)[6] << 8 | (*src)[7];
    142   *src += 8;
    143   return CURLE_OK;
    144 }
    145 
    146 static CURLcode spack_encstr16(struct dynbuf *buf, const char *s)
    147 {
    148   size_t slen = strlen(s);
    149   CURLcode r;
    150   if(slen > UINT16_MAX)
    151     return CURLE_BAD_FUNCTION_ARGUMENT;
    152   r = spack_enc16(buf, (uint16_t)slen);
    153   if(!r) {
    154     r = curlx_dyn_addn(buf, s, slen);
    155   }
    156   return r;
    157 }
    158 
    159 static CURLcode
    160 spack_decstr16(char **val, const uint8_t **src, const uint8_t *end)
    161 {
    162   uint16_t slen;
    163   CURLcode r;
    164 
    165   *val = NULL;
    166   r = spack_dec16(&slen, src, end);
    167   if(r)
    168     return r;
    169   if(end - *src < slen)
    170     return CURLE_READ_ERROR;
    171   *val = Curl_memdup0((const char *)(*src), slen);
    172   *src += slen;
    173   return *val ? CURLE_OK : CURLE_OUT_OF_MEMORY;
    174 }
    175 
    176 static CURLcode spack_encdata16(struct dynbuf *buf,
    177                                 const uint8_t *data, size_t data_len)
    178 {
    179   CURLcode r;
    180   if(data_len > UINT16_MAX)
    181     return CURLE_BAD_FUNCTION_ARGUMENT;
    182   r = spack_enc16(buf, (uint16_t)data_len);
    183   if(!r) {
    184     r = curlx_dyn_addn(buf, data, data_len);
    185   }
    186   return r;
    187 }
    188 
    189 static CURLcode
    190 spack_decdata16(uint8_t **val, size_t *val_len,
    191                 const uint8_t **src, const uint8_t *end)
    192 {
    193   uint16_t data_len;
    194   CURLcode r;
    195 
    196   *val = NULL;
    197   r = spack_dec16(&data_len, src, end);
    198   if(r)
    199     return r;
    200   if(end - *src < data_len)
    201     return CURLE_READ_ERROR;
    202   *val = Curl_memdup0((const char *)(*src), data_len);
    203   *val_len = data_len;
    204   *src += data_len;
    205   return *val ? CURLE_OK : CURLE_OUT_OF_MEMORY;
    206 }
    207 
    208 CURLcode Curl_ssl_session_pack(struct Curl_easy *data,
    209                                struct Curl_ssl_session *s,
    210                                struct dynbuf *buf)
    211 {
    212   CURLcode r;
    213   DEBUGASSERT(s->sdata);
    214   DEBUGASSERT(s->sdata_len);
    215 
    216   if(s->valid_until < 0)
    217     return CURLE_BAD_FUNCTION_ARGUMENT;
    218 
    219   r = spack_enc8(buf, CURL_SPACK_VERSION);
    220   if(!r)
    221     r = spack_enc8(buf, CURL_SPACK_TICKET);
    222   if(!r)
    223     r = spack_encdata16(buf, s->sdata, s->sdata_len);
    224   if(!r)
    225     r = spack_enc8(buf, CURL_SPACK_IETF_ID);
    226   if(!r)
    227     r = spack_enc16(buf, (uint16_t)s->ietf_tls_id);
    228   if(!r)
    229     r = spack_enc8(buf, CURL_SPACK_VALID_UNTIL);
    230   if(!r)
    231     r = spack_enc64(buf, (uint64_t)s->valid_until);
    232   if(!r && s->alpn) {
    233     r = spack_enc8(buf, CURL_SPACK_ALPN);
    234     if(!r)
    235       r = spack_encstr16(buf, s->alpn);
    236   }
    237   if(!r && s->earlydata_max) {
    238     if(s->earlydata_max > UINT32_MAX)
    239       r = CURLE_BAD_FUNCTION_ARGUMENT;
    240     if(!r)
    241       r = spack_enc8(buf, CURL_SPACK_EARLYDATA);
    242     if(!r)
    243       r = spack_enc32(buf, (uint32_t)s->earlydata_max);
    244   }
    245   if(!r && s->quic_tp && s->quic_tp_len) {
    246     r = spack_enc8(buf, CURL_SPACK_QUICTP);
    247     if(!r)
    248       r = spack_encdata16(buf, s->quic_tp, s->quic_tp_len);
    249   }
    250 
    251   if(r)
    252     CURL_TRC_SSLS(data, "error packing data: %d", r);
    253   return r;
    254 }
    255 
    256 CURLcode Curl_ssl_session_unpack(struct Curl_easy *data,
    257                                  const void *bufv, size_t buflen,
    258                                  struct Curl_ssl_session **ps)
    259 {
    260   struct Curl_ssl_session *s = NULL;
    261   const unsigned char *buf = (const unsigned char *)bufv;
    262   const unsigned char *end = buf + buflen;
    263   uint8_t val8, *pval8;
    264   uint16_t val16;
    265   uint32_t val32;
    266   uint64_t val64;
    267   CURLcode r;
    268 
    269   DEBUGASSERT(buf);
    270   DEBUGASSERT(buflen);
    271   *ps = NULL;
    272 
    273   r = spack_dec8(&val8, &buf, end);
    274   if(r)
    275     goto out;
    276   if(val8 != CURL_SPACK_VERSION) {
    277     r = CURLE_READ_ERROR;
    278     goto out;
    279   }
    280 
    281   s = calloc(1, sizeof(*s));
    282   if(!s) {
    283     r = CURLE_OUT_OF_MEMORY;
    284     goto out;
    285   }
    286 
    287   while(buf < end) {
    288     r = spack_dec8(&val8, &buf, end);
    289     if(r)
    290       goto out;
    291 
    292     switch(val8) {
    293     case CURL_SPACK_ALPN:
    294       r = spack_decstr16(&s->alpn, &buf, end);
    295       if(r)
    296         goto out;
    297       break;
    298     case CURL_SPACK_EARLYDATA:
    299       r = spack_dec32(&val32, &buf, end);
    300       if(r)
    301         goto out;
    302       s->earlydata_max = val32;
    303       break;
    304     case CURL_SPACK_IETF_ID:
    305       r = spack_dec16(&val16, &buf, end);
    306       if(r)
    307         goto out;
    308       s->ietf_tls_id = val16;
    309       break;
    310     case CURL_SPACK_QUICTP: {
    311       r = spack_decdata16(&pval8, &s->quic_tp_len, &buf, end);
    312       if(r)
    313         goto out;
    314       s->quic_tp = pval8;
    315       break;
    316     }
    317     case CURL_SPACK_TICKET: {
    318       r = spack_decdata16(&pval8, &s->sdata_len, &buf, end);
    319       if(r)
    320         goto out;
    321       s->sdata = pval8;
    322       break;
    323     }
    324     case CURL_SPACK_VALID_UNTIL:
    325       r = spack_dec64(&val64, &buf, end);
    326       if(r)
    327         goto out;
    328       s->valid_until = (curl_off_t)val64;
    329       break;
    330     default:  /* unknown tag */
    331       r = CURLE_READ_ERROR;
    332       goto out;
    333     }
    334   }
    335 
    336 out:
    337   if(r) {
    338     CURL_TRC_SSLS(data, "error unpacking data: %d", r);
    339     Curl_ssl_session_destroy(s);
    340   }
    341   else
    342     *ps = s;
    343   return r;
    344 }
    345 
    346 #endif /* USE_SSLS_EXPORT */