lsquic_handshake.c revision c7d81ce1
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 1189 cleanup: 1190 if (chain) 1191 sk_X509_free(chain); 1192 X509_free(server_cert); 1193 return ret; 1194} 1195 1196 1197void setup_aead_ctx(EVP_AEAD_CTX **ctx, unsigned char key[], int key_len, 1198 unsigned char *key_copy) 1199{ 1200 const EVP_AEAD *aead_ = EVP_aead_aes_128_gcm(); 1201 const int auth_tag_size = 12; 1202 if (*ctx) 1203 { 1204 EVP_AEAD_CTX_cleanup(*ctx); 1205 } 1206 else 1207 *ctx = (EVP_AEAD_CTX *)malloc(sizeof(EVP_AEAD_CTX)); 1208 1209 EVP_AEAD_CTX_init(*ctx, aead_, key, key_len, auth_tag_size, NULL); 1210 if (key_copy) 1211 memcpy(key_copy, key, key_len); 1212} 1213 1214 1215static int 1216determine_diversification_key (lsquic_enc_session_t *enc_session, 1217 uint8_t *diversification_nonce 1218 ) 1219{ 1220 EVP_AEAD_CTX **ctx_s_key; 1221 unsigned char *key_i, *iv; 1222 uint8_t ikm[aes128_key_len + aes128_iv_len]; 1223 1224 ctx_s_key = &enc_session->dec_ctx_i; 1225 key_i = enc_session->dec_key_i; 1226 iv = enc_session->dec_key_nonce_i; 1227 memcpy(ikm, key_i, aes128_key_len); 1228 memcpy(ikm + aes128_key_len, iv, aes128_iv_len); 1229 export_key_material(ikm, aes128_key_len + aes128_iv_len, 1230 diversification_nonce, DNONC_LENGTH, 1231 (const unsigned char *) "QUIC key diversification", 24, 1232 0, NULL, aes128_key_len, key_i, 0, NULL, 1233 aes128_iv_len, iv, NULL); 1234 1235 setup_aead_ctx(ctx_s_key, key_i, aes128_key_len, NULL); 1236 LSQ_DEBUG("determine_diversification_keys diversification_key: %s\n", 1237 get_bin_str(key_i, aes128_key_len, 512)); 1238 LSQ_DEBUG("determine_diversification_keys diversification_key nonce: %s\n", 1239 get_bin_str(iv, aes128_iv_len, 512)); 1240 return 0; 1241} 1242 1243 1244/* After CHLO msg generatered, call it to determine_keys */ 1245static int determine_keys(lsquic_enc_session_t *enc_session) 1246{ 1247 lsquic_str_t *chlo = &enc_session->chlo; 1248 uint8_t shared_key_c[32]; 1249 struct lsquic_buf *nonce_c = lsquic_buf_create(100); 1250 struct lsquic_buf *hkdf_input = lsquic_buf_create(0); 1251 1252 unsigned char c_key[aes128_key_len]; 1253 unsigned char s_key[aes128_key_len]; 1254 unsigned char *c_key_bin = NULL; 1255 unsigned char *s_key_bin = NULL; 1256 1257 unsigned char *c_iv; 1258 unsigned char *s_iv; 1259 unsigned char sub_key[32]; 1260 EVP_AEAD_CTX **ctx_c_key, **ctx_s_key; 1261 char key_flag; 1262 1263 lsquic_buf_clear(nonce_c); 1264 lsquic_buf_clear(hkdf_input); 1265 if (enc_session->have_key == 0) 1266 { 1267 lsquic_buf_append(hkdf_input, "QUIC key expansion\0", 18 + 1); // Add a 0x00 */ 1268 key_flag = 'I'; 1269 } 1270 else 1271 { 1272 lsquic_buf_append(hkdf_input, "QUIC forward secure key expansion\0", 33 + 1); // Add a 0x00 */ 1273 key_flag = 'F'; 1274 } 1275 1276 c255_gen_share_key(enc_session->priv_key, 1277 enc_session->hs_ctx.pubs, 1278 (unsigned char *)shared_key_c); 1279 { 1280 if (enc_session->have_key == 0) 1281 { 1282 ctx_c_key = &enc_session->enc_ctx_i; 1283 ctx_s_key = &enc_session->dec_ctx_i; 1284 c_iv = (unsigned char *) enc_session->enc_key_nonce_i; 1285 s_iv = (unsigned char *) enc_session->dec_key_nonce_i; 1286 c_key_bin = enc_session->enc_key_i; 1287 s_key_bin = enc_session->dec_key_i; 1288 } 1289 else 1290 { 1291 ctx_c_key = &enc_session->enc_ctx_f; 1292 ctx_s_key = &enc_session->dec_ctx_f; 1293 c_iv = (unsigned char *) enc_session->enc_key_nonce_f; 1294 s_iv = (unsigned char *) enc_session->dec_key_nonce_f; 1295 } 1296 } 1297 1298 LSQ_DEBUG("export_key_material c255_gen_share_key %s", 1299 get_bin_str(shared_key_c, 32, 512)); 1300 1301 lsquic_buf_append(hkdf_input, (char *)&enc_session->cid, sizeof(enc_session->cid)); 1302 lsquic_buf_append(hkdf_input, lsquic_str_cstr(chlo), lsquic_str_len(chlo)); /* CHLO msg */ 1303 { 1304 lsquic_buf_append(hkdf_input, lsquic_str_cstr(&enc_session->info->scfg), 1305 lsquic_str_len(&enc_session->info->scfg)); /* scfg msg */ 1306 } 1307 lsquic_buf_append(hkdf_input, lsquic_str_cstr(enc_session->cert_ptr), 1308 lsquic_str_len(enc_session->cert_ptr)); 1309 LSQ_DEBUG("export_key_material hkdf_input %s", 1310 get_bin_str(lsquic_buf_begin(hkdf_input), 1311 (size_t)lsquic_buf_size(hkdf_input), 512)); 1312 1313 /* then need to use the salts and the shared_key_* to get the real aead key */ 1314 lsquic_buf_append(nonce_c, (const char *) enc_session->hs_ctx.nonc, 32); 1315 lsquic_buf_append(nonce_c, lsquic_str_cstr(&enc_session->ssno), 1316 lsquic_str_len(&enc_session->ssno)); 1317 LSQ_DEBUG("export_key_material nonce %s", 1318 get_bin_str(lsquic_buf_begin(nonce_c), 1319 (size_t)lsquic_buf_size(nonce_c), 512)); 1320 1321 export_key_material(shared_key_c, 32, 1322 (unsigned char *)lsquic_buf_begin(nonce_c), lsquic_buf_size(nonce_c), 1323 (unsigned char *)lsquic_buf_begin(hkdf_input), 1324 lsquic_buf_size(hkdf_input), 1325 aes128_key_len, c_key, 1326 aes128_key_len, s_key, 1327 aes128_iv_len, c_iv, 1328 aes128_iv_len, s_iv, 1329 sub_key); 1330 1331 setup_aead_ctx(ctx_c_key, c_key, aes128_key_len, c_key_bin); 1332 setup_aead_ctx(ctx_s_key, s_key, aes128_key_len, s_key_bin); 1333 1334 1335 lsquic_buf_destroy(nonce_c); 1336 lsquic_buf_destroy(hkdf_input); 1337 1338 LSQ_DEBUG("***export_key_material '%c' c_key: %s", key_flag, 1339 get_bin_str(c_key, aes128_key_len, 512)); 1340 LSQ_DEBUG("***export_key_material '%c' s_key: %s", key_flag, 1341 get_bin_str(s_key, aes128_key_len, 512)); 1342 LSQ_DEBUG("***export_key_material '%c' c_iv: %s", key_flag, 1343 get_bin_str(c_iv, aes128_iv_len, 512)); 1344 LSQ_DEBUG("***export_key_material '%c' s_iv: %s", key_flag, 1345 get_bin_str(s_iv, aes128_iv_len, 512)); 1346 LSQ_DEBUG("***export_key_material '%c' subkey: %s", key_flag, 1347 get_bin_str(sub_key, 32, 512)); 1348 1349 return 0; 1350} 1351 1352 1353/* 0 Match */ 1354static int cached_certs_match(c_cert_item_t *item, 1355 lsquic_str_t **certs, int count) 1356{ 1357 int i; 1358 if (!item || item->count != count) 1359 return -1; 1360 1361 for (i=0; i<count; ++i) 1362 { 1363 if (lsquic_str_bcmp(certs[i], &item->crts[i]) != 0) 1364 return -1; 1365 } 1366 1367 return 0; 1368} 1369 1370 1371static const char * 1372he2str (enum handshake_error he) 1373{ 1374 switch (he) 1375 { 1376 case DATA_NOT_ENOUGH: return "DATA_NOT_ENOUGH"; 1377 case HS_ERROR: return "HS_ERROR"; 1378 case HS_SHLO: return "HS_SHLO"; 1379 case HS_1RTT: return "HS_1RTT"; 1380 case HS_2RTT: return "HS_2RTT"; 1381 default: 1382 assert(0); return "<unknown enum value>"; 1383 } 1384} 1385 1386 1387/* NOT packet, just the frames-data */ 1388/* return rtt number: 1389 * 0 OK 1390 * DATA_NOT_ENOUGH(-2) for not enough data, 1391 * DATA_FORMAT_ERROR(-1) all other errors 1392 */ 1393static int 1394lsquic_enc_session_handle_chlo_reply (lsquic_enc_session_t *enc_session, 1395 const uint8_t *data, int len) 1396{ 1397 uint32_t head_tag; 1398 int ret; 1399 lsquic_session_cache_info_t *info = enc_session->info; 1400 c_cert_item_t *cert_item = enc_session->cert_item; 1401 1402 /* FIXME get the number first */ 1403 lsquic_str_t **out_certs = NULL; 1404 size_t out_certs_count = 0, i; 1405 1406 ret = parse_hs(enc_session, data, len, &head_tag); 1407 if (ret) 1408 goto end; 1409 1410 if (head_tag != QTAG_SREJ && 1411 head_tag != QTAG_REJ && 1412 head_tag != QTAG_SHLO) 1413 { 1414 ret = 1; 1415 goto end; 1416 } 1417 1418 if (head_tag == QTAG_SREJ || head_tag == QTAG_REJ) 1419 { 1420 enc_session->hsk_state = HSK_CHLO_REJ; 1421 enc_session->es_flags |= ES_RECV_REJ; 1422 } 1423 else if(head_tag == QTAG_SHLO) 1424 { 1425 enc_session->hsk_state = HSK_COMPLETED; 1426 } 1427 1428 if (info->scfg_flag == 1) 1429 { 1430 ret = parse_hs(enc_session, (uint8_t *)lsquic_str_cstr(&info->scfg), 1431 lsquic_str_len(&info->scfg), &head_tag); 1432 1433 /* After handled, set the length to 0 to avoid do it again*/ 1434 enc_session->info->scfg_flag = 2; 1435 if (ret) 1436 goto end; 1437 1438 if (lsquic_str_len(&enc_session->hs_ctx.crt) > 0) 1439 { 1440 out_certs_count = get_certs_count(&enc_session->hs_ctx.crt); 1441 if (out_certs_count > 0) 1442 { 1443 out_certs = malloc(out_certs_count * sizeof(lsquic_str_t *)); 1444 if (!out_certs) 1445 { 1446 ret = -1; 1447 goto end; 1448 } 1449 1450 for (i=0; i<out_certs_count; ++i) 1451 out_certs[i] = lsquic_str_new(NULL, 0); 1452 1453 ret = handle_chlo_reply_verify_prof(enc_session, out_certs, 1454 &out_certs_count, 1455 (cert_item ? cert_item->crts : NULL), 1456 (cert_item ? cert_item->count : 0)); 1457 if (ret == 0) 1458 { 1459 if (out_certs_count > 0) 1460 { 1461 if (cached_certs_match(cert_item, out_certs, 1462 out_certs_count) != 0) 1463 { 1464 cert_item = make_c_cert_item(out_certs, 1465 out_certs_count); 1466 enc_session->cert_item = cert_item; 1467 enc_session->cert_ptr = &cert_item->crts[0]; 1468 } 1469 } 1470 } 1471 for (i=0; i<out_certs_count; ++i) 1472 lsquic_str_delete(out_certs[i]); 1473 free(out_certs); 1474 1475 if (ret) 1476 goto end; 1477 } 1478 } 1479 } 1480 1481 if (enc_session->hsk_state == HSK_COMPLETED) 1482 { 1483 ret = determine_keys(enc_session 1484 ); /* FIXME: check ret */ 1485 enc_session->have_key = 3; 1486 } 1487 1488 end: 1489 LSQ_DEBUG("lsquic_enc_session_handle_chlo_reply called, buf in %d, return %d.", len, ret); 1490 EV_LOG_CONN_EVENT(enc_session->cid, "%s returning %s", __func__, 1491 he2str(ret)); 1492 return ret; 1493} 1494 1495 1496static uint64_t combine_path_id_pack_num(uint8_t path_id, uint64_t pack_num) 1497{ 1498 uint64_t v = ((uint64_t)path_id << 56) | pack_num; 1499 return v; 1500} 1501 1502 1503# define IS_SERVER(session) 0 1504 1505static int 1506verify_packet_hash (const lsquic_enc_session_t *enc_session, 1507 enum lsquic_version version, const unsigned char *buf, size_t *header_len, 1508 size_t data_len, unsigned char *buf_out, size_t max_out_len, 1509 size_t *out_len) 1510{ 1511 uint8_t md[HS_PKT_HASH_LENGTH]; 1512 uint128 hash; 1513 int ret; 1514 1515 if (data_len < HS_PKT_HASH_LENGTH) 1516 return -1; 1517 1518 if (version >= LSQVER_039) 1519 { 1520 hash = fnv1a_128_3(buf, *header_len, 1521 buf + *header_len + HS_PKT_HASH_LENGTH, 1522 data_len - HS_PKT_HASH_LENGTH, 1523 (unsigned char *) "Server", 6); 1524 } 1525 else 1526 { 1527 hash = fnv1a_128_2(buf, *header_len, 1528 buf + *header_len + HS_PKT_HASH_LENGTH, 1529 data_len - HS_PKT_HASH_LENGTH); 1530 } 1531 1532 serialize_fnv128_short(hash, md); 1533 ret = memcmp(md, buf + *header_len, HS_PKT_HASH_LENGTH); 1534 if(ret == 0) 1535 { 1536 *header_len += HS_PKT_HASH_LENGTH; 1537 *out_len = data_len - HS_PKT_HASH_LENGTH; 1538 if (max_out_len < *header_len + *out_len) 1539 return -1; 1540 1541 memcpy(buf_out, buf, *header_len + *out_len); 1542 return 0; 1543 } 1544 else 1545 return -1; 1546} 1547 1548 1549static enum enc_level 1550decrypt_packet (lsquic_enc_session_t *enc_session, uint8_t path_id, 1551 uint64_t pack_num, unsigned char *buf, size_t *header_len, 1552 size_t data_len, unsigned char *buf_out, size_t max_out_len, 1553 size_t *out_len) 1554{ 1555 int ret; 1556 /* Comment: 12 = sizeof(dec_key_iv] 4 + sizeof(pack_num) 8 */ 1557 uint8_t nonce[12]; 1558 uint64_t path_id_packet_number; 1559 EVP_AEAD_CTX *key = NULL; 1560 int try_times = 0; 1561 enum enc_level enc_level; 1562 1563 path_id_packet_number = combine_path_id_pack_num(path_id, pack_num); 1564 memcpy(buf_out, buf, *header_len); 1565 do 1566 { 1567 if (enc_session->have_key == 3 && try_times == 0) 1568 { 1569 key = enc_session->dec_ctx_f; 1570 memcpy(nonce, enc_session->dec_key_nonce_f, 4); 1571 LSQ_DEBUG("decrypt_packet using 'F' key..."); 1572 enc_level = ENC_LEV_FORW; 1573 } 1574 else 1575 { 1576 key = enc_session->dec_ctx_i; 1577 memcpy(nonce, enc_session->dec_key_nonce_i, 4); 1578 LSQ_DEBUG("decrypt_packet using 'I' key..."); 1579 enc_level = ENC_LEV_INIT; 1580 } 1581 memcpy(nonce + 4, &path_id_packet_number, 1582 sizeof(path_id_packet_number)); 1583 1584 *out_len = data_len; 1585 ret = aes_aead_dec(key, 1586 buf, *header_len, 1587 nonce, 12, 1588 buf + *header_len, data_len, 1589 buf_out + *header_len, out_len); 1590 1591 if (ret != 0) 1592 ++try_times; 1593 else 1594 { 1595 if (enc_session->peer_have_final_key == 0 && 1596 enc_session->have_key == 3 && 1597 try_times == 0) 1598 { 1599 LSQ_DEBUG("!!!decrypt_packet find peer have final key."); 1600 enc_session->peer_have_final_key = 1; 1601 EV_LOG_CONN_EVENT(enc_session->cid, "settled on private key " 1602 "'%c' after %d tries (packet number %"PRIu64")", 1603 key == enc_session->dec_ctx_f ? 'F' : 'I', 1604 try_times, pack_num); 1605 } 1606 break; 1607 } 1608 } 1609 while (try_times < 2); 1610 1611 LSQ_DEBUG("***decrypt_packet %s.", (ret == 0 ? "succeed" : "failed")); 1612 return ret == 0 ? enc_level : (enum enc_level) -1; 1613} 1614 1615 1616static int 1617lsquic_enc_session_have_key_gt_one (const lsquic_enc_session_t *enc_session) 1618{ 1619 return enc_session && enc_session->have_key > 1; 1620} 1621 1622 1623/* The size of `buf' is *header_len plus data_len. The two parts of the 1624 * buffer correspond to the header and the payload of incoming QUIC packet. 1625 */ 1626static enum enc_level 1627lsquic_enc_session_decrypt (lsquic_enc_session_t *enc_session, 1628 enum lsquic_version version, 1629 uint8_t path_id, uint64_t pack_num, 1630 unsigned char *buf, size_t *header_len, size_t data_len, 1631 unsigned char *diversification_nonce, 1632 unsigned char *buf_out, size_t max_out_len, size_t *out_len) 1633{ 1634 /* Client: got SHLO which should have diversification_nonce */ 1635 if (diversification_nonce && enc_session && enc_session->have_key == 1) 1636 { 1637 determine_diversification_key(enc_session, diversification_nonce); 1638 enc_session->have_key = 2; 1639 } 1640 1641 if (lsquic_enc_session_have_key_gt_one(enc_session)) 1642 return decrypt_packet(enc_session, path_id, pack_num, buf, 1643 header_len, data_len, buf_out, max_out_len, out_len); 1644 else if (0 == verify_packet_hash(enc_session, version, buf, header_len, 1645 data_len, buf_out, max_out_len, out_len)) 1646 return ENC_LEV_CLEAR; 1647 else 1648 return -1; 1649} 1650 1651 1652static enum enc_level 1653lsquic_enc_session_encrypt (lsquic_enc_session_t *enc_session, 1654 enum lsquic_version version, 1655 uint8_t path_id, uint64_t pack_num, 1656 const unsigned char *header, size_t header_len, 1657 const unsigned char *data, size_t data_len, 1658 unsigned char *buf_out, size_t max_out_len, size_t *out_len, 1659 int is_hello) 1660{ 1661 uint8_t md[HS_PKT_HASH_LENGTH]; 1662 uint128 hash; 1663 int ret; 1664 enum enc_level enc_level; 1665 int is_chlo = (is_hello && ((IS_SERVER(enc_session)) == 0)); 1666 int is_shlo = (is_hello && (IS_SERVER(enc_session))); 1667 1668 /* Comment: 12 = sizeof(dec_key_iv] 4 + sizeof(pack_num) 8 */ 1669 uint8_t nonce[12]; 1670 uint64_t path_id_packet_number; 1671 EVP_AEAD_CTX *key; 1672 1673 if (enc_session) 1674 LSQ_DEBUG("%s: hsk_state: %d", __func__, enc_session->hsk_state); 1675 else 1676 LSQ_DEBUG("%s: enc_session is not set", __func__); 1677 1678 if (!enc_session || enc_session->have_key == 0 || is_chlo) 1679 { 1680 *out_len = header_len + data_len + HS_PKT_HASH_LENGTH; 1681 if (max_out_len < *out_len) 1682 return -1; 1683 1684 if (version >= LSQVER_039) 1685 { 1686 hash = fnv1a_128_3(header, header_len, data, data_len, 1687 (unsigned char *) "Client", 6); 1688 } 1689 else 1690 { 1691 hash = fnv1a_128_2(header, header_len, data, data_len); 1692 } 1693 1694 serialize_fnv128_short(hash, md); 1695 memcpy(buf_out, header, header_len); 1696 memcpy(buf_out + header_len, md, HS_PKT_HASH_LENGTH); 1697 memcpy(buf_out + header_len + HS_PKT_HASH_LENGTH, data, data_len); 1698 return ENC_LEV_CLEAR; 1699 } 1700 else 1701 { 1702 if (enc_session->have_key != 3 || is_shlo || 1703 ((IS_SERVER(enc_session)) && 1704 enc_session->server_start_use_final_key == 0)) 1705 { 1706 LSQ_DEBUG("lsquic_enc_session_encrypt using 'I' key..."); 1707 key = enc_session->enc_ctx_i; 1708 memcpy(nonce, enc_session->enc_key_nonce_i, 4); 1709 if (is_shlo && enc_session->have_key == 3) 1710 { 1711 enc_session->server_start_use_final_key = 1; 1712 } 1713 enc_level = ENC_LEV_INIT; 1714 } 1715 else 1716 { 1717 LSQ_DEBUG("lsquic_enc_session_encrypt using 'F' key..."); 1718 key = enc_session->enc_ctx_f; 1719 memcpy(nonce, enc_session->enc_key_nonce_f, 4); 1720 enc_level = ENC_LEV_FORW; 1721 } 1722 path_id_packet_number = combine_path_id_pack_num(path_id, pack_num); 1723 memcpy(nonce + 4, &path_id_packet_number, 1724 sizeof(path_id_packet_number)); 1725 1726 memcpy(buf_out, header, header_len); 1727 *out_len = max_out_len - header_len; 1728 1729 ret = aes_aead_enc(key, header, header_len, nonce, 12, data, 1730 data_len, buf_out + header_len, out_len); 1731 if (ret == 0) 1732 { 1733 *out_len += header_len; 1734 return enc_level; 1735 } 1736 else 1737 return -1; 1738 } 1739} 1740 1741 1742static int 1743lsquic_enc_session_get_peer_option (const lsquic_enc_session_t *enc_session, 1744 uint32_t tag) 1745{ 1746 switch (tag) 1747 { 1748 case QTAG_NSTP: 1749 return !!(enc_session->hs_ctx.opts & HOPT_NSTP); 1750 case QTAG_SREJ: 1751 return !!(enc_session->hs_ctx.opts & HOPT_SREJ); 1752 default: 1753 assert(0); 1754 return 0; 1755 } 1756} 1757 1758 1759/* Query a several parameters sent by the peer that are required by 1760 * connection. 1761 */ 1762static int 1763lsquic_enc_session_get_peer_setting (const lsquic_enc_session_t *enc_session, 1764 uint32_t tag, uint32_t *val) 1765{ 1766 switch (tag) 1767 { 1768 case QTAG_TCID: 1769 if (enc_session->hs_ctx.set & HSET_TCID) 1770 { 1771 *val = enc_session->hs_ctx.tcid; 1772 return 0; 1773 } 1774 else 1775 return -1; 1776 case QTAG_SMHL: 1777 if (enc_session->hs_ctx.set & HSET_SMHL) 1778 { 1779 *val = enc_session->hs_ctx.smhl; 1780 return 0; 1781 } 1782 else 1783 return -1; 1784 case QTAG_IRTT: 1785 if (enc_session->hs_ctx.set & HSET_IRTT) 1786 { 1787 *val = enc_session->hs_ctx.irtt; 1788 return 0; 1789 } 1790 else 1791 return -1; 1792 } 1793 1794 /* XXX For the following values, there is no record which were present 1795 * in CHLO or SHLO and which were not. Assume that zero means that 1796 * they weren't present. 1797 */ 1798 switch (tag) 1799 { 1800 case QTAG_CFCW: 1801 if (enc_session->hs_ctx.cfcw) 1802 { 1803 *val = enc_session->hs_ctx.cfcw; 1804 return 0; 1805 } 1806 else 1807 return -1; 1808 case QTAG_SFCW: 1809 if (enc_session->hs_ctx.sfcw) 1810 { 1811 *val = enc_session->hs_ctx.sfcw; 1812 return 0; 1813 } 1814 else 1815 return -1; 1816 case QTAG_MIDS: 1817 if (enc_session->hs_ctx.mids) 1818 { 1819 *val = enc_session->hs_ctx.mids; 1820 return 0; 1821 } 1822 else 1823 return -1; 1824 default: 1825 return -1; 1826 } 1827} 1828 1829 1830#if LSQUIC_KEEP_ENC_SESS_HISTORY 1831static void 1832lsquic_get_enc_hist (const lsquic_enc_session_t *enc_session, 1833 char buf[(1 << ESHIST_BITS) + 1]) 1834{ 1835 const unsigned hist_idx = ESHIST_MASK & enc_session->es_hist_idx; 1836 if (enc_session->es_hist_buf[hist_idx] == ESHE_EMPTY) 1837 memcpy(buf, enc_session->es_hist_buf, hist_idx + 1); 1838 else 1839 { 1840 memcpy(buf, enc_session->es_hist_buf + hist_idx, sizeof(enc_session->es_hist_buf) - hist_idx); 1841 memcpy(buf + hist_idx, enc_session->es_hist_buf, hist_idx); 1842 buf[(1 << ESHIST_BITS)] = '\0'; 1843 } 1844} 1845 1846 1847#endif 1848 1849 1850 1851 1852static size_t 1853lsquic_enc_session_mem_used (struct lsquic_enc_session *enc_session) 1854{ 1855 size_t size; 1856 1857 size = sizeof(*enc_session); 1858 1859 size += lsquic_str_len(&enc_session->chlo); 1860 size += lsquic_str_len(&enc_session->sstk); 1861 size += lsquic_str_len(&enc_session->ssno); 1862 1863 size += lsquic_str_len(&enc_session->hs_ctx.ccs); 1864 size += lsquic_str_len(&enc_session->hs_ctx.sni); 1865 size += lsquic_str_len(&enc_session->hs_ctx.ccrt); 1866 size += lsquic_str_len(&enc_session->hs_ctx.stk); 1867 size += lsquic_str_len(&enc_session->hs_ctx.sno); 1868 size += lsquic_str_len(&enc_session->hs_ctx.prof); 1869 size += lsquic_str_len(&enc_session->hs_ctx.csct); 1870 size += lsquic_str_len(&enc_session->hs_ctx.crt); 1871 1872 if (enc_session->info) 1873 { 1874 size += sizeof(*enc_session->info); 1875 size += lsquic_str_len(&enc_session->info->sstk); 1876 size += lsquic_str_len(&enc_session->info->scfg); 1877 size += lsquic_str_len(&enc_session->info->sni_key); 1878 } 1879 1880 /* TODO: calculate memory taken up by SSL stuff */ 1881 1882 return size; 1883} 1884 1885 1886static int 1887lsquic_enc_session_verify_reset_token (lsquic_enc_session_t *enc_session, 1888 const unsigned char *buf, size_t bufsz) 1889{ 1890 if (bufsz == SRST_LENGTH 1891 && (enc_session->hs_ctx.set & HSET_SRST) 1892 && 0 == memcmp(buf, enc_session->hs_ctx.srst, SRST_LENGTH)) 1893 return 0; 1894 else 1895 return -1; 1896} 1897 1898 1899static int 1900lsquic_enc_session_did_zero_rtt_succeed (const lsquic_enc_session_t *enc_session) 1901{ 1902 return !(enc_session->es_flags & ES_RECV_REJ); 1903} 1904 1905 1906static int 1907lsquic_enc_session_is_zero_rtt_enabled (const lsquic_enc_session_t *enc_session) 1908{ 1909 return enc_session->info && enc_session->cert_item; 1910} 1911 1912 1913static c_cert_item_t * 1914lsquic_enc_session_get_cert_item (const lsquic_enc_session_t *enc_session) 1915{ 1916 return enc_session->cert_item; 1917} 1918 1919 1920static STACK_OF(X509) * 1921lsquic_enc_session_get_server_cert_chain (lsquic_enc_session_t *enc_session) 1922{ 1923 const struct c_cert_item_st *item; 1924 STACK_OF(X509) *chain; 1925 X509 *cert; 1926 int i; 1927 1928 item = enc_session->cert_item; 1929 if (!item) 1930 { 1931 LSQ_WARN("could not find certificates for `%.*s'", 1932 (int) lsquic_str_len(&enc_session->hs_ctx.sni), 1933 lsquic_str_cstr(&enc_session->hs_ctx.sni)); 1934 return NULL; 1935 } 1936 1937 chain = sk_X509_new_null(); 1938 for (i = 0; i < item->count; ++i) 1939 { 1940 cert = bio_to_crt(lsquic_str_cstr(&item->crts[i]), 1941 lsquic_str_len(&item->crts[i]), 0); 1942 if (cert) 1943 sk_X509_push(chain, cert); 1944 else 1945 { 1946 sk_X509_free(chain); 1947 return NULL; 1948 } 1949 } 1950 1951 return chain; 1952} 1953 1954 1955ssize_t 1956lsquic_enc_session_get_zero_rtt (lsquic_enc_session_t *enc_session, 1957 enum lsquic_version version, 1958 void *buf, size_t len) 1959{ 1960 int i; 1961 size_t sz = 0; 1962 if (!enc_session->info || !enc_session->cert_item) 1963 { 1964 LSQ_DEBUG("client asked for rtt_into but it is not available"); 1965 return 0; 1966 } 1967 for (i = 0; i < enc_session->cert_item->count; ++i) 1968 { 1969 sz += sizeof(uint32_t); 1970 sz += lsquic_str_len(&enc_session->cert_item->crts[i]); 1971 } 1972 sz += sizeof(struct lsquic_zero_rtt_storage); 1973 if (len < sz) 1974 { 1975 LSQ_DEBUG("client provided buf is too small %zu < %zu", len, sz); 1976 errno = ENOBUFS; 1977 return -1; 1978 } 1979 lsquic_enc_session_serialize_zero_rtt((struct lsquic_zero_rtt_storage *)buf, 1980 version, enc_session->info, 1981 enc_session->cert_item); 1982 return sz; 1983} 1984 1985 1986#ifdef NDEBUG 1987const 1988#endif 1989struct enc_session_funcs lsquic_enc_session_gquic_1 = 1990{ 1991 .esf_global_init = lsquic_handshake_init, 1992 .esf_global_cleanup = lsquic_handshake_cleanup, 1993#if LSQUIC_KEEP_ENC_SESS_HISTORY 1994 .esf_get_hist = lsquic_get_enc_hist, 1995#endif 1996 .esf_destroy = lsquic_enc_session_destroy, 1997 .esf_is_hsk_done = lsquic_enc_session_is_hsk_done, 1998 .esf_encrypt = lsquic_enc_session_encrypt, 1999 .esf_decrypt = lsquic_enc_session_decrypt, 2000 .esf_get_peer_setting = lsquic_enc_session_get_peer_setting, 2001 .esf_get_peer_option = lsquic_enc_session_get_peer_option, 2002 .esf_create_client = lsquic_enc_session_create_client, 2003 .esf_generate_cid = lsquic_generate_cid, 2004 .esf_gen_chlo = lsquic_enc_session_gen_chlo, 2005 .esf_handle_chlo_reply = lsquic_enc_session_handle_chlo_reply, 2006 .esf_mem_used = lsquic_enc_session_mem_used, 2007 .esf_verify_reset_token = lsquic_enc_session_verify_reset_token, 2008 .esf_did_zero_rtt_succeed = lsquic_enc_session_did_zero_rtt_succeed, 2009 .esf_is_zero_rtt_enabled = lsquic_enc_session_is_zero_rtt_enabled, 2010 .esf_get_cert_item = lsquic_enc_session_get_cert_item, 2011 .esf_get_server_cert_chain = lsquic_enc_session_get_server_cert_chain, 2012 .esf_get_zero_rtt = lsquic_enc_session_get_zero_rtt, 2013}; 2014 2015 2016const char *const lsquic_enclev2str[] = 2017{ 2018 [ENC_LEV_UNSET] = "unset", 2019 [ENC_LEV_CLEAR] = "clear", 2020 [ENC_LEV_INIT] = "initial", 2021 [ENC_LEV_FORW] = "forw-secure", 2022}; 2023 2024 2025enum lsquic_version 2026lsquic_zero_rtt_version (const unsigned char *buf, size_t bufsz) 2027{ 2028 lsquic_ver_tag_t tag; 2029 2030 if (bufsz >= sizeof(tag)) 2031 { 2032 memcpy(&tag, buf, sizeof(tag)); 2033 return lsquic_tag2ver(tag); 2034 } 2035 else 2036 return -1; 2037} 2038