lsquic_handshake.c revision 55cd0b38
1/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc.  See LICENSE. */
2
3#include <assert.h>
4#include <errno.h>
5#include <time.h>
6#include <string.h>
7#include <sys/queue.h>
8#ifndef WIN32
9#include <sys/socket.h>
10#endif
11
12#include <openssl/ssl.h>
13#include <openssl/crypto.h>
14#include <openssl/stack.h>
15#include <openssl/x509.h>
16#include <openssl/rand.h>
17#include <openssl/nid.h>
18#include <zlib.h>
19
20#include "lsquic.h"
21#include "lsquic_types.h"
22#include "lsquic_crypto.h"
23#include "lsquic_str.h"
24#include "lsquic_handshake.h"
25#include "lsquic_parse.h"
26#include "lsquic_crt_compress.h"
27#include "lsquic_util.h"
28#include "lsquic_version.h"
29#include "lsquic_mm.h"
30#include "lsquic_engine_public.h"
31#include "lsquic_hash.h"
32#include "lsquic_buf.h"
33#include "lsquic_qtags.h"
34
35#include "fiu-local.h"
36
37#include "lsquic_ev_log.h"
38
39#define MIN_CHLO_SIZE 1024
40
41#define LSQUIC_LOGGER_MODULE LSQLM_HANDSHAKE
42#include "lsquic_logger.h"
43
44enum handshake_state
45{
46    HSK_CHLO_REJ = 0,
47    HSK_SHLO,
48    HSK_COMPLETED,
49    N_HSK_STATES
50};
51
52#if LSQUIC_KEEP_ENC_SESS_HISTORY
53typedef unsigned char eshist_idx_t;
54
55enum enc_sess_history_event
56{
57    ESHE_EMPTY              =  '\0',
58    ESHE_SET_SNI            =  'I',
59    ESHE_SET_SNO            =  'O',
60    ESHE_SET_STK            =  'K',
61    ESHE_SET_SCID           =  'D',
62    ESHE_SET_PROF           =  'P',
63    ESHE_SET_SRST           =  'S',
64};
65#endif
66
67
68typedef struct hs_ctx_st
69{
70    enum {
71        HSET_TCID     =   (1 << 0),     /* tcid is set */
72        HSET_SMHL     =   (1 << 1),     /* smhl is set */
73        HSET_SCID     =   (1 << 2),
74        HSET_IRTT     =   (1 << 3),
75        HSET_SRST     =   (1 << 4),
76    }           set;
77    enum {
78        HOPT_NSTP     =   (1 << 0),     /* NSTP option present in COPT */
79        HOPT_SREJ     =   (1 << 1),     /* SREJ option present in COPT */
80    }           opts;
81    uint32_t    pdmd;
82    uint32_t    aead;
83    uint32_t    kexs;
84
85    uint32_t    mids;
86    uint32_t    scls;
87    uint32_t    cfcw;
88    uint32_t    sfcw;
89    uint32_t    icsl;
90
91    uint32_t    irtt;
92    uint64_t    rcid;
93    uint32_t    tcid;
94    uint32_t    smhl;
95    uint64_t    sttl;
96    unsigned char scid[SCID_LENGTH];
97    //unsigned char chlo_hash[32]; //SHA256 HASH of CHLO
98    unsigned char nonc[DNONC_LENGTH]; /* 4 tm, 8 orbit ---> REJ, 20 rand */
99    unsigned char  pubs[32];
100    unsigned char srst[SRST_LENGTH];
101
102    uint32_t    rrej;
103    struct lsquic_str ccs;
104    struct lsquic_str sni;   /* 0 rtt */
105    struct lsquic_str ccrt;
106    struct lsquic_str stk;
107    struct lsquic_str sno;
108    struct lsquic_str prof;
109
110    struct lsquic_str csct;
111    struct lsquic_str crt; /* compressed certs buffer */
112    struct lsquic_str scfg_pubs; /* Need to copy PUBS, as KEXS comes after it */
113} hs_ctx_t;
114
115
116struct lsquic_enc_session
117{
118    enum handshake_state hsk_state;
119    enum {
120        ES_RECV_REJ =   1 << 2,
121    }                    es_flags;
122
123    uint8_t have_key; /* 0, no 1, I, 2, D, 3, F */
124    uint8_t peer_have_final_key;
125    uint8_t server_start_use_final_key;
126
127    lsquic_cid_t cid;
128    unsigned char priv_key[32];
129    EVP_AEAD_CTX *enc_ctx_i;
130    EVP_AEAD_CTX *dec_ctx_i;
131
132    /* Have to save the initial key for diversification need */
133    unsigned char enc_key_i[aes128_key_len];
134    unsigned char dec_key_i[aes128_key_len];
135    unsigned char enc_key_nonce_i[aes128_iv_len];
136    unsigned char dec_key_nonce_i[aes128_iv_len];
137
138    EVP_AEAD_CTX *enc_ctx_f;
139    EVP_AEAD_CTX *dec_ctx_f;
140    unsigned char enc_key_nonce_f[aes128_iv_len];
141    unsigned char dec_key_nonce_f[aes128_iv_len];
142
143    hs_ctx_t hs_ctx;
144    lsquic_session_cache_info_t *info;
145    c_cert_item_t *cert_item;
146    SSL_CTX *  ssl_ctx;
147    const struct lsquic_engine_public *enpub;
148    struct lsquic_str * cert_ptr; /* pointer to the leaf cert of the server, not real copy */
149    struct lsquic_str   chlo; /* real copy of CHLO message */
150    struct lsquic_str   sstk;
151    struct lsquic_str   ssno;
152
153#if LSQUIC_KEEP_ENC_SESS_HISTORY
154    eshist_idx_t        es_hist_idx;
155    unsigned char       es_hist_buf[1 << ESHIST_BITS];
156#endif
157};
158
159
160
161/* client */
162static c_cert_item_t *make_c_cert_item(struct lsquic_str **certs, int count);
163static void free_c_cert_item(c_cert_item_t *item);
164
165static int get_tag_val_u32 (unsigned char *v, int len, uint32_t *val);
166static int init_hs_hash_tables(int flags);
167static uint32_t get_tag_value_i32(unsigned char *, int);
168static uint64_t get_tag_value_i64(unsigned char *, int);
169
170static int determine_keys(lsquic_enc_session_t *enc_session);
171
172
173#if LSQUIC_KEEP_ENC_SESS_HISTORY
174static void
175eshist_append (lsquic_enc_session_t *enc_session,
176                                        enum enc_sess_history_event eh_event)
177{
178    enc_session->es_hist_buf[
179                    ESHIST_MASK & enc_session->es_hist_idx++ ] = eh_event;
180}
181
182
183#   define ESHIST_APPEND(sess, event) eshist_append(sess, event)
184#else
185#   define ESHIST_APPEND(sess, event) do { } while (0)
186#endif
187
188static int
189lsquic_handshake_init(int flags)
190{
191    crypto_init();
192    return init_hs_hash_tables(flags);
193}
194
195
196static void
197lsquic_handshake_cleanup (void)
198{
199    lsquic_crt_cleanup();
200}
201
202
203/* return -1 for fail, 0 OK*/
204static int init_hs_hash_tables(int flags)
205{
206
207    return 0;
208}
209
210
211/* client */
212static c_cert_item_t *
213make_c_cert_item (lsquic_str_t **certs, int count)
214{
215    int i;
216    uint64_t hash;
217    c_cert_item_t *item = (c_cert_item_t *)malloc(sizeof(c_cert_item_t));
218    item->crts = (lsquic_str_t *)malloc(count * sizeof(lsquic_str_t));
219    item->hashs = lsquic_str_new(NULL, 0);
220    item->count = count;
221    for (i = 0; i < count; ++i)
222    {
223        lsquic_str_copy(&item->crts[i], certs[i]);
224        hash = fnv1a_64((const uint8_t *)lsquic_str_cstr(certs[i]),
225                        lsquic_str_len(certs[i]));
226        lsquic_str_append(item->hashs, (char *)&hash, 8);
227    }
228    return item;
229}
230
231
232/* client */
233static void
234free_c_cert_item (c_cert_item_t *item)
235{
236    int i;
237    if (item)
238    {
239        lsquic_str_delete(item->hashs);
240        for(i=0; i<item->count; ++i)
241            lsquic_str_d(&item->crts[i]);
242        free(item->crts);
243        free(item);
244    }
245}
246
247
248enum rtt_deserialize_return_type
249{
250    RTT_DESERIALIZE_OK              = 0,
251    RTT_DESERIALIZE_BAD_QUIC_VER    = 1,
252    RTT_DESERIALIZE_BAD_SERIAL_VER  = 2,
253    RTT_DESERIALIZE_BAD_CERT_SIZE   = 3,
254};
255
256#define RTT_SERIALIZER_VERSION  (1 << 0)
257
258static void
259lsquic_enc_session_serialize_zero_rtt(struct lsquic_zero_rtt_storage *storage,
260                                        enum lsquic_version version,
261                                        const lsquic_session_cache_info_t *info,
262                                                const c_cert_item_t *cert_item)
263{
264    uint32_t i;
265    uint32_t *cert_len;
266    uint8_t *cert_data;
267    /*
268     * assign versions
269     */
270    storage->quic_version_tag = lsquic_ver2tag(version);
271    storage->serializer_version = RTT_SERIALIZER_VERSION;
272    /*
273     * server config
274     */
275    storage->ver = info->ver;
276    storage->aead = info->aead;
277    storage->kexs = info->kexs;
278    storage->pdmd = info->pdmd;
279    storage->orbt = info->orbt;
280    storage->expy = info->expy;
281    storage->sstk_len = lsquic_str_len(&info->sstk);
282    storage->scfg_len = lsquic_str_len(&info->scfg);
283    storage->scfg_flag = info->scfg_flag;
284    memcpy(storage->sstk, lsquic_str_buf(&info->sstk), storage->sstk_len);
285    memcpy(storage->scfg, lsquic_str_buf(&info->scfg), storage->scfg_len);
286    memcpy(storage->sscid, &info->sscid, SCID_LENGTH);
287    memcpy(storage->spubs, &info->spubs, MAX_SPUBS_LENGTH);
288    /*
289     * certificate chain
290     */
291    storage->cert_count = (uint32_t)cert_item->count;
292    cert_len = (uint32_t *)(storage + 1);
293    cert_data = (uint8_t *)(cert_len + 1);
294    for (i = 0; i < storage->cert_count; i++)
295    {
296        *cert_len = lsquic_str_len(&cert_item->crts[i]);
297        memcpy(cert_data, lsquic_str_buf(&cert_item->crts[i]), *cert_len);
298        cert_len = (uint32_t *)(cert_data + *cert_len);
299        cert_data = (uint8_t *)(cert_len + 1);
300    }
301}
302
303
304#define CHECK_SPACE(need, start, end) \
305    do { if ((intptr_t) (need) > ((intptr_t) (end) - (intptr_t) (start))) \
306        { return RTT_DESERIALIZE_BAD_CERT_SIZE; } \
307    } while (0) \
308
309static enum rtt_deserialize_return_type
310lsquic_enc_session_deserialize_zero_rtt(
311                                const struct lsquic_zero_rtt_storage *storage,
312                                                        size_t storage_size,
313                                const struct lsquic_engine_settings *settings,
314                                            lsquic_session_cache_info_t *info,
315                                                    c_cert_item_t *cert_item)
316{
317    enum lsquic_version ver;
318    uint32_t i, len;
319    uint64_t hash;
320    uint32_t *cert_len;
321    uint8_t *cert_data;
322    void *storage_end = (uint8_t *)storage + storage_size;
323    /*
324     * check versions
325     */
326    ver = lsquic_tag2ver(storage->quic_version_tag);
327    if ((int)ver == -1 || !((1 << ver) & settings->es_versions))
328        return RTT_DESERIALIZE_BAD_QUIC_VER;
329    if (storage->serializer_version != RTT_SERIALIZER_VERSION)
330        return RTT_DESERIALIZE_BAD_SERIAL_VER;
331    /*
332     * server config
333     */
334    info->ver = storage->ver;
335    info->aead = storage->aead;
336    info->kexs = storage->kexs;
337    info->pdmd = storage->pdmd;
338    info->orbt = storage->orbt;
339    info->expy = storage->expy;
340    info->scfg_flag = storage->scfg_flag;
341    lsquic_str_setto(&info->sstk, storage->sstk, storage->sstk_len);
342    lsquic_str_setto(&info->scfg, storage->scfg, storage->scfg_len);
343    memcpy(&info->sscid, storage->sscid, SCID_LENGTH);
344    memcpy(&info->spubs, storage->spubs, MAX_SPUBS_LENGTH);
345    /*
346     * certificate chain
347     */
348    cert_item->count = storage->cert_count;
349    cert_item->crts = malloc(cert_item->count * sizeof(lsquic_str_t));
350    cert_item->hashs = lsquic_str_new(NULL, 0);
351    cert_len = (uint32_t *)(storage + 1);
352    for (i = 0; i < storage->cert_count; i++)
353    {
354        CHECK_SPACE(sizeof(uint32_t), cert_len, storage_end);
355        cert_data = (uint8_t *)(cert_len + 1);
356        memcpy(&len, cert_len, sizeof(len));
357        CHECK_SPACE(len, cert_data, storage_end);
358        lsquic_str_prealloc(&cert_item->crts[i], len);
359        lsquic_str_setlen(&cert_item->crts[i], len);
360        memcpy(lsquic_str_buf(&cert_item->crts[i]), cert_data, len);
361        hash = fnv1a_64((const uint8_t *)cert_data, len);
362        lsquic_str_append(cert_item->hashs, (char *)&hash, 8);
363        cert_len = (uint32_t *)(cert_data + len);
364    }
365    return RTT_DESERIALIZE_OK;
366}
367
368
369static lsquic_enc_session_t *
370lsquic_enc_session_create_client (const char *domain, lsquic_cid_t cid,
371                                    const struct lsquic_engine_public *enpub,
372                                    const unsigned char *zero_rtt, size_t zero_rtt_len)
373{
374    lsquic_session_cache_info_t *info;
375    lsquic_enc_session_t *enc_session;
376    c_cert_item_t *item;
377    const struct lsquic_zero_rtt_storage *zero_rtt_storage;
378
379    if (!domain)
380    {
381        errno = EINVAL;
382        return NULL;
383    }
384
385    enc_session = calloc(1, sizeof(*enc_session));
386    if (!enc_session)
387        return NULL;
388
389    /* have to allocate every time */
390    info = calloc(1, sizeof(*info));
391    if (!info)
392    {
393        free(enc_session);
394        return NULL;
395    }
396
397    if (zero_rtt && zero_rtt_len > sizeof(struct lsquic_zero_rtt_storage))
398    {
399        item = calloc(1, sizeof(*item));
400        if (!item)
401        {
402            free(enc_session);
403            free(info);
404            return NULL;
405        }
406        zero_rtt_storage = (const struct lsquic_zero_rtt_storage *)zero_rtt;
407        switch (lsquic_enc_session_deserialize_zero_rtt(zero_rtt_storage,
408                                                        zero_rtt_len,
409                                                        &enpub->enp_settings,
410                                                        info, item))
411        {
412            case RTT_DESERIALIZE_BAD_QUIC_VER:
413                LSQ_ERROR("provided zero_rtt has unsupported QUIC version");
414                free(item);
415                break;
416            case RTT_DESERIALIZE_BAD_SERIAL_VER:
417                LSQ_ERROR("provided zero_rtt has bad serializer version");
418                free(item);
419                break;
420            case RTT_DESERIALIZE_BAD_CERT_SIZE:
421                LSQ_ERROR("provided zero_rtt has bad cert size");
422                free(item);
423                break;
424            case RTT_DESERIALIZE_OK:
425                memcpy(enc_session->hs_ctx.pubs, info->spubs, 32);
426                enc_session->cert_item = item;
427                break;
428        }
429    }
430    enc_session->enpub = enpub;
431    enc_session->cid   = cid;
432    enc_session->info  = info;
433    /* FIXME: allocation may fail */
434    lsquic_str_append(&enc_session->hs_ctx.sni, domain, strlen(domain));
435    return enc_session;
436}
437
438
439static void
440lsquic_enc_session_destroy (lsquic_enc_session_t *enc_session)
441{
442    if (!enc_session)
443        return ;
444
445    hs_ctx_t *hs_ctx = &enc_session->hs_ctx;
446    lsquic_str_d(&hs_ctx->sni);
447    lsquic_str_d(&hs_ctx->ccs);
448    lsquic_str_d(&hs_ctx->ccrt);
449    lsquic_str_d(&hs_ctx->stk);
450    lsquic_str_d(&hs_ctx->sno);
451    lsquic_str_d(&hs_ctx->prof);
452    lsquic_str_d(&hs_ctx->csct);
453    lsquic_str_d(&hs_ctx->crt);
454    lsquic_str_d(&hs_ctx->scfg_pubs);
455    lsquic_str_d(&enc_session->chlo);
456    lsquic_str_d(&enc_session->sstk);
457    lsquic_str_d(&enc_session->ssno);
458    if (enc_session->dec_ctx_i)
459    {
460        EVP_AEAD_CTX_cleanup(enc_session->dec_ctx_i);
461        free(enc_session->dec_ctx_i);
462    }
463    if (enc_session->enc_ctx_i)
464    {
465        EVP_AEAD_CTX_cleanup(enc_session->enc_ctx_i);
466        free(enc_session->enc_ctx_i);
467    }
468    if (enc_session->dec_ctx_f)
469    {
470        EVP_AEAD_CTX_cleanup(enc_session->dec_ctx_f);
471        free(enc_session->dec_ctx_f);
472    }
473    if (enc_session->enc_ctx_f)
474    {
475        EVP_AEAD_CTX_cleanup(enc_session->enc_ctx_f);
476        free(enc_session->enc_ctx_f);
477    }
478    if (enc_session->info)
479    {
480        lsquic_str_d(&enc_session->info->sstk);
481        lsquic_str_d(&enc_session->info->scfg);
482        lsquic_str_d(&enc_session->info->sni_key);
483        free(enc_session->info);
484    }
485    if (enc_session->cert_item)
486    {
487        free_c_cert_item(enc_session->cert_item);
488        enc_session->cert_item = NULL;
489    }
490    free(enc_session);
491
492}
493
494
495static int get_hs_state(lsquic_enc_session_t *enc_session)
496{
497    return enc_session->hsk_state;
498}
499
500
501/* make sure have more room for encrypt */
502static int
503lsquic_enc_session_is_hsk_done (lsquic_enc_session_t *enc_session)
504{
505    return (get_hs_state(enc_session) == HSK_COMPLETED);
506}
507
508
509static void
510process_copt (lsquic_enc_session_t *enc_session, const uint32_t *const opts,
511                unsigned n_opts)
512{
513    unsigned i;
514    for (i = 0; i < n_opts; ++i)
515        switch (opts[i])
516        {
517        case QTAG_NSTP:
518            enc_session->hs_ctx.opts |= HOPT_NSTP;
519            break;
520        case QTAG_SREJ:
521            enc_session->hs_ctx.opts |= HOPT_SREJ;
522            break;
523        }
524}
525
526
527static int parse_hs_data (lsquic_enc_session_t *enc_session, uint32_t tag,
528                          unsigned char *val, int len, uint32_t head_tag)
529{
530    hs_ctx_t * hs_ctx = &enc_session->hs_ctx;
531
532    switch(tag)
533    {
534    case QTAG_PDMD:
535        hs_ctx->pdmd = get_tag_value_i32(val, len);
536        break;
537
538    case QTAG_MIDS:
539        if (0 != get_tag_val_u32(val, len, &hs_ctx->mids))
540            return -1;
541        break;
542
543    case QTAG_SCLS:
544        hs_ctx->scls = get_tag_value_i32(val, len);
545        break;
546
547    case QTAG_CFCW:
548        if (0 != get_tag_val_u32(val, len, &hs_ctx->cfcw))
549            return -1;
550        break;
551
552    case QTAG_SFCW:
553        if (0 != get_tag_val_u32(val, len, &hs_ctx->sfcw))
554            return -1;
555        break;
556
557    case QTAG_ICSL:
558        hs_ctx->icsl = get_tag_value_i32(val, len);
559        break;
560
561    case QTAG_IRTT:
562        if (0 != get_tag_val_u32(val, len, &hs_ctx->irtt))
563            return -1;
564        hs_ctx->set |= HSET_IRTT;
565        break;
566
567    case QTAG_COPT:
568        if (0 == len % sizeof(uint32_t))
569            process_copt(enc_session, (uint32_t *) val, len / sizeof(uint32_t));
570        /* else ignore, following the reference implementation */
571        break;
572
573    case QTAG_SNI:
574        lsquic_str_setto(&hs_ctx->sni, val, len);
575        ESHIST_APPEND(enc_session, ESHE_SET_SNI);
576        break;
577
578    case QTAG_CCS:
579        lsquic_str_setto(&hs_ctx->ccs, val, len);
580        break;
581
582    case QTAG_CCRT:
583        lsquic_str_setto(&hs_ctx->ccrt, val, len);
584        break;
585
586    case QTAG_CRT:
587        lsquic_str_setto(&hs_ctx->crt, val, len);
588        break;
589
590    case QTAG_PUBS:
591        if (head_tag == QTAG_SCFG)
592            lsquic_str_setto(&hs_ctx->scfg_pubs, val, len);
593        else if (len == 32)
594            memcpy(hs_ctx->pubs, val, len);
595        break;
596
597    case QTAG_RCID:
598        hs_ctx->rcid = get_tag_value_i64(val, len);
599        break;
600
601
602    case QTAG_SMHL:
603        if (0 != get_tag_val_u32(val, len, &hs_ctx->smhl))
604            return -1;
605        hs_ctx->set |= HSET_SMHL;
606        break;
607
608    case QTAG_TCID:
609        if (0 != get_tag_val_u32(val, len, &hs_ctx->tcid))
610            return -1;
611        hs_ctx->set |= HSET_TCID;
612        break;
613
614    case QTAG_EXPY:
615        enc_session->info->expy = get_tag_value_i64(val, len);
616        break;
617
618    case QTAG_ORBT:
619        enc_session->info->orbt = get_tag_value_i64(val, len);
620        break;
621
622    case QTAG_SNO:
623        lsquic_str_setto(&enc_session->ssno, val, len);
624        ESHIST_APPEND(enc_session, ESHE_SET_SNO);
625        break;
626
627    case QTAG_STK:
628        lsquic_str_setto(&enc_session->info->sstk, val, len);
629    ESHIST_APPEND(enc_session, ESHE_SET_STK);
630    break;
631
632    case QTAG_SCID:
633        if (len != SCID_LENGTH)
634            return -1;
635        memcpy(enc_session->info->sscid, val, len);
636        ESHIST_APPEND(enc_session, ESHE_SET_SCID);
637        break;
638
639    case QTAG_AEAD:
640        enc_session->info->aead = get_tag_value_i32(val, len);
641        break;
642
643    case QTAG_KEXS:
644    {
645            if (head_tag == QTAG_SCFG && 0 == len % 4)
646            {
647                const unsigned char *p, *end;
648                unsigned pub_idx, idx;
649#ifdef WIN32
650                pub_idx = 0;
651#endif
652
653                for (p = val; p < val + len; p += 4)
654                    if (0 == memcmp(p, "C255", 4))
655                    {
656                        memcpy(&enc_session->info->kexs, p, 4);
657                        pub_idx = (p - val) / 4;
658                        LSQ_DEBUG("Parsing SCFG: supported KEXS C255 at "
659                                                        "index %u", pub_idx);
660                        break;
661                    }
662                if (p >= val + len)
663                {
664                    LSQ_INFO("supported KEXS not found, trouble ahead");
665                    break;
666                }
667                if (lsquic_str_len(&hs_ctx->scfg_pubs) > 0)
668                {
669                    p = (const unsigned char *)
670                                        lsquic_str_cstr(&hs_ctx->scfg_pubs);
671                    end = p + lsquic_str_len(&hs_ctx->scfg_pubs);
672
673                    for (idx = 0; p < end; ++idx)
674                    {
675                        uint32_t sz = 0;
676                        if (p + 3 > end)
677                            break;
678                        sz |= *p++;
679                        sz |= *p++ << 8;
680                        sz |= *p++ << 16;
681                        if (p + sz > end)
682                            break;
683                        if (idx == pub_idx)
684                        {
685                            if (sz == 32)
686                            {
687                                memcpy(hs_ctx->pubs, p, 32);
688                                memcpy(enc_session->info->spubs, p, 32);
689                            }
690                            break;
691                        }
692                        p += sz;
693                    }
694                }
695                else
696                    LSQ_INFO("No PUBS from SCFG to parse");
697            }
698        }
699        break;
700
701    case QTAG_NONC:
702        if (len != sizeof(hs_ctx->nonc))
703            return -1;
704        memcpy(hs_ctx->nonc, val, len);
705        break;
706
707    case QTAG_SCFG:
708        lsquic_str_setto(&enc_session->info->scfg, val, len);
709        enc_session->info->scfg_flag = 1;
710        break;
711
712    case QTAG_PROF:
713        lsquic_str_setto(&hs_ctx->prof, val, len);
714        ESHIST_APPEND(enc_session, ESHE_SET_PROF);
715        break;
716
717    case QTAG_STTL:
718        hs_ctx->sttl = get_tag_value_i64(val, len);
719        break;
720
721    case QTAG_SRST:
722        if (len != sizeof(hs_ctx->srst))
723        {
724            LSQ_INFO("Unexpected size of SRST: %u instead of %zu bytes",
725                len, sizeof(hs_ctx->srst));
726            return -1;
727        }
728        memcpy(hs_ctx->srst, val, len);
729        hs_ctx->set |= HSET_SRST;
730        ESHIST_APPEND(enc_session, ESHE_SET_SRST);
731        break;
732
733    default:
734        LSQ_DEBUG("Ignored tag '%.*s'", 4, (char *)&tag);
735        break;
736    }
737
738    return 0;
739}
740
741
742/* only for the hs stream-frame data, NOT with the packet header or frame header*/
743static enum handshake_error parse_hs (lsquic_enc_session_t *enc_session,
744                                      const unsigned char *buf, int buf_len,
745                                      uint32_t *head_tag)
746{
747    uint16_t i;
748    const unsigned char *p = buf;
749    const unsigned char *pend = buf + buf_len;
750
751    unsigned char *data;
752    uint32_t len = 0, offset = 0;
753    uint16_t num;
754    uint32_t tag;
755    if (buf_len < 6)
756        return DATA_FORMAT_ERROR;
757
758    memcpy(&tag, p, 4);
759    p += 4;
760
761    {
762        if (tag != QTAG_SREJ && tag != QTAG_REJ && tag != QTAG_SHLO &&
763                                                        tag != QTAG_SCFG)
764            return DATA_FORMAT_ERROR;
765    }
766
767    *head_tag = tag;
768
769    memcpy((char *)&num, p, 2);
770    p += 2 + 2;  /* the 2 bytes padding 0x0000 need to be bypassed */
771
772    if (num < 1)
773        return DATA_FORMAT_ERROR;
774
775    data = (uint8_t *)(buf + 4 * 2 * (1 + num));
776    if ((const char *)data > (const char *)pend)
777    {
778        LSQ_DEBUG("parse_hs tag '%.*s' error: data not enough", 4, (char *)head_tag);
779        return DATA_NOT_ENOUGH;
780    }
781
782    /* check last offset */
783    memcpy((char *)&len, data - 4, 4);
784    if ((const char *)data + len > (const char *)pend)
785    {
786        LSQ_DEBUG("parse_hs tag '%.*s' error: data not enough!!!", 4, (char *)head_tag);
787        return DATA_NOT_ENOUGH;
788    }
789
790    for (i=0; i<num; ++i)
791    {
792        memcpy((char *)&tag, p, 4);
793        p += 4;
794        memcpy((char *)&len, p, 4);
795        len -= offset;
796        p += 4;
797
798        if ((const char *)data + offset + len > (const char *)pend)
799            return DATA_FORMAT_ERROR;
800
801        if (0 != parse_hs_data(enc_session, tag, data + offset, len,
802                                                                *head_tag))
803            return DATA_FORMAT_ERROR;
804        offset += len;
805    }
806
807    LSQ_DEBUG("parse_hs tag '%.*s' no error.", 4, (char *)head_tag);
808    return DATA_NO_ERROR;
809}
810
811
812static uint32_t get_tag_value_i32(unsigned char *val, int len)
813{
814    uint32_t v;
815    if (len < 4)
816        return 0;
817    memcpy(&v, val, 4);
818    return v;
819}
820
821
822static uint64_t get_tag_value_i64(unsigned char *val, int len)
823{
824    uint64_t v;
825    if (len < 8)
826        return 0;
827    memcpy(&v, val, 8);
828    return v;
829}
830
831
832static int
833get_tag_val_u32 (unsigned char *v, int len, uint32_t *val)
834{
835    if (len != 4)
836        return -1;
837    memcpy(val, v, 4);
838    return 0;
839}
840
841
842static void
843generate_cid_buf (void *buf, size_t bufsz)
844{
845    RAND_bytes(buf, bufsz);
846}
847
848
849static lsquic_cid_t
850lsquic_generate_cid (void)
851{
852    lsquic_cid_t cid;
853    generate_cid_buf(&cid, sizeof(cid));
854    return cid;
855}
856
857
858/*  From "QUIC Crypto" for easy reference:
859 *
860 *  A handshake message consists of:
861 *    - The tag of the message.
862 *    - A uint16 containing the number of tag-value pairs.
863 *    - Two bytes of padding which should be zero when sent but ignored when
864 *          received.
865 *    - A series of uint32 tags and uint32 end offsets, one for each
866 *          tag-value pair. The tags must be strictly monotonically
867 *          increasing, and the end-offsets must be monotonic non-decreasing.
868 *          The end offset gives the offset, from the start of the value
869 *          data, to a byte one beyond the end of the data for that tag.
870 *          (Thus the end offset of the last tag contains the length of the
871 *          value data).
872 *    - The value data, concatenated without padding.
873 */
874
875struct table_entry { uint32_t tag, off; };
876
877struct message_writer
878{
879    unsigned char       *mw_p;
880    struct table_entry   mw_first_dummy_entry;
881    struct table_entry  *mw_entry,
882                        *mw_prev_entry,
883                        *mw_end;
884};
885
886/* MW_ family of macros is used to write entries to handshake message
887 * (MW stands for "message writer").
888 */
889#define MW_BEGIN(mw, msg_tag, n_entries, data_ptr) do {             \
890    uint32_t t_ = msg_tag;                                          \
891    uint16_t n_ = n_entries;                                        \
892    memcpy(data_ptr, &t_, 4);                                       \
893    memcpy(data_ptr + 4, &n_, 2);                                   \
894    memset(data_ptr + 4 + 2, 0, 2);                                 \
895    (mw)->mw_entry = (void *) (data_ptr + 8);                       \
896    (mw)->mw_p = data_ptr + 8 +                                     \
897                    (n_entries) * sizeof((mw)->mw_entry[0]);        \
898    (mw)->mw_first_dummy_entry.tag = 0;                             \
899    (mw)->mw_first_dummy_entry.off = 0;                             \
900    (mw)->mw_prev_entry = &(mw)->mw_first_dummy_entry;              \
901    (mw)->mw_end = (void *) (mw)->mw_p;                             \
902} while (0)
903
904#ifndef NDEBUG
905#   define MW_END(mw) do {                                          \
906        assert((mw)->mw_entry == (mw)->mw_end);                     \
907    } while (0)
908#else
909#   define MW_END(mw)
910#endif
911
912#define MW_P(mw) ((mw)->mw_p)
913
914#define MW_ADVANCE_P(mw, n) do {                                    \
915    MW_P(mw) += (n);                                                \
916} while (0)
917
918#define MW_WRITE_TABLE_ENTRY(mw, tag_, sz) do {                     \
919    assert((mw)->mw_prev_entry->tag < (tag_));                      \
920    assert((mw)->mw_entry < (mw)->mw_end);                          \
921    (mw)->mw_entry->tag = (tag_);                                   \
922    (mw)->mw_entry->off = (mw)->mw_prev_entry->off + (sz);          \
923    (mw)->mw_prev_entry = (mw)->mw_entry;                           \
924    ++(mw)->mw_entry;                                               \
925} while (0)
926
927#define MW_WRITE_BUFFER(mw, tag, buf, sz) do {                      \
928    MW_WRITE_TABLE_ENTRY(mw, tag, sz);                              \
929    memcpy(MW_P(mw), buf, sz);                                      \
930    MW_ADVANCE_P(mw, sz);                                           \
931} while (0)
932
933#define MW_WRITE_LS_STR(mw, tag, s) \
934    MW_WRITE_BUFFER(mw, tag, lsquic_str_buf(s), lsquic_str_len(s))
935
936#define MW_WRITE_UINT32(mw, tag, val) do {                          \
937    uint32_t v_ = (val);                                            \
938    MW_WRITE_BUFFER(mw, tag, &v_, sizeof(v_));                      \
939} while (0)
940
941#define MW_WRITE_UINT64(mw, tag, val) do {                          \
942    uint64_t v_ = (val);                                            \
943    MW_WRITE_BUFFER(mw, tag, &v_, sizeof(v_));                      \
944} while (0)
945
946
947/* MSG_LEN_ family of macros calculates buffer size required for a
948 * handshake message.
949 */
950#define MSG_LEN_INIT(len) do {                                      \
951    len = 4 /* Tag */ + 2 /* # tags */ + 2 /* Two zero bytes */;    \
952} while (0)
953
954#define MSG_LEN_ADD(len, payload_sz) do {                           \
955    len += 4 + 4 + (payload_sz);                                    \
956} while (0)
957
958#define MSG_LEN_VAL(len) (+(len))
959
960
961static int
962lsquic_enc_session_gen_chlo (lsquic_enc_session_t *enc_session,
963                        enum lsquic_version version, uint8_t *buf, size_t *len)
964{
965    int ret, include_pad;
966    const lsquic_str_t *const ccs = get_common_certs_hash();
967    const struct lsquic_engine_settings *const settings =
968                                        &enc_session->enpub->enp_settings;
969    c_cert_item_t *const cert_item = enc_session->cert_item;
970    unsigned char pub_key[32];
971    size_t ua_len;
972    uint32_t opts[1];  /* Only NSTP is supported for now */
973    unsigned n_opts, msg_len, n_tags, pad_size;
974    struct message_writer mw;
975
976    /* Before we do anything else, sanity check: */
977    if (*len < MIN_CHLO_SIZE)
978        return -1;
979
980    n_opts = 0;
981    /* CHLO is not regenerated during version negotiation.  Hence we always
982     * include this option to cover the case when Q044 or Q046 gets negotiated
983     * down.
984     */
985    if (settings->es_support_nstp)
986        opts[ n_opts++ ] = QTAG_NSTP;
987
988    /* Count tags and calculate required buffer size: */
989    MSG_LEN_INIT(msg_len);                  n_tags = 0;
990    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* PDMD */
991    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* AEAD */
992    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* VER  */
993    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* MIDS */
994    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* SCLS */
995    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* CFCW */
996    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* SFCW */
997    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* ICSL */
998    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* SMHL */
999    MSG_LEN_ADD(msg_len, 4);                ++n_tags;           /* KEXS */
1000    MSG_LEN_ADD(msg_len, 0);                ++n_tags;           /* CSCT */
1001    if (n_opts > 0)
1002    {
1003        MSG_LEN_ADD(msg_len, sizeof(opts[0]) * n_opts);
1004                                            ++n_tags;           /* COPT */
1005    }
1006    if (settings->es_ua)
1007    {
1008        ua_len = strlen(settings->es_ua);
1009        if (ua_len > 0)
1010        {
1011            MSG_LEN_ADD(msg_len, ua_len);   ++n_tags;           /* UAID */
1012        }
1013    }
1014    else
1015        ua_len = 0;
1016    if (settings->es_support_tcid0)
1017    {
1018        MSG_LEN_ADD(msg_len, 4);            ++n_tags;           /* TCID */
1019    }
1020    MSG_LEN_ADD(msg_len, lsquic_str_len(&enc_session->hs_ctx.sni));
1021                                            ++n_tags;           /* SNI  */
1022    MSG_LEN_ADD(msg_len, lsquic_str_len(ccs));  ++n_tags;           /* CCS  */
1023    if (cert_item)
1024    {
1025        enc_session->cert_ptr = &cert_item->crts[0];
1026        MSG_LEN_ADD(msg_len, lsquic_str_len(cert_item->hashs));
1027                                            ++n_tags;           /* CCRT */
1028        MSG_LEN_ADD(msg_len, 8);            ++n_tags;           /* XLCT */
1029    }
1030    MSG_LEN_ADD(msg_len, lsquic_str_len(&enc_session->ssno));
1031                                            ++n_tags;           /* SNO  */
1032    MSG_LEN_ADD(msg_len, lsquic_str_len(&enc_session->info->sstk));
1033                                            ++n_tags;           /* STK  */
1034    if (lsquic_str_len(&enc_session->info->scfg) > 0)
1035    {
1036        MSG_LEN_ADD(msg_len, sizeof(enc_session->info->sscid));
1037                                            ++n_tags;           /* SCID */
1038        if (enc_session->cert_ptr)
1039        {
1040            MSG_LEN_ADD(msg_len, sizeof(pub_key));
1041                                            ++n_tags;           /* PUBS */
1042            MSG_LEN_ADD(msg_len, sizeof(enc_session->hs_ctx.nonc));
1043                                            ++n_tags;           /* NONC */
1044            rand_bytes(enc_session->priv_key, 32);
1045            c255_get_pub_key(enc_session->priv_key, pub_key);
1046            gen_nonce_c(enc_session->hs_ctx.nonc, enc_session->info->orbt);
1047        }
1048    }
1049    include_pad = MSG_LEN_VAL(msg_len) < MIN_CHLO_SIZE;
1050    if (include_pad)
1051    {
1052        if (MSG_LEN_VAL(msg_len) + sizeof(struct table_entry) < MIN_CHLO_SIZE)
1053            pad_size = MIN_CHLO_SIZE - MSG_LEN_VAL(msg_len) -
1054                                                sizeof(struct table_entry);
1055        else
1056            pad_size = 0;
1057        MSG_LEN_ADD(msg_len, pad_size);     ++n_tags;           /* PAD  */
1058    }
1059#ifdef WIN32
1060    else
1061        pad_size = 0;
1062#endif
1063
1064    /* Check that we have enough room in the output buffer: */
1065    if (MSG_LEN_VAL(msg_len) > *len)
1066        return -1;
1067
1068    /* Write CHLO: */
1069    MW_BEGIN(&mw, QTAG_CHLO, n_tags, buf);
1070    if (include_pad)
1071    {
1072        memset(MW_P(&mw), '-', pad_size);
1073        MW_WRITE_TABLE_ENTRY(&mw, QTAG_PAD, pad_size);
1074        MW_ADVANCE_P(&mw, pad_size);
1075    }
1076    MW_WRITE_LS_STR(&mw, QTAG_SNI, &enc_session->hs_ctx.sni);
1077    MW_WRITE_LS_STR(&mw, QTAG_STK, &enc_session->info->sstk);
1078    MW_WRITE_LS_STR(&mw, QTAG_SNO, &enc_session->ssno);
1079    MW_WRITE_UINT32(&mw, QTAG_VER, lsquic_ver2tag(version));
1080    MW_WRITE_LS_STR(&mw, QTAG_CCS, ccs);
1081    if (lsquic_str_len(&enc_session->info->scfg) > 0 && enc_session->cert_ptr)
1082        MW_WRITE_BUFFER(&mw, QTAG_NONC, enc_session->hs_ctx.nonc,
1083                                        sizeof(enc_session->hs_ctx.nonc));
1084    MW_WRITE_UINT32(&mw, QTAG_AEAD, settings->es_aead);
1085    if (ua_len)
1086        MW_WRITE_BUFFER(&mw, QTAG_UAID, settings->es_ua, ua_len);
1087    if (lsquic_str_len(&enc_session->info->scfg) > 0)
1088        MW_WRITE_BUFFER(&mw, QTAG_SCID, enc_session->info->sscid,
1089                                        sizeof(enc_session->info->sscid));
1090    if (settings->es_support_tcid0)
1091        MW_WRITE_UINT32(&mw, QTAG_TCID, 0);
1092    MW_WRITE_UINT32(&mw, QTAG_PDMD, settings->es_pdmd);
1093    MW_WRITE_UINT32(&mw, QTAG_SMHL, 1);
1094    MW_WRITE_UINT32(&mw, QTAG_ICSL, settings->es_idle_conn_to / 1000000);
1095    if (lsquic_str_len(&enc_session->info->scfg) > 0 && enc_session->cert_ptr)
1096        MW_WRITE_BUFFER(&mw, QTAG_PUBS, pub_key, sizeof(pub_key));
1097    MW_WRITE_UINT32(&mw, QTAG_MIDS, settings->es_max_streams_in);
1098    MW_WRITE_UINT32(&mw, QTAG_SCLS, settings->es_silent_close);
1099    MW_WRITE_UINT32(&mw, QTAG_KEXS, settings->es_kexs);
1100    if (cert_item)
1101        MW_WRITE_BUFFER(&mw, QTAG_XLCT, lsquic_str_buf(cert_item->hashs), 8);
1102    /* CSCT is empty on purpose (retained from original code) */
1103    MW_WRITE_TABLE_ENTRY(&mw, QTAG_CSCT, 0);
1104    if (n_opts > 0)
1105        MW_WRITE_BUFFER(&mw, QTAG_COPT, opts, n_opts * sizeof(opts[0]));
1106    if (cert_item)
1107        MW_WRITE_LS_STR(&mw, QTAG_CCRT, cert_item->hashs);
1108    MW_WRITE_UINT32(&mw, QTAG_CFCW, settings->es_cfcw);
1109    MW_WRITE_UINT32(&mw, QTAG_SFCW, settings->es_sfcw);
1110    MW_END(&mw);
1111    assert(buf + *len >= MW_P(&mw));
1112
1113    *len = MW_P(&mw) - buf;
1114
1115    lsquic_str_setto(&enc_session->chlo, buf, *len);
1116
1117    if (lsquic_str_len(&enc_session->info->scfg) > 0 && enc_session->cert_ptr)
1118    {
1119        enc_session->have_key = 0;
1120        assert(lsquic_str_len(enc_session->cert_ptr) > 0);
1121        ret = determine_keys(enc_session
1122                                            );
1123        enc_session->have_key = 1;
1124    }
1125    else
1126        ret = 0;
1127
1128    LSQ_DEBUG("lsquic_enc_session_gen_chlo called, return %d, buf_len %zd.", ret, *len);
1129    return ret;
1130}
1131
1132
1133static int handle_chlo_reply_verify_prof(lsquic_enc_session_t *enc_session,
1134                                         lsquic_str_t **out_certs,
1135                                         size_t *out_certs_count,
1136                                         lsquic_str_t *cached_certs,
1137                                         int cached_certs_count)
1138{
1139    const unsigned char *const in =
1140                (const unsigned char *) lsquic_str_buf(&enc_session->hs_ctx.crt);
1141    const unsigned char *const in_end =
1142                                    in + lsquic_str_len(&enc_session->hs_ctx.crt);
1143    EVP_PKEY *pub_key;
1144    int ret;
1145    size_t i;
1146    X509 *cert, *server_cert;
1147    STACK_OF(X509) *chain = NULL;
1148    ret = decompress_certs(in, in_end,cached_certs, cached_certs_count,
1149                           out_certs, out_certs_count);
1150    if (ret)
1151        return ret;
1152
1153    server_cert = bio_to_crt((const char *)lsquic_str_cstr(out_certs[0]),
1154                      lsquic_str_len(out_certs[0]), 0);
1155    pub_key = X509_get_pubkey(server_cert);
1156    ret = verify_prof((const uint8_t *)lsquic_str_cstr(&enc_session->chlo),
1157                      (size_t)lsquic_str_len(&enc_session->chlo),
1158                      &enc_session->info->scfg,
1159                      pub_key,
1160                      (const uint8_t *)lsquic_str_cstr(&enc_session->hs_ctx.prof),
1161                      lsquic_str_len(&enc_session->hs_ctx.prof));
1162    EVP_PKEY_free(pub_key);
1163    if (ret != 0)
1164        goto cleanup;
1165
1166    if (enc_session->enpub->enp_verify_cert)
1167    {
1168        chain = sk_X509_new_null();
1169        sk_X509_push(chain, server_cert);
1170        for (i = 1; i < *out_certs_count; ++i)
1171        {
1172            cert = bio_to_crt((const char *)lsquic_str_cstr(out_certs[i]),
1173                                    lsquic_str_len(out_certs[i]), 0);
1174            if (cert)
1175                sk_X509_push(chain, cert);
1176            else
1177            {
1178                LSQ_WARN("cannot push certificate to stack");
1179                ret = -1;
1180                goto cleanup;
1181            }
1182        }
1183        ret = enc_session->enpub->enp_verify_cert(
1184                                enc_session->enpub->enp_verify_ctx, chain);
1185        LSQ_INFO("server certificate verification %ssuccessful",
1186                                                    ret == 0 ? "" : "not ");
1187    }
1188    EV_LOG_CHECK_CERTS(enc_session->cid, (const lsquic_str_t **)out_certs, *out_certs_count);
1189
1190  cleanup:
1191    if (chain)
1192        sk_X509_free(chain);
1193    X509_free(server_cert);
1194    return ret;
1195}
1196
1197
1198void setup_aead_ctx(EVP_AEAD_CTX **ctx, unsigned char key[], int key_len,
1199                    unsigned char *key_copy)
1200{
1201    const EVP_AEAD *aead_ = EVP_aead_aes_128_gcm();
1202    const int auth_tag_size = 12;
1203    if (*ctx)
1204    {
1205        EVP_AEAD_CTX_cleanup(*ctx);
1206    }
1207    else
1208        *ctx = (EVP_AEAD_CTX *)malloc(sizeof(EVP_AEAD_CTX));
1209
1210    EVP_AEAD_CTX_init(*ctx, aead_, key, key_len, auth_tag_size, NULL);
1211    if (key_copy)
1212        memcpy(key_copy, key, key_len);
1213}
1214
1215
1216static int
1217determine_diversification_key (lsquic_enc_session_t *enc_session,
1218                  uint8_t *diversification_nonce
1219                  )
1220{
1221    EVP_AEAD_CTX **ctx_s_key;
1222    unsigned char *key_i, *iv;
1223    uint8_t ikm[aes128_key_len + aes128_iv_len];
1224
1225    ctx_s_key = &enc_session->dec_ctx_i;
1226    key_i = enc_session->dec_key_i;
1227    iv = enc_session->dec_key_nonce_i;
1228    memcpy(ikm, key_i, aes128_key_len);
1229    memcpy(ikm + aes128_key_len, iv, aes128_iv_len);
1230    export_key_material(ikm, aes128_key_len + aes128_iv_len,
1231                        diversification_nonce, DNONC_LENGTH,
1232                        (const unsigned char *) "QUIC key diversification", 24,
1233                        0, NULL, aes128_key_len, key_i, 0, NULL,
1234                        aes128_iv_len, iv, NULL);
1235
1236    setup_aead_ctx(ctx_s_key, key_i, aes128_key_len, NULL);
1237    LSQ_DEBUG("determine_diversification_keys diversification_key: %s\n",
1238              get_bin_str(key_i, aes128_key_len, 512));
1239    LSQ_DEBUG("determine_diversification_keys diversification_key nonce: %s\n",
1240              get_bin_str(iv, aes128_iv_len, 512));
1241    return 0;
1242}
1243
1244
1245/* After CHLO msg generatered, call it to determine_keys */
1246static int determine_keys(lsquic_enc_session_t *enc_session)
1247{
1248    lsquic_str_t *chlo = &enc_session->chlo;
1249    uint8_t shared_key_c[32];
1250    struct lsquic_buf *nonce_c = lsquic_buf_create(100);
1251    struct lsquic_buf *hkdf_input = lsquic_buf_create(0);
1252
1253    unsigned char c_key[aes128_key_len];
1254    unsigned char s_key[aes128_key_len];
1255    unsigned char *c_key_bin = NULL;
1256    unsigned char *s_key_bin = NULL;
1257
1258    unsigned char *c_iv;
1259    unsigned char *s_iv;
1260    unsigned char sub_key[32];
1261    EVP_AEAD_CTX **ctx_c_key, **ctx_s_key;
1262    char key_flag;
1263
1264    lsquic_buf_clear(nonce_c);
1265    lsquic_buf_clear(hkdf_input);
1266    if (enc_session->have_key == 0)
1267    {
1268        lsquic_buf_append(hkdf_input, "QUIC key expansion\0", 18 + 1); // Add a 0x00 */
1269        key_flag = 'I';
1270    }
1271    else
1272    {
1273        lsquic_buf_append(hkdf_input, "QUIC forward secure key expansion\0", 33 + 1); // Add a 0x00 */
1274        key_flag = 'F';
1275    }
1276
1277    c255_gen_share_key(enc_session->priv_key,
1278                       enc_session->hs_ctx.pubs,
1279                       (unsigned char *)shared_key_c);
1280    {
1281        if (enc_session->have_key == 0)
1282        {
1283            ctx_c_key = &enc_session->enc_ctx_i;
1284            ctx_s_key = &enc_session->dec_ctx_i;
1285            c_iv = (unsigned char *) enc_session->enc_key_nonce_i;
1286            s_iv = (unsigned char *) enc_session->dec_key_nonce_i;
1287            c_key_bin = enc_session->enc_key_i;
1288            s_key_bin = enc_session->dec_key_i;
1289        }
1290        else
1291        {
1292            ctx_c_key = &enc_session->enc_ctx_f;
1293            ctx_s_key = &enc_session->dec_ctx_f;
1294            c_iv = (unsigned char *) enc_session->enc_key_nonce_f;
1295            s_iv = (unsigned char *) enc_session->dec_key_nonce_f;
1296        }
1297    }
1298
1299    LSQ_DEBUG("export_key_material c255_gen_share_key %s",
1300              get_bin_str(shared_key_c, 32, 512));
1301
1302    lsquic_buf_append(hkdf_input, (char *)&enc_session->cid, sizeof(enc_session->cid));
1303    lsquic_buf_append(hkdf_input, lsquic_str_cstr(chlo), lsquic_str_len(chlo)); /* CHLO msg */
1304    {
1305        lsquic_buf_append(hkdf_input, lsquic_str_cstr(&enc_session->info->scfg),
1306                       lsquic_str_len(&enc_session->info->scfg)); /* scfg msg */
1307    }
1308    lsquic_buf_append(hkdf_input, lsquic_str_cstr(enc_session->cert_ptr),
1309                   lsquic_str_len(enc_session->cert_ptr));
1310    LSQ_DEBUG("export_key_material hkdf_input %s",
1311              get_bin_str(lsquic_buf_begin(hkdf_input),
1312                          (size_t)lsquic_buf_size(hkdf_input), 512));
1313
1314    /* then need to use the salts and the shared_key_* to get the real aead key */
1315    lsquic_buf_append(nonce_c, (const char *) enc_session->hs_ctx.nonc, 32);
1316    lsquic_buf_append(nonce_c, lsquic_str_cstr(&enc_session->ssno),
1317                   lsquic_str_len(&enc_session->ssno));
1318    LSQ_DEBUG("export_key_material nonce %s",
1319              get_bin_str(lsquic_buf_begin(nonce_c),
1320                          (size_t)lsquic_buf_size(nonce_c), 512));
1321
1322    export_key_material(shared_key_c, 32,
1323                        (unsigned char *)lsquic_buf_begin(nonce_c), lsquic_buf_size(nonce_c),
1324                        (unsigned char *)lsquic_buf_begin(hkdf_input),
1325                        lsquic_buf_size(hkdf_input),
1326                        aes128_key_len, c_key,
1327                        aes128_key_len, s_key,
1328                        aes128_iv_len, c_iv,
1329                        aes128_iv_len, s_iv,
1330                        sub_key);
1331
1332    setup_aead_ctx(ctx_c_key, c_key, aes128_key_len, c_key_bin);
1333    setup_aead_ctx(ctx_s_key, s_key, aes128_key_len, s_key_bin);
1334
1335
1336    lsquic_buf_destroy(nonce_c);
1337    lsquic_buf_destroy(hkdf_input);
1338
1339    LSQ_DEBUG("***export_key_material '%c' c_key: %s", key_flag,
1340              get_bin_str(c_key, aes128_key_len, 512));
1341    LSQ_DEBUG("***export_key_material '%c' s_key: %s", key_flag,
1342              get_bin_str(s_key, aes128_key_len, 512));
1343    LSQ_DEBUG("***export_key_material '%c' c_iv: %s", key_flag,
1344              get_bin_str(c_iv, aes128_iv_len, 512));
1345    LSQ_DEBUG("***export_key_material '%c' s_iv: %s", key_flag,
1346              get_bin_str(s_iv, aes128_iv_len, 512));
1347    LSQ_DEBUG("***export_key_material '%c' subkey: %s", key_flag,
1348              get_bin_str(sub_key, 32, 512));
1349
1350    return 0;
1351}
1352
1353
1354/* 0 Match */
1355static int cached_certs_match(c_cert_item_t *item,
1356                                        lsquic_str_t **certs, int count)
1357{
1358    int i;
1359    if (!item || item->count != count)
1360        return -1;
1361
1362    for (i=0; i<count; ++i)
1363    {
1364        if (lsquic_str_bcmp(certs[i], &item->crts[i]) != 0)
1365            return -1;
1366    }
1367
1368    return 0;
1369}
1370
1371
1372static const char *
1373he2str (enum handshake_error he)
1374{
1375    switch (he)
1376    {
1377    case DATA_NOT_ENOUGH:   return "DATA_NOT_ENOUGH";
1378    case HS_ERROR:          return "HS_ERROR";
1379    case HS_SHLO:           return "HS_SHLO";
1380    case HS_1RTT:           return "HS_1RTT";
1381    case HS_2RTT:           return "HS_2RTT";
1382    default:
1383        assert(0);          return "<unknown enum value>";
1384    }
1385}
1386
1387
1388/* NOT packet, just the frames-data */
1389/* return rtt number:
1390 *      0 OK
1391 *      DATA_NOT_ENOUGH(-2) for not enough data,
1392 *      DATA_FORMAT_ERROR(-1) all other errors
1393 */
1394static int
1395lsquic_enc_session_handle_chlo_reply (lsquic_enc_session_t *enc_session,
1396                                                const uint8_t *data, int len)
1397{
1398    uint32_t head_tag;
1399    int ret;
1400    lsquic_session_cache_info_t *info = enc_session->info;
1401    c_cert_item_t *cert_item = enc_session->cert_item;
1402
1403    /* FIXME get the number first */
1404    lsquic_str_t **out_certs = NULL;
1405    size_t out_certs_count = 0, i;
1406
1407    ret = parse_hs(enc_session, data, len, &head_tag);
1408    if (ret)
1409        goto end;
1410
1411    if (head_tag != QTAG_SREJ &&
1412        head_tag != QTAG_REJ &&
1413        head_tag != QTAG_SHLO)
1414    {
1415        ret = 1;
1416        goto end;
1417    }
1418
1419    if (head_tag == QTAG_SREJ || head_tag == QTAG_REJ)
1420    {
1421        enc_session->hsk_state = HSK_CHLO_REJ;
1422        enc_session->es_flags |= ES_RECV_REJ;
1423    }
1424    else if(head_tag == QTAG_SHLO)
1425    {
1426        enc_session->hsk_state = HSK_COMPLETED;
1427        EV_LOG_HSK_COMPLETED(enc_session->cid);
1428        if (!(enc_session->es_flags & ES_RECV_REJ))
1429            EV_LOG_ZERO_RTT(enc_session->cid);
1430    }
1431
1432    if (info->scfg_flag == 1)
1433    {
1434        ret = parse_hs(enc_session, (uint8_t *)lsquic_str_cstr(&info->scfg),
1435                       lsquic_str_len(&info->scfg), &head_tag);
1436
1437        /* After handled, set the length to 0 to avoid do it again*/
1438        enc_session->info->scfg_flag = 2;
1439        if (ret)
1440            goto end;
1441
1442        if (lsquic_str_len(&enc_session->hs_ctx.crt) > 0)
1443        {
1444            out_certs_count = get_certs_count(&enc_session->hs_ctx.crt);
1445            if (out_certs_count > 0)
1446            {
1447                out_certs = malloc(out_certs_count * sizeof(lsquic_str_t *));
1448                if (!out_certs)
1449                {
1450                    ret = -1;
1451                    goto end;
1452                }
1453
1454                for (i=0; i<out_certs_count; ++i)
1455                    out_certs[i] = lsquic_str_new(NULL, 0);
1456
1457                ret = handle_chlo_reply_verify_prof(enc_session, out_certs,
1458                                            &out_certs_count,
1459                                            (cert_item ? cert_item->crts : NULL),
1460                                            (cert_item ? cert_item->count : 0));
1461                if (ret == 0)
1462                {
1463                    if (out_certs_count > 0)
1464                    {
1465                        if (cached_certs_match(cert_item, out_certs,
1466                                                        out_certs_count) != 0)
1467                        {
1468                            cert_item = make_c_cert_item(out_certs,
1469                                                            out_certs_count);
1470                            enc_session->cert_item = cert_item;
1471                            enc_session->cert_ptr = &cert_item->crts[0];
1472                        }
1473                    }
1474                }
1475                for (i=0; i<out_certs_count; ++i)
1476                    lsquic_str_delete(out_certs[i]);
1477                free(out_certs);
1478
1479                if (ret)
1480                    goto end;
1481            }
1482        }
1483    }
1484
1485    if (enc_session->hsk_state == HSK_COMPLETED)
1486    {
1487        ret = determine_keys(enc_session
1488                                           ); /* FIXME: check ret */
1489        enc_session->have_key = 3;
1490    }
1491
1492  end:
1493    LSQ_DEBUG("lsquic_enc_session_handle_chlo_reply called, buf in %d, return %d.", len, ret);
1494    EV_LOG_CONN_EVENT(enc_session->cid, "%s returning %s", __func__,
1495                                                                he2str(ret));
1496    return ret;
1497}
1498
1499
1500static uint64_t combine_path_id_pack_num(uint8_t path_id, uint64_t pack_num)
1501{
1502    uint64_t v = ((uint64_t)path_id << 56) | pack_num;
1503    return v;
1504}
1505
1506
1507#   define IS_SERVER(session) 0
1508
1509static int
1510verify_packet_hash (const lsquic_enc_session_t *enc_session,
1511    enum lsquic_version version, const unsigned char *buf, size_t *header_len,
1512    size_t data_len, unsigned char *buf_out, size_t max_out_len,
1513    size_t *out_len)
1514{
1515    uint8_t md[HS_PKT_HASH_LENGTH];
1516    uint128 hash;
1517    int ret;
1518
1519    if (data_len < HS_PKT_HASH_LENGTH)
1520        return -1;
1521
1522    if (version >= LSQVER_039)
1523    {
1524        hash = fnv1a_128_3(buf, *header_len,
1525                    buf + *header_len + HS_PKT_HASH_LENGTH,
1526                    data_len - HS_PKT_HASH_LENGTH,
1527                    (unsigned char *) "Server", 6);
1528    }
1529    else
1530    {
1531        hash = fnv1a_128_2(buf, *header_len,
1532                        buf + *header_len + HS_PKT_HASH_LENGTH,
1533                        data_len - HS_PKT_HASH_LENGTH);
1534    }
1535
1536    serialize_fnv128_short(hash, md);
1537    ret = memcmp(md, buf + *header_len, HS_PKT_HASH_LENGTH);
1538    if(ret == 0)
1539    {
1540        *header_len += HS_PKT_HASH_LENGTH;
1541        *out_len = data_len - HS_PKT_HASH_LENGTH;
1542        if (max_out_len < *header_len + *out_len)
1543            return -1;
1544
1545        memcpy(buf_out, buf, *header_len + *out_len);
1546        return 0;
1547    }
1548    else
1549        return -1;
1550}
1551
1552
1553static enum enc_level
1554decrypt_packet (lsquic_enc_session_t *enc_session, uint8_t path_id,
1555                uint64_t pack_num, unsigned char *buf, size_t *header_len,
1556                size_t data_len, unsigned char *buf_out, size_t max_out_len,
1557                size_t *out_len)
1558{
1559    int ret;
1560    /* Comment: 12 = sizeof(dec_key_iv] 4 + sizeof(pack_num) 8 */
1561    uint8_t nonce[12];
1562    uint64_t path_id_packet_number;
1563    EVP_AEAD_CTX *key = NULL;
1564    int try_times = 0;
1565    enum enc_level enc_level;
1566
1567    path_id_packet_number = combine_path_id_pack_num(path_id, pack_num);
1568    memcpy(buf_out, buf, *header_len);
1569    do
1570    {
1571        if (enc_session->have_key == 3 && try_times == 0)
1572        {
1573            key = enc_session->dec_ctx_f;
1574            memcpy(nonce, enc_session->dec_key_nonce_f, 4);
1575            LSQ_DEBUG("decrypt_packet using 'F' key...");
1576            enc_level = ENC_LEV_FORW;
1577        }
1578        else
1579        {
1580            key = enc_session->dec_ctx_i;
1581            memcpy(nonce, enc_session->dec_key_nonce_i, 4);
1582            LSQ_DEBUG("decrypt_packet using 'I' key...");
1583            enc_level = ENC_LEV_INIT;
1584        }
1585        memcpy(nonce + 4, &path_id_packet_number,
1586               sizeof(path_id_packet_number));
1587
1588        *out_len = data_len;
1589        ret = aes_aead_dec(key,
1590                           buf, *header_len,
1591                           nonce, 12,
1592                           buf + *header_len, data_len,
1593                           buf_out + *header_len, out_len);
1594
1595        if (ret != 0)
1596            ++try_times;
1597        else
1598        {
1599            if (enc_session->peer_have_final_key == 0 &&
1600                enc_session->have_key == 3 &&
1601                try_times == 0)
1602            {
1603                LSQ_DEBUG("!!!decrypt_packet find peer have final key.");
1604                enc_session->peer_have_final_key = 1;
1605                EV_LOG_CONN_EVENT(enc_session->cid, "settled on private key "
1606                    "'%c' after %d tries (packet number %"PRIu64")",
1607                    key == enc_session->dec_ctx_f ? 'F' : 'I',
1608                    try_times, pack_num);
1609            }
1610            break;
1611        }
1612    }
1613    while (try_times < 2);
1614
1615    LSQ_DEBUG("***decrypt_packet %s.", (ret == 0 ? "succeed" : "failed"));
1616    return ret == 0 ? enc_level : (enum enc_level) -1;
1617}
1618
1619
1620static int
1621lsquic_enc_session_have_key_gt_one (const lsquic_enc_session_t *enc_session)
1622{
1623    return enc_session && enc_session->have_key > 1;
1624}
1625
1626
1627/* The size of `buf' is *header_len plus data_len.  The two parts of the
1628 * buffer correspond to the header and the payload of incoming QUIC packet.
1629 */
1630static enum enc_level
1631lsquic_enc_session_decrypt (lsquic_enc_session_t *enc_session,
1632               enum lsquic_version version,
1633               uint8_t path_id, uint64_t pack_num,
1634               unsigned char *buf, size_t *header_len, size_t data_len,
1635               unsigned char *diversification_nonce,
1636               unsigned char *buf_out, size_t max_out_len, size_t *out_len)
1637{
1638    /* Client: got SHLO which should have diversification_nonce */
1639    if (diversification_nonce && enc_session && enc_session->have_key == 1)
1640    {
1641        determine_diversification_key(enc_session, diversification_nonce);
1642        enc_session->have_key = 2;
1643    }
1644
1645    if (lsquic_enc_session_have_key_gt_one(enc_session))
1646        return decrypt_packet(enc_session, path_id, pack_num, buf,
1647                        header_len, data_len, buf_out, max_out_len, out_len);
1648    else if (0 == verify_packet_hash(enc_session, version, buf, header_len,
1649                                     data_len, buf_out, max_out_len, out_len))
1650        return ENC_LEV_CLEAR;
1651    else
1652        return -1;
1653}
1654
1655
1656static enum enc_level
1657lsquic_enc_session_encrypt (lsquic_enc_session_t *enc_session,
1658               enum lsquic_version version,
1659               uint8_t path_id, uint64_t pack_num,
1660               const unsigned char *header, size_t header_len,
1661               const unsigned char *data, size_t data_len,
1662               unsigned char *buf_out, size_t max_out_len, size_t *out_len,
1663               int is_hello)
1664{
1665    uint8_t md[HS_PKT_HASH_LENGTH];
1666    uint128 hash;
1667    int ret;
1668    enum enc_level enc_level;
1669    int is_chlo = (is_hello && ((IS_SERVER(enc_session)) == 0));
1670    int is_shlo = (is_hello && (IS_SERVER(enc_session)));
1671
1672    /* Comment: 12 = sizeof(dec_key_iv] 4 + sizeof(pack_num) 8 */
1673    uint8_t nonce[12];
1674    uint64_t path_id_packet_number;
1675    EVP_AEAD_CTX *key;
1676
1677    if (enc_session)
1678        LSQ_DEBUG("%s: hsk_state: %d", __func__, enc_session->hsk_state);
1679    else
1680        LSQ_DEBUG("%s: enc_session is not set", __func__);
1681
1682    if (!enc_session || enc_session->have_key == 0 || is_chlo)
1683    {
1684        *out_len = header_len + data_len + HS_PKT_HASH_LENGTH;
1685        if (max_out_len < *out_len)
1686            return -1;
1687
1688        if (version >= LSQVER_039)
1689        {
1690            hash = fnv1a_128_3(header, header_len, data, data_len,
1691                                        (unsigned char *) "Client", 6);
1692        }
1693        else
1694        {
1695            hash = fnv1a_128_2(header, header_len, data, data_len);
1696        }
1697
1698        serialize_fnv128_short(hash, md);
1699        memcpy(buf_out, header, header_len);
1700        memcpy(buf_out + header_len, md, HS_PKT_HASH_LENGTH);
1701        memcpy(buf_out + header_len + HS_PKT_HASH_LENGTH, data, data_len);
1702        return ENC_LEV_CLEAR;
1703    }
1704    else
1705    {
1706        if (enc_session->have_key != 3 || is_shlo ||
1707            ((IS_SERVER(enc_session)) &&
1708             enc_session->server_start_use_final_key == 0))
1709        {
1710            LSQ_DEBUG("lsquic_enc_session_encrypt using 'I' key...");
1711            key = enc_session->enc_ctx_i;
1712            memcpy(nonce, enc_session->enc_key_nonce_i, 4);
1713            if (is_shlo && enc_session->have_key == 3)
1714            {
1715                enc_session->server_start_use_final_key = 1;
1716            }
1717            enc_level = ENC_LEV_INIT;
1718        }
1719        else
1720        {
1721            LSQ_DEBUG("lsquic_enc_session_encrypt using 'F' key...");
1722            key = enc_session->enc_ctx_f;
1723            memcpy(nonce, enc_session->enc_key_nonce_f, 4);
1724            enc_level = ENC_LEV_FORW;
1725        }
1726        path_id_packet_number = combine_path_id_pack_num(path_id, pack_num);
1727        memcpy(nonce + 4, &path_id_packet_number,
1728               sizeof(path_id_packet_number));
1729
1730        memcpy(buf_out, header, header_len);
1731        *out_len = max_out_len - header_len;
1732
1733        ret = aes_aead_enc(key, header, header_len, nonce, 12, data,
1734                           data_len, buf_out + header_len, out_len);
1735        if (ret == 0)
1736        {
1737            *out_len += header_len;
1738            return enc_level;
1739        }
1740        else
1741            return -1;
1742    }
1743}
1744
1745
1746static int
1747lsquic_enc_session_get_peer_option (const lsquic_enc_session_t *enc_session,
1748                                                                uint32_t tag)
1749{
1750    switch (tag)
1751    {
1752    case QTAG_NSTP:
1753        return !!(enc_session->hs_ctx.opts & HOPT_NSTP);
1754    case QTAG_SREJ:
1755        return !!(enc_session->hs_ctx.opts & HOPT_SREJ);
1756    default:
1757        assert(0);
1758        return 0;
1759    }
1760}
1761
1762
1763/* Query a several parameters sent by the peer that are required by
1764 * connection.
1765 */
1766static int
1767lsquic_enc_session_get_peer_setting (const lsquic_enc_session_t *enc_session,
1768                                        uint32_t tag, uint32_t *val)
1769{
1770    switch (tag)
1771    {
1772    case QTAG_TCID:
1773        if (enc_session->hs_ctx.set & HSET_TCID)
1774        {
1775            *val = enc_session->hs_ctx.tcid;
1776            return 0;
1777        }
1778        else
1779            return -1;
1780    case QTAG_SMHL:
1781        if (enc_session->hs_ctx.set & HSET_SMHL)
1782        {
1783            *val = enc_session->hs_ctx.smhl;
1784            return 0;
1785        }
1786        else
1787            return -1;
1788    case QTAG_IRTT:
1789        if (enc_session->hs_ctx.set & HSET_IRTT)
1790        {
1791            *val = enc_session->hs_ctx.irtt;
1792            return 0;
1793        }
1794        else
1795            return -1;
1796    }
1797
1798    /* XXX For the following values, there is no record which were present
1799     *     in CHLO or SHLO and which were not.  Assume that zero means that
1800     *     they weren't present.
1801     */
1802        switch (tag)
1803        {
1804        case QTAG_CFCW:
1805            if (enc_session->hs_ctx.cfcw)
1806            {
1807                *val = enc_session->hs_ctx.cfcw;
1808                return 0;
1809            }
1810            else
1811                return -1;
1812        case QTAG_SFCW:
1813            if (enc_session->hs_ctx.sfcw)
1814            {
1815                *val = enc_session->hs_ctx.sfcw;
1816                return 0;
1817            }
1818            else
1819                return -1;
1820        case QTAG_MIDS:
1821            if (enc_session->hs_ctx.mids)
1822            {
1823                *val = enc_session->hs_ctx.mids;
1824                return 0;
1825            }
1826            else
1827                return -1;
1828        default:
1829            return -1;
1830        }
1831}
1832
1833
1834#if LSQUIC_KEEP_ENC_SESS_HISTORY
1835static void
1836lsquic_get_enc_hist (const lsquic_enc_session_t *enc_session,
1837                                        char buf[(1 << ESHIST_BITS) + 1])
1838{
1839    const unsigned hist_idx = ESHIST_MASK & enc_session->es_hist_idx;
1840    if (enc_session->es_hist_buf[hist_idx] == ESHE_EMPTY)
1841        memcpy(buf, enc_session->es_hist_buf, hist_idx + 1);
1842    else
1843    {
1844        memcpy(buf, enc_session->es_hist_buf + hist_idx, sizeof(enc_session->es_hist_buf) - hist_idx);
1845        memcpy(buf + hist_idx, enc_session->es_hist_buf, hist_idx);
1846        buf[(1 << ESHIST_BITS)] = '\0';
1847    }
1848}
1849
1850
1851#endif
1852
1853
1854
1855
1856static size_t
1857lsquic_enc_session_mem_used (struct lsquic_enc_session *enc_session)
1858{
1859    size_t size;
1860
1861    size = sizeof(*enc_session);
1862
1863    size += lsquic_str_len(&enc_session->chlo);
1864    size += lsquic_str_len(&enc_session->sstk);
1865    size += lsquic_str_len(&enc_session->ssno);
1866
1867    size += lsquic_str_len(&enc_session->hs_ctx.ccs);
1868    size += lsquic_str_len(&enc_session->hs_ctx.sni);
1869    size += lsquic_str_len(&enc_session->hs_ctx.ccrt);
1870    size += lsquic_str_len(&enc_session->hs_ctx.stk);
1871    size += lsquic_str_len(&enc_session->hs_ctx.sno);
1872    size += lsquic_str_len(&enc_session->hs_ctx.prof);
1873    size += lsquic_str_len(&enc_session->hs_ctx.csct);
1874    size += lsquic_str_len(&enc_session->hs_ctx.crt);
1875
1876    if (enc_session->info)
1877    {
1878        size += sizeof(*enc_session->info);
1879        size += lsquic_str_len(&enc_session->info->sstk);
1880        size += lsquic_str_len(&enc_session->info->scfg);
1881        size += lsquic_str_len(&enc_session->info->sni_key);
1882    }
1883
1884    /* TODO: calculate memory taken up by SSL stuff */
1885
1886    return size;
1887}
1888
1889
1890static int
1891lsquic_enc_session_verify_reset_token (lsquic_enc_session_t *enc_session,
1892                                        const unsigned char *buf, size_t bufsz)
1893{
1894    if (bufsz == SRST_LENGTH
1895            && (enc_session->hs_ctx.set & HSET_SRST)
1896            && 0 == memcmp(buf, enc_session->hs_ctx.srst, SRST_LENGTH))
1897        return 0;
1898    else
1899        return -1;
1900}
1901
1902
1903static int
1904lsquic_enc_session_did_zero_rtt_succeed (const lsquic_enc_session_t *enc_session)
1905{
1906    return !(enc_session->es_flags & ES_RECV_REJ);
1907}
1908
1909
1910static int
1911lsquic_enc_session_is_zero_rtt_enabled (const lsquic_enc_session_t *enc_session)
1912{
1913    return enc_session->info && enc_session->cert_item;
1914}
1915
1916
1917static c_cert_item_t *
1918lsquic_enc_session_get_cert_item (const lsquic_enc_session_t *enc_session)
1919{
1920    return enc_session->cert_item;
1921}
1922
1923
1924static STACK_OF(X509) *
1925lsquic_enc_session_get_server_cert_chain (lsquic_enc_session_t *enc_session)
1926{
1927    const struct c_cert_item_st *item;
1928    STACK_OF(X509) *chain;
1929    X509 *cert;
1930    int i;
1931
1932    item = enc_session->cert_item;
1933    if (!item)
1934    {
1935        LSQ_WARN("could not find certificates for `%.*s'",
1936                            (int) lsquic_str_len(&enc_session->hs_ctx.sni),
1937                            lsquic_str_cstr(&enc_session->hs_ctx.sni));
1938        return NULL;
1939    }
1940
1941    chain = sk_X509_new_null();
1942    for (i = 0; i < item->count; ++i)
1943    {
1944        cert = bio_to_crt(lsquic_str_cstr(&item->crts[i]),
1945                                lsquic_str_len(&item->crts[i]), 0);
1946        if (cert)
1947            sk_X509_push(chain, cert);
1948        else
1949        {
1950            sk_X509_free(chain);
1951            return NULL;
1952        }
1953    }
1954
1955    return chain;
1956}
1957
1958
1959ssize_t
1960lsquic_enc_session_get_zero_rtt (lsquic_enc_session_t *enc_session,
1961                                                enum lsquic_version version,
1962                                                        void *buf, size_t len)
1963{
1964    int i;
1965    size_t sz = 0;
1966    if (!enc_session->info || !enc_session->cert_item)
1967    {
1968        LSQ_DEBUG("client asked for rtt_into but it is not available");
1969        return 0;
1970    }
1971    for (i = 0; i < enc_session->cert_item->count; ++i)
1972    {
1973        sz += sizeof(uint32_t);
1974        sz += lsquic_str_len(&enc_session->cert_item->crts[i]);
1975    }
1976    sz += sizeof(struct lsquic_zero_rtt_storage);
1977    if (len < sz)
1978    {
1979        LSQ_DEBUG("client provided buf is too small %zu < %zu", len, sz);
1980        errno = ENOBUFS;
1981        return -1;
1982    }
1983    lsquic_enc_session_serialize_zero_rtt((struct lsquic_zero_rtt_storage *)buf,
1984                                                    version, enc_session->info,
1985                                                    enc_session->cert_item);
1986    return sz;
1987}
1988
1989
1990#ifdef NDEBUG
1991const
1992#endif
1993struct enc_session_funcs lsquic_enc_session_gquic_1 =
1994{
1995    .esf_global_init    = lsquic_handshake_init,
1996    .esf_global_cleanup = lsquic_handshake_cleanup,
1997#if LSQUIC_KEEP_ENC_SESS_HISTORY
1998    .esf_get_hist       = lsquic_get_enc_hist,
1999#endif
2000    .esf_destroy = lsquic_enc_session_destroy,
2001    .esf_is_hsk_done = lsquic_enc_session_is_hsk_done,
2002    .esf_encrypt = lsquic_enc_session_encrypt,
2003    .esf_decrypt = lsquic_enc_session_decrypt,
2004    .esf_get_peer_setting = lsquic_enc_session_get_peer_setting,
2005    .esf_get_peer_option = lsquic_enc_session_get_peer_option,
2006    .esf_create_client = lsquic_enc_session_create_client,
2007    .esf_generate_cid = lsquic_generate_cid,
2008    .esf_gen_chlo = lsquic_enc_session_gen_chlo,
2009    .esf_handle_chlo_reply = lsquic_enc_session_handle_chlo_reply,
2010    .esf_mem_used = lsquic_enc_session_mem_used,
2011    .esf_verify_reset_token = lsquic_enc_session_verify_reset_token,
2012    .esf_did_zero_rtt_succeed = lsquic_enc_session_did_zero_rtt_succeed,
2013    .esf_is_zero_rtt_enabled = lsquic_enc_session_is_zero_rtt_enabled,
2014    .esf_get_cert_item = lsquic_enc_session_get_cert_item,
2015    .esf_get_server_cert_chain = lsquic_enc_session_get_server_cert_chain,
2016    .esf_get_zero_rtt = lsquic_enc_session_get_zero_rtt,
2017};
2018
2019
2020const char *const lsquic_enclev2str[] =
2021{
2022    [ENC_LEV_UNSET] = "unset",
2023    [ENC_LEV_CLEAR] = "clear",
2024    [ENC_LEV_INIT]  = "initial",
2025    [ENC_LEV_FORW]  = "forw-secure",
2026};
2027
2028
2029enum lsquic_version
2030lsquic_zero_rtt_version (const unsigned char *buf, size_t bufsz)
2031{
2032    lsquic_ver_tag_t tag;
2033
2034    if (bufsz >= sizeof(tag))
2035    {
2036        memcpy(&tag, buf, sizeof(tag));
2037        return lsquic_tag2ver(tag);
2038    }
2039    else
2040        return -1;
2041}
2042