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