lsquic_handshake.c revision 8437e4a4
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 650 for (p = val; p < val + len; p += 4) 651 if (0 == memcmp(p, "C255", 4)) 652 { 653 memcpy(&enc_session->info->kexs, p, 4); 654 pub_idx = (p - val) / 4; 655 LSQ_DEBUG("Parsing SCFG: supported KEXS C255 at " 656 "index %u", pub_idx); 657 break; 658 } 659 if (p >= val + len) 660 { 661 LSQ_INFO("supported KEXS not found, trouble ahead"); 662 break; 663 } 664 if (lsquic_str_len(&hs_ctx->scfg_pubs) > 0) 665 { 666 p = (const unsigned char *) 667 lsquic_str_cstr(&hs_ctx->scfg_pubs); 668 end = p + lsquic_str_len(&hs_ctx->scfg_pubs); 669 670 for (idx = 0; p < end; ++idx) 671 { 672 uint32_t sz = 0; 673 if (p + 3 > end) 674 break; 675 sz |= *p++; 676 sz |= *p++ << 8; 677 sz |= *p++ << 16; 678 if (p + sz > end) 679 break; 680 if (idx == pub_idx) 681 { 682 if (sz == 32) 683 { 684 memcpy(hs_ctx->pubs, p, 32); 685 memcpy(enc_session->info->spubs, p, 32); 686 } 687 break; 688 } 689 p += sz; 690 } 691 } 692 else 693 LSQ_INFO("No PUBS from SCFG to parse"); 694 } 695 } 696 break; 697 698 case QTAG_NONC: 699 if (len != sizeof(hs_ctx->nonc)) 700 return -1; 701 memcpy(hs_ctx->nonc, val, len); 702 break; 703 704 case QTAG_SCFG: 705 lsquic_str_setto(&enc_session->info->scfg, val, len); 706 enc_session->info->scfg_flag = 1; 707 break; 708 709 case QTAG_PROF: 710 lsquic_str_setto(&hs_ctx->prof, val, len); 711 ESHIST_APPEND(enc_session, ESHE_SET_PROF); 712 break; 713 714 case QTAG_STTL: 715 hs_ctx->sttl = get_tag_value_i64(val, len); 716 break; 717 718 case QTAG_SRST: 719 if (len != sizeof(hs_ctx->srst)) 720 { 721 LSQ_INFO("Unexpected size of SRST: %u instead of %zu bytes", 722 len, sizeof(hs_ctx->srst)); 723 return -1; 724 } 725 memcpy(hs_ctx->srst, val, len); 726 hs_ctx->set |= HSET_SRST; 727 ESHIST_APPEND(enc_session, ESHE_SET_SRST); 728 break; 729 730 default: 731 LSQ_DEBUG("Ignored tag '%.*s'", 4, (char *)&tag); 732 break; 733 } 734 735 return 0; 736} 737 738 739/* only for the hs stream-frame data, NOT with the packet header or frame header*/ 740static enum handshake_error parse_hs (lsquic_enc_session_t *enc_session, 741 const unsigned char *buf, int buf_len, 742 uint32_t *head_tag) 743{ 744 uint16_t i; 745 const unsigned char *p = buf; 746 const unsigned char *pend = buf + buf_len; 747 748 unsigned char *data; 749 uint32_t len = 0, offset = 0; 750 uint16_t num; 751 uint32_t tag; 752 if (buf_len < 6) 753 return DATA_FORMAT_ERROR; 754 755 memcpy(&tag, p, 4); 756 p += 4; 757 758 { 759 if (tag != QTAG_SREJ && tag != QTAG_REJ && tag != QTAG_SHLO && 760 tag != QTAG_SCFG) 761 return DATA_FORMAT_ERROR; 762 } 763 764 *head_tag = tag; 765 766 memcpy((char *)&num, p, 2); 767 p += 2 + 2; /* the 2 bytes padding 0x0000 need to be bypassed */ 768 769 if (num < 1) 770 return DATA_FORMAT_ERROR; 771 772 data = (uint8_t *)(buf + 4 * 2 * (1 + num)); 773 if ((const char *)data > (const char *)pend) 774 { 775 LSQ_DEBUG("parse_hs tag '%.*s' error: data not enough", 4, (char *)head_tag); 776 return DATA_NOT_ENOUGH; 777 } 778 779 /* check last offset */ 780 memcpy((char *)&len, data - 4, 4); 781 if ((const char *)data + len > (const char *)pend) 782 { 783 LSQ_DEBUG("parse_hs tag '%.*s' error: data not enough!!!", 4, (char *)head_tag); 784 return DATA_NOT_ENOUGH; 785 } 786 787 for (i=0; i<num; ++i) 788 { 789 memcpy((char *)&tag, p, 4); 790 p += 4; 791 memcpy((char *)&len, p, 4); 792 len -= offset; 793 p += 4; 794 795 if ((const char *)data + offset + len > (const char *)pend) 796 return DATA_FORMAT_ERROR; 797 798 if (0 != parse_hs_data(enc_session, tag, data + offset, len, 799 *head_tag)) 800 return DATA_FORMAT_ERROR; 801 offset += len; 802 } 803 804 LSQ_DEBUG("parse_hs tag '%.*s' no error.", 4, (char *)head_tag); 805 return DATA_NO_ERROR; 806} 807 808 809static uint32_t get_tag_value_i32(unsigned char *val, int len) 810{ 811 uint32_t v; 812 if (len < 4) 813 return 0; 814 memcpy(&v, val, 4); 815 return v; 816} 817 818 819static uint64_t get_tag_value_i64(unsigned char *val, int len) 820{ 821 uint64_t v; 822 if (len < 8) 823 return 0; 824 memcpy(&v, val, 8); 825 return v; 826} 827 828 829static int 830get_tag_val_u32 (unsigned char *v, int len, uint32_t *val) 831{ 832 if (len != 4) 833 return -1; 834 memcpy(val, v, 4); 835 return 0; 836} 837 838 839static void 840generate_cid_buf (void *buf, size_t bufsz) 841{ 842 RAND_bytes(buf, bufsz); 843} 844 845 846static lsquic_cid_t 847lsquic_generate_cid (void) 848{ 849 lsquic_cid_t cid; 850 generate_cid_buf(&cid, sizeof(cid)); 851 return cid; 852} 853 854 855/* From "QUIC Crypto" for easy reference: 856 * 857 * A handshake message consists of: 858 * - The tag of the message. 859 * - A uint16 containing the number of tag-value pairs. 860 * - Two bytes of padding which should be zero when sent but ignored when 861 * received. 862 * - A series of uint32 tags and uint32 end offsets, one for each 863 * tag-value pair. The tags must be strictly monotonically 864 * increasing, and the end-offsets must be monotonic non-decreasing. 865 * The end offset gives the offset, from the start of the value 866 * data, to a byte one beyond the end of the data for that tag. 867 * (Thus the end offset of the last tag contains the length of the 868 * value data). 869 * - The value data, concatenated without padding. 870 */ 871 872struct table_entry { uint32_t tag, off; }; 873 874struct message_writer 875{ 876 unsigned char *mw_p; 877 struct table_entry mw_first_dummy_entry; 878 struct table_entry *mw_entry, 879 *mw_prev_entry, 880 *mw_end; 881}; 882 883/* MW_ family of macros is used to write entries to handshake message 884 * (MW stands for "message writer"). 885 */ 886#define MW_BEGIN(mw, msg_tag, n_entries, data_ptr) do { \ 887 uint32_t t_ = msg_tag; \ 888 uint16_t n_ = n_entries; \ 889 memcpy(data_ptr, &t_, 4); \ 890 memcpy(data_ptr + 4, &n_, 2); \ 891 memset(data_ptr + 4 + 2, 0, 2); \ 892 (mw)->mw_entry = (void *) (data_ptr + 8); \ 893 (mw)->mw_p = data_ptr + 8 + \ 894 (n_entries) * sizeof((mw)->mw_entry[0]); \ 895 (mw)->mw_first_dummy_entry.tag = 0; \ 896 (mw)->mw_first_dummy_entry.off = 0; \ 897 (mw)->mw_prev_entry = &(mw)->mw_first_dummy_entry; \ 898 (mw)->mw_end = (void *) (mw)->mw_p; \ 899} while (0) 900 901#ifndef NDEBUG 902# define MW_END(mw) do { \ 903 assert((mw)->mw_entry == (mw)->mw_end); \ 904 } while (0) 905#else 906# define MW_END(mw) 907#endif 908 909#define MW_P(mw) ((mw)->mw_p) 910 911#define MW_ADVANCE_P(mw, n) do { \ 912 MW_P(mw) += (n); \ 913} while (0) 914 915#define MW_WRITE_TABLE_ENTRY(mw, tag_, sz) do { \ 916 assert((mw)->mw_prev_entry->tag < (tag_)); \ 917 assert((mw)->mw_entry < (mw)->mw_end); \ 918 (mw)->mw_entry->tag = (tag_); \ 919 (mw)->mw_entry->off = (mw)->mw_prev_entry->off + (sz); \ 920 (mw)->mw_prev_entry = (mw)->mw_entry; \ 921 ++(mw)->mw_entry; \ 922} while (0) 923 924#define MW_WRITE_BUFFER(mw, tag, buf, sz) do { \ 925 MW_WRITE_TABLE_ENTRY(mw, tag, sz); \ 926 memcpy(MW_P(mw), buf, sz); \ 927 MW_ADVANCE_P(mw, sz); \ 928} while (0) 929 930#define MW_WRITE_LS_STR(mw, tag, s) \ 931 MW_WRITE_BUFFER(mw, tag, lsquic_str_buf(s), lsquic_str_len(s)) 932 933#define MW_WRITE_UINT32(mw, tag, val) do { \ 934 uint32_t v_ = (val); \ 935 MW_WRITE_BUFFER(mw, tag, &v_, sizeof(v_)); \ 936} while (0) 937 938#define MW_WRITE_UINT64(mw, tag, val) do { \ 939 uint64_t v_ = (val); \ 940 MW_WRITE_BUFFER(mw, tag, &v_, sizeof(v_)); \ 941} while (0) 942 943 944/* MSG_LEN_ family of macros calculates buffer size required for a 945 * handshake message. 946 */ 947#define MSG_LEN_INIT(len) do { \ 948 len = 4 /* Tag */ + 2 /* # tags */ + 2 /* Two zero bytes */; \ 949} while (0) 950 951#define MSG_LEN_ADD(len, payload_sz) do { \ 952 len += 4 + 4 + (payload_sz); \ 953} while (0) 954 955#define MSG_LEN_VAL(len) (+(len)) 956 957 958static int 959lsquic_enc_session_gen_chlo (lsquic_enc_session_t *enc_session, 960 enum lsquic_version version, uint8_t *buf, size_t *len) 961{ 962 int ret, include_pad; 963 const lsquic_str_t *const ccs = get_common_certs_hash(); 964 const struct lsquic_engine_settings *const settings = 965 &enc_session->enpub->enp_settings; 966 c_cert_item_t *const cert_item = enc_session->cert_item; 967 unsigned char pub_key[32]; 968 size_t ua_len; 969 uint32_t opts[1]; /* Only NSTP is supported for now */ 970 unsigned n_opts, msg_len, n_tags, pad_size; 971 struct message_writer mw; 972 973 /* Before we do anything else, sanity check: */ 974 if (*len < MIN_CHLO_SIZE) 975 return -1; 976 977 n_opts = 0; 978 /* CHLO is not regenerated during version negotiation. Hence we always 979 * include this option to cover the case when Q044 gets negotiated down. 980 */ 981 if (settings->es_support_nstp) 982 opts[ n_opts++ ] = QTAG_NSTP; 983 984 /* Count tags and calculate required buffer size: */ 985 MSG_LEN_INIT(msg_len); n_tags = 0; 986 MSG_LEN_ADD(msg_len, 4); ++n_tags; /* PDMD */ 987 MSG_LEN_ADD(msg_len, 4); ++n_tags; /* AEAD */ 988 MSG_LEN_ADD(msg_len, 4); ++n_tags; /* VER */ 989 MSG_LEN_ADD(msg_len, 4); ++n_tags; /* MIDS */ 990 MSG_LEN_ADD(msg_len, 4); ++n_tags; /* SCLS */ 991 MSG_LEN_ADD(msg_len, 4); ++n_tags; /* CFCW */ 992 MSG_LEN_ADD(msg_len, 4); ++n_tags; /* SFCW */ 993 MSG_LEN_ADD(msg_len, 4); ++n_tags; /* ICSL */ 994 MSG_LEN_ADD(msg_len, 4); ++n_tags; /* SMHL */ 995 MSG_LEN_ADD(msg_len, 4); ++n_tags; /* KEXS */ 996 MSG_LEN_ADD(msg_len, 0); ++n_tags; /* CSCT */ 997 if (n_opts > 0) 998 { 999 MSG_LEN_ADD(msg_len, sizeof(opts[0]) * n_opts); 1000 ++n_tags; /* COPT */ 1001 } 1002 if (settings->es_ua) 1003 { 1004 ua_len = strlen(settings->es_ua); 1005 if (ua_len > 0) 1006 { 1007 MSG_LEN_ADD(msg_len, ua_len); ++n_tags; /* UAID */ 1008 } 1009 } 1010 else 1011 ua_len = 0; 1012 if (settings->es_support_tcid0) 1013 { 1014 MSG_LEN_ADD(msg_len, 4); ++n_tags; /* TCID */ 1015 } 1016 MSG_LEN_ADD(msg_len, lsquic_str_len(&enc_session->hs_ctx.sni)); 1017 ++n_tags; /* SNI */ 1018 MSG_LEN_ADD(msg_len, lsquic_str_len(ccs)); ++n_tags; /* CCS */ 1019 if (cert_item) 1020 { 1021 enc_session->cert_ptr = &cert_item->crts[0]; 1022 MSG_LEN_ADD(msg_len, lsquic_str_len(cert_item->hashs)); 1023 ++n_tags; /* CCRT */ 1024 MSG_LEN_ADD(msg_len, 8); ++n_tags; /* XLCT */ 1025 } 1026 MSG_LEN_ADD(msg_len, lsquic_str_len(&enc_session->ssno)); 1027 ++n_tags; /* SNO */ 1028 MSG_LEN_ADD(msg_len, lsquic_str_len(&enc_session->info->sstk)); 1029 ++n_tags; /* STK */ 1030 if (lsquic_str_len(&enc_session->info->scfg) > 0) 1031 { 1032 MSG_LEN_ADD(msg_len, sizeof(enc_session->info->sscid)); 1033 ++n_tags; /* SCID */ 1034 if (enc_session->cert_ptr) 1035 { 1036 MSG_LEN_ADD(msg_len, sizeof(pub_key)); 1037 ++n_tags; /* PUBS */ 1038 MSG_LEN_ADD(msg_len, sizeof(enc_session->hs_ctx.nonc)); 1039 ++n_tags; /* NONC */ 1040 rand_bytes(enc_session->priv_key, 32); 1041 c255_get_pub_key(enc_session->priv_key, pub_key); 1042 gen_nonce_c(enc_session->hs_ctx.nonc, enc_session->info->orbt); 1043 } 1044 } 1045 include_pad = MSG_LEN_VAL(msg_len) < MIN_CHLO_SIZE; 1046 if (include_pad) 1047 { 1048 if (MSG_LEN_VAL(msg_len) + sizeof(struct table_entry) < MIN_CHLO_SIZE) 1049 pad_size = MIN_CHLO_SIZE - MSG_LEN_VAL(msg_len) - 1050 sizeof(struct table_entry); 1051 else 1052 pad_size = 0; 1053 MSG_LEN_ADD(msg_len, pad_size); ++n_tags; /* PAD */ 1054 } 1055#ifdef WIN32 1056 else 1057 pad_size = 0; 1058#endif 1059 1060 /* Check that we have enough room in the output buffer: */ 1061 if (MSG_LEN_VAL(msg_len) > *len) 1062 return -1; 1063 1064 /* Write CHLO: */ 1065 MW_BEGIN(&mw, QTAG_CHLO, n_tags, buf); 1066 if (include_pad) 1067 { 1068 memset(MW_P(&mw), '-', pad_size); 1069 MW_WRITE_TABLE_ENTRY(&mw, QTAG_PAD, pad_size); 1070 MW_ADVANCE_P(&mw, pad_size); 1071 } 1072 MW_WRITE_LS_STR(&mw, QTAG_SNI, &enc_session->hs_ctx.sni); 1073 MW_WRITE_LS_STR(&mw, QTAG_STK, &enc_session->info->sstk); 1074 MW_WRITE_LS_STR(&mw, QTAG_SNO, &enc_session->ssno); 1075 MW_WRITE_UINT32(&mw, QTAG_VER, lsquic_ver2tag(version)); 1076 MW_WRITE_LS_STR(&mw, QTAG_CCS, ccs); 1077 if (lsquic_str_len(&enc_session->info->scfg) > 0 && enc_session->cert_ptr) 1078 MW_WRITE_BUFFER(&mw, QTAG_NONC, enc_session->hs_ctx.nonc, 1079 sizeof(enc_session->hs_ctx.nonc)); 1080 MW_WRITE_UINT32(&mw, QTAG_AEAD, settings->es_aead); 1081 if (ua_len) 1082 MW_WRITE_BUFFER(&mw, QTAG_UAID, settings->es_ua, ua_len); 1083 if (lsquic_str_len(&enc_session->info->scfg) > 0) 1084 MW_WRITE_BUFFER(&mw, QTAG_SCID, enc_session->info->sscid, 1085 sizeof(enc_session->info->sscid)); 1086 if (settings->es_support_tcid0) 1087 MW_WRITE_UINT32(&mw, QTAG_TCID, 0); 1088 MW_WRITE_UINT32(&mw, QTAG_PDMD, settings->es_pdmd); 1089 MW_WRITE_UINT32(&mw, QTAG_SMHL, 1); 1090 MW_WRITE_UINT32(&mw, QTAG_ICSL, settings->es_idle_conn_to / 1000000); 1091 if (lsquic_str_len(&enc_session->info->scfg) > 0 && enc_session->cert_ptr) 1092 MW_WRITE_BUFFER(&mw, QTAG_PUBS, pub_key, sizeof(pub_key)); 1093 MW_WRITE_UINT32(&mw, QTAG_MIDS, settings->es_max_streams_in); 1094 MW_WRITE_UINT32(&mw, QTAG_SCLS, settings->es_silent_close); 1095 MW_WRITE_UINT32(&mw, QTAG_KEXS, settings->es_kexs); 1096 if (cert_item) 1097 MW_WRITE_BUFFER(&mw, QTAG_XLCT, lsquic_str_buf(cert_item->hashs), 8); 1098 /* CSCT is empty on purpose (retained from original code) */ 1099 MW_WRITE_TABLE_ENTRY(&mw, QTAG_CSCT, 0); 1100 if (n_opts > 0) 1101 MW_WRITE_BUFFER(&mw, QTAG_COPT, opts, n_opts * sizeof(opts[0])); 1102 if (cert_item) 1103 MW_WRITE_LS_STR(&mw, QTAG_CCRT, cert_item->hashs); 1104 MW_WRITE_UINT32(&mw, QTAG_CFCW, settings->es_cfcw); 1105 MW_WRITE_UINT32(&mw, QTAG_SFCW, settings->es_sfcw); 1106 MW_END(&mw); 1107 assert(buf + *len >= MW_P(&mw)); 1108 1109 *len = MW_P(&mw) - buf; 1110 1111 lsquic_str_setto(&enc_session->chlo, buf, *len); 1112 1113 if (lsquic_str_len(&enc_session->info->scfg) > 0 && enc_session->cert_ptr) 1114 { 1115 enc_session->have_key = 0; 1116 assert(lsquic_str_len(enc_session->cert_ptr) > 0); 1117 ret = determine_keys(enc_session 1118 ); 1119 enc_session->have_key = 1; 1120 } 1121 else 1122 ret = 0; 1123 1124 LSQ_DEBUG("lsquic_enc_session_gen_chlo called, return %d, buf_len %zd.", ret, *len); 1125 return ret; 1126} 1127 1128 1129static int handle_chlo_reply_verify_prof(lsquic_enc_session_t *enc_session, 1130 lsquic_str_t **out_certs, 1131 size_t *out_certs_count, 1132 lsquic_str_t *cached_certs, 1133 int cached_certs_count) 1134{ 1135 const unsigned char *const in = 1136 (const unsigned char *) lsquic_str_buf(&enc_session->hs_ctx.crt); 1137 const unsigned char *const in_end = 1138 in + lsquic_str_len(&enc_session->hs_ctx.crt); 1139 EVP_PKEY *pub_key; 1140 int ret; 1141 size_t i; 1142 X509 *cert, *server_cert; 1143 STACK_OF(X509) *chain = NULL; 1144 ret = decompress_certs(in, in_end,cached_certs, cached_certs_count, 1145 out_certs, out_certs_count); 1146 if (ret) 1147 return ret; 1148 1149 server_cert = bio_to_crt((const char *)lsquic_str_cstr(out_certs[0]), 1150 lsquic_str_len(out_certs[0]), 0); 1151 pub_key = X509_get_pubkey(server_cert); 1152 ret = verify_prof((const uint8_t *)lsquic_str_cstr(&enc_session->chlo), 1153 (size_t)lsquic_str_len(&enc_session->chlo), 1154 &enc_session->info->scfg, 1155 pub_key, 1156 (const uint8_t *)lsquic_str_cstr(&enc_session->hs_ctx.prof), 1157 lsquic_str_len(&enc_session->hs_ctx.prof)); 1158 EVP_PKEY_free(pub_key); 1159 if (ret != 0) 1160 goto cleanup; 1161 1162 if (enc_session->enpub->enp_verify_cert) 1163 { 1164 chain = sk_X509_new_null(); 1165 sk_X509_push(chain, server_cert); 1166 for (i = 1; i < *out_certs_count; ++i) 1167 { 1168 cert = bio_to_crt((const char *)lsquic_str_cstr(out_certs[i]), 1169 lsquic_str_len(out_certs[i]), 0); 1170 if (cert) 1171 sk_X509_push(chain, cert); 1172 else 1173 { 1174 LSQ_WARN("cannot push certificate to stack"); 1175 ret = -1; 1176 goto cleanup; 1177 } 1178 } 1179 ret = enc_session->enpub->enp_verify_cert( 1180 enc_session->enpub->enp_verify_ctx, chain); 1181 LSQ_INFO("server certificate verification %ssuccessful", 1182 ret == 0 ? "" : "not "); 1183 } 1184 1185 cleanup: 1186 if (chain) 1187 sk_X509_free(chain); 1188 X509_free(server_cert); 1189 return ret; 1190} 1191 1192 1193void setup_aead_ctx(EVP_AEAD_CTX **ctx, unsigned char key[], int key_len, 1194 unsigned char *key_copy) 1195{ 1196 const EVP_AEAD *aead_ = EVP_aead_aes_128_gcm(); 1197 const int auth_tag_size = 12; 1198 if (*ctx) 1199 { 1200 EVP_AEAD_CTX_cleanup(*ctx); 1201 } 1202 else 1203 *ctx = (EVP_AEAD_CTX *)malloc(sizeof(EVP_AEAD_CTX)); 1204 1205 EVP_AEAD_CTX_init(*ctx, aead_, key, key_len, auth_tag_size, NULL); 1206 if (key_copy) 1207 memcpy(key_copy, key, key_len); 1208} 1209 1210 1211static int 1212determine_diversification_key (lsquic_enc_session_t *enc_session, 1213 uint8_t *diversification_nonce 1214 ) 1215{ 1216 EVP_AEAD_CTX **ctx_s_key; 1217 unsigned char *key_i, *iv; 1218 uint8_t ikm[aes128_key_len + aes128_iv_len]; 1219 1220 ctx_s_key = &enc_session->dec_ctx_i; 1221 key_i = enc_session->dec_key_i; 1222 iv = enc_session->dec_key_nonce_i; 1223 memcpy(ikm, key_i, aes128_key_len); 1224 memcpy(ikm + aes128_key_len, iv, aes128_iv_len); 1225 export_key_material(ikm, aes128_key_len + aes128_iv_len, 1226 diversification_nonce, DNONC_LENGTH, 1227 (const unsigned char *) "QUIC key diversification", 24, 1228 0, NULL, aes128_key_len, key_i, 0, NULL, 1229 aes128_iv_len, iv, NULL); 1230 1231 setup_aead_ctx(ctx_s_key, key_i, aes128_key_len, NULL); 1232 LSQ_DEBUG("determine_diversification_keys diversification_key: %s\n", 1233 get_bin_str(key_i, aes128_key_len, 512)); 1234 LSQ_DEBUG("determine_diversification_keys diversification_key nonce: %s\n", 1235 get_bin_str(iv, aes128_iv_len, 512)); 1236 return 0; 1237} 1238 1239 1240/* After CHLO msg generatered, call it to determine_keys */ 1241static int determine_keys(lsquic_enc_session_t *enc_session) 1242{ 1243 lsquic_str_t *chlo = &enc_session->chlo; 1244 uint8_t shared_key_c[32]; 1245 struct lsquic_buf *nonce_c = lsquic_buf_create(100); 1246 struct lsquic_buf *hkdf_input = lsquic_buf_create(0); 1247 1248 unsigned char c_key[aes128_key_len]; 1249 unsigned char s_key[aes128_key_len]; 1250 unsigned char *c_key_bin = NULL; 1251 unsigned char *s_key_bin = NULL; 1252 1253 unsigned char *c_iv; 1254 unsigned char *s_iv; 1255 unsigned char sub_key[32]; 1256 EVP_AEAD_CTX **ctx_c_key, **ctx_s_key; 1257 char key_flag; 1258 1259 lsquic_buf_clear(nonce_c); 1260 lsquic_buf_clear(hkdf_input); 1261 if (enc_session->have_key == 0) 1262 { 1263 lsquic_buf_append(hkdf_input, "QUIC key expansion\0", 18 + 1); // Add a 0x00 */ 1264 key_flag = 'I'; 1265 } 1266 else 1267 { 1268 lsquic_buf_append(hkdf_input, "QUIC forward secure key expansion\0", 33 + 1); // Add a 0x00 */ 1269 key_flag = 'F'; 1270 } 1271 1272 c255_gen_share_key(enc_session->priv_key, 1273 enc_session->hs_ctx.pubs, 1274 (unsigned char *)shared_key_c); 1275 { 1276 if (enc_session->have_key == 0) 1277 { 1278 ctx_c_key = &enc_session->enc_ctx_i; 1279 ctx_s_key = &enc_session->dec_ctx_i; 1280 c_iv = (unsigned char *) enc_session->enc_key_nonce_i; 1281 s_iv = (unsigned char *) enc_session->dec_key_nonce_i; 1282 c_key_bin = enc_session->enc_key_i; 1283 s_key_bin = enc_session->dec_key_i; 1284 } 1285 else 1286 { 1287 ctx_c_key = &enc_session->enc_ctx_f; 1288 ctx_s_key = &enc_session->dec_ctx_f; 1289 c_iv = (unsigned char *) enc_session->enc_key_nonce_f; 1290 s_iv = (unsigned char *) enc_session->dec_key_nonce_f; 1291 } 1292 } 1293 1294 LSQ_DEBUG("export_key_material c255_gen_share_key %s", 1295 get_bin_str(shared_key_c, 32, 512)); 1296 1297 lsquic_buf_append(hkdf_input, (char *)&enc_session->cid, sizeof(enc_session->cid)); 1298 lsquic_buf_append(hkdf_input, lsquic_str_cstr(chlo), lsquic_str_len(chlo)); /* CHLO msg */ 1299 { 1300 lsquic_buf_append(hkdf_input, lsquic_str_cstr(&enc_session->info->scfg), 1301 lsquic_str_len(&enc_session->info->scfg)); /* scfg msg */ 1302 } 1303 lsquic_buf_append(hkdf_input, lsquic_str_cstr(enc_session->cert_ptr), 1304 lsquic_str_len(enc_session->cert_ptr)); 1305 LSQ_DEBUG("export_key_material hkdf_input %s", 1306 get_bin_str(lsquic_buf_begin(hkdf_input), 1307 (size_t)lsquic_buf_size(hkdf_input), 512)); 1308 1309 /* then need to use the salts and the shared_key_* to get the real aead key */ 1310 lsquic_buf_append(nonce_c, (const char *) enc_session->hs_ctx.nonc, 32); 1311 lsquic_buf_append(nonce_c, lsquic_str_cstr(&enc_session->ssno), 1312 lsquic_str_len(&enc_session->ssno)); 1313 LSQ_DEBUG("export_key_material nonce %s", 1314 get_bin_str(lsquic_buf_begin(nonce_c), 1315 (size_t)lsquic_buf_size(nonce_c), 512)); 1316 1317 export_key_material(shared_key_c, 32, 1318 (unsigned char *)lsquic_buf_begin(nonce_c), lsquic_buf_size(nonce_c), 1319 (unsigned char *)lsquic_buf_begin(hkdf_input), 1320 lsquic_buf_size(hkdf_input), 1321 aes128_key_len, c_key, 1322 aes128_key_len, s_key, 1323 aes128_iv_len, c_iv, 1324 aes128_iv_len, s_iv, 1325 sub_key); 1326 1327 setup_aead_ctx(ctx_c_key, c_key, aes128_key_len, c_key_bin); 1328 setup_aead_ctx(ctx_s_key, s_key, aes128_key_len, s_key_bin); 1329 1330 1331 lsquic_buf_destroy(nonce_c); 1332 lsquic_buf_destroy(hkdf_input); 1333 1334 LSQ_DEBUG("***export_key_material '%c' c_key: %s", key_flag, 1335 get_bin_str(c_key, aes128_key_len, 512)); 1336 LSQ_DEBUG("***export_key_material '%c' s_key: %s", key_flag, 1337 get_bin_str(s_key, aes128_key_len, 512)); 1338 LSQ_DEBUG("***export_key_material '%c' c_iv: %s", key_flag, 1339 get_bin_str(c_iv, aes128_iv_len, 512)); 1340 LSQ_DEBUG("***export_key_material '%c' s_iv: %s", key_flag, 1341 get_bin_str(s_iv, aes128_iv_len, 512)); 1342 LSQ_DEBUG("***export_key_material '%c' subkey: %s", key_flag, 1343 get_bin_str(sub_key, 32, 512)); 1344 1345 return 0; 1346} 1347 1348 1349/* 0 Match */ 1350static int cached_certs_match(c_cert_item_t *item, 1351 lsquic_str_t **certs, int count) 1352{ 1353 int i; 1354 if (!item || item->count != count) 1355 return -1; 1356 1357 for (i=0; i<count; ++i) 1358 { 1359 if (lsquic_str_bcmp(certs[i], &item->crts[i]) != 0) 1360 return -1; 1361 } 1362 1363 return 0; 1364} 1365 1366 1367static const char * 1368he2str (enum handshake_error he) 1369{ 1370 switch (he) 1371 { 1372 case DATA_NOT_ENOUGH: return "DATA_NOT_ENOUGH"; 1373 case HS_ERROR: return "HS_ERROR"; 1374 case HS_SHLO: return "HS_SHLO"; 1375 case HS_1RTT: return "HS_1RTT"; 1376 case HS_2RTT: return "HS_2RTT"; 1377 default: 1378 assert(0); return "<unknown enum value>"; 1379 } 1380} 1381 1382 1383/* NOT packet, just the frames-data */ 1384/* return rtt number: 1385 * 0 OK 1386 * DATA_NOT_ENOUGH(-2) for not enough data, 1387 * DATA_FORMAT_ERROR(-1) all other errors 1388 */ 1389static int 1390lsquic_enc_session_handle_chlo_reply (lsquic_enc_session_t *enc_session, 1391 const uint8_t *data, int len) 1392{ 1393 uint32_t head_tag; 1394 int ret; 1395 lsquic_session_cache_info_t *info = enc_session->info; 1396 c_cert_item_t *cert_item = enc_session->cert_item; 1397 1398 /* FIXME get the number first */ 1399 lsquic_str_t **out_certs = NULL; 1400 size_t out_certs_count = 0, i; 1401 1402 ret = parse_hs(enc_session, data, len, &head_tag); 1403 if (ret) 1404 goto end; 1405 1406 if (head_tag != QTAG_SREJ && 1407 head_tag != QTAG_REJ && 1408 head_tag != QTAG_SHLO) 1409 { 1410 ret = 1; 1411 goto end; 1412 } 1413 1414 if (head_tag == QTAG_SREJ || head_tag == QTAG_REJ) 1415 { 1416 enc_session->hsk_state = HSK_CHLO_REJ; 1417 enc_session->es_flags |= ES_RECV_REJ; 1418 } 1419 else if(head_tag == QTAG_SHLO) 1420 { 1421 enc_session->hsk_state = HSK_COMPLETED; 1422 } 1423 1424 if (info->scfg_flag == 1) 1425 { 1426 ret = parse_hs(enc_session, (uint8_t *)lsquic_str_cstr(&info->scfg), 1427 lsquic_str_len(&info->scfg), &head_tag); 1428 1429 /* After handled, set the length to 0 to avoid do it again*/ 1430 enc_session->info->scfg_flag = 2; 1431 if (ret) 1432 goto end; 1433 1434 if (lsquic_str_len(&enc_session->hs_ctx.crt) > 0) 1435 { 1436 out_certs_count = get_certs_count(&enc_session->hs_ctx.crt); 1437 if (out_certs_count > 0) 1438 { 1439 out_certs = malloc(out_certs_count * sizeof(lsquic_str_t *)); 1440 if (!out_certs) 1441 { 1442 ret = -1; 1443 goto end; 1444 } 1445 1446 for (i=0; i<out_certs_count; ++i) 1447 out_certs[i] = lsquic_str_new(NULL, 0); 1448 1449 ret = handle_chlo_reply_verify_prof(enc_session, out_certs, 1450 &out_certs_count, 1451 (cert_item ? cert_item->crts : NULL), 1452 (cert_item ? cert_item->count : 0)); 1453 if (ret == 0) 1454 { 1455 if (out_certs_count > 0) 1456 { 1457 if (cached_certs_match(cert_item, out_certs, 1458 out_certs_count) != 0) 1459 { 1460 cert_item = make_c_cert_item(out_certs, 1461 out_certs_count); 1462 enc_session->cert_item = cert_item; 1463 enc_session->cert_ptr = &cert_item->crts[0]; 1464 } 1465 } 1466 } 1467 for (i=0; i<out_certs_count; ++i) 1468 lsquic_str_delete(out_certs[i]); 1469 free(out_certs); 1470 1471 if (ret) 1472 goto end; 1473 } 1474 } 1475 } 1476 1477 if (enc_session->hsk_state == HSK_COMPLETED) 1478 { 1479 ret = determine_keys(enc_session 1480 ); /* FIXME: check ret */ 1481 enc_session->have_key = 3; 1482 } 1483 1484 end: 1485 LSQ_DEBUG("lsquic_enc_session_handle_chlo_reply called, buf in %d, return %d.", len, ret); 1486 EV_LOG_CONN_EVENT(enc_session->cid, "%s returning %s", __func__, 1487 he2str(ret)); 1488 return ret; 1489} 1490 1491 1492static uint64_t combine_path_id_pack_num(uint8_t path_id, uint64_t pack_num) 1493{ 1494 uint64_t v = ((uint64_t)path_id << 56) | pack_num; 1495 return v; 1496} 1497 1498 1499# define IS_SERVER(session) 0 1500 1501static int 1502verify_packet_hash (const lsquic_enc_session_t *enc_session, 1503 enum lsquic_version version, const unsigned char *buf, size_t *header_len, 1504 size_t data_len, unsigned char *buf_out, size_t max_out_len, 1505 size_t *out_len) 1506{ 1507 uint8_t md[HS_PKT_HASH_LENGTH]; 1508 uint128 hash; 1509 int ret; 1510 1511 if (data_len < HS_PKT_HASH_LENGTH) 1512 return -1; 1513 1514 if (version >= LSQVER_039) 1515 { 1516 hash = fnv1a_128_3(buf, *header_len, 1517 buf + *header_len + HS_PKT_HASH_LENGTH, 1518 data_len - HS_PKT_HASH_LENGTH, 1519 (unsigned char *) "Server", 6); 1520 } 1521 else 1522 { 1523 hash = fnv1a_128_2(buf, *header_len, 1524 buf + *header_len + HS_PKT_HASH_LENGTH, 1525 data_len - HS_PKT_HASH_LENGTH); 1526 } 1527 1528 serialize_fnv128_short(hash, md); 1529 ret = memcmp(md, buf + *header_len, HS_PKT_HASH_LENGTH); 1530 if(ret == 0) 1531 { 1532 *header_len += HS_PKT_HASH_LENGTH; 1533 *out_len = data_len - HS_PKT_HASH_LENGTH; 1534 if (max_out_len < *header_len + *out_len) 1535 return -1; 1536 1537 memcpy(buf_out, buf, *header_len + *out_len); 1538 return 0; 1539 } 1540 else 1541 return -1; 1542} 1543 1544 1545static enum enc_level 1546decrypt_packet (lsquic_enc_session_t *enc_session, uint8_t path_id, 1547 uint64_t pack_num, unsigned char *buf, size_t *header_len, 1548 size_t data_len, unsigned char *buf_out, size_t max_out_len, 1549 size_t *out_len) 1550{ 1551 int ret; 1552 /* Comment: 12 = sizeof(dec_key_iv] 4 + sizeof(pack_num) 8 */ 1553 uint8_t nonce[12]; 1554 uint64_t path_id_packet_number; 1555 EVP_AEAD_CTX *key = NULL; 1556 int try_times = 0; 1557 enum enc_level enc_level; 1558 1559 path_id_packet_number = combine_path_id_pack_num(path_id, pack_num); 1560 memcpy(buf_out, buf, *header_len); 1561 do 1562 { 1563 if (enc_session->have_key == 3 && try_times == 0) 1564 { 1565 key = enc_session->dec_ctx_f; 1566 memcpy(nonce, enc_session->dec_key_nonce_f, 4); 1567 LSQ_DEBUG("decrypt_packet using 'F' key..."); 1568 enc_level = ENC_LEV_FORW; 1569 } 1570 else 1571 { 1572 key = enc_session->dec_ctx_i; 1573 memcpy(nonce, enc_session->dec_key_nonce_i, 4); 1574 LSQ_DEBUG("decrypt_packet using 'I' key..."); 1575 enc_level = ENC_LEV_INIT; 1576 } 1577 memcpy(nonce + 4, &path_id_packet_number, 1578 sizeof(path_id_packet_number)); 1579 1580 *out_len = data_len; 1581 ret = aes_aead_dec(key, 1582 buf, *header_len, 1583 nonce, 12, 1584 buf + *header_len, data_len, 1585 buf_out + *header_len, out_len); 1586 1587 if (ret != 0) 1588 ++try_times; 1589 else 1590 { 1591 if (enc_session->peer_have_final_key == 0 && 1592 enc_session->have_key == 3 && 1593 try_times == 0) 1594 { 1595 LSQ_DEBUG("!!!decrypt_packet find peer have final key."); 1596 enc_session->peer_have_final_key = 1; 1597 EV_LOG_CONN_EVENT(enc_session->cid, "settled on private key " 1598 "'%c' after %d tries (packet number %"PRIu64")", 1599 key == enc_session->dec_ctx_f ? 'F' : 'I', 1600 try_times, pack_num); 1601 } 1602 break; 1603 } 1604 } 1605 while (try_times < 2); 1606 1607 LSQ_DEBUG("***decrypt_packet %s.", (ret == 0 ? "succeed" : "failed")); 1608 return ret == 0 ? enc_level : (enum enc_level) -1; 1609} 1610 1611 1612static int 1613lsquic_enc_session_have_key_gt_one (const lsquic_enc_session_t *enc_session) 1614{ 1615 return enc_session && enc_session->have_key > 1; 1616} 1617 1618 1619/* The size of `buf' is *header_len plus data_len. The two parts of the 1620 * buffer correspond to the header and the payload of incoming QUIC packet. 1621 */ 1622static enum enc_level 1623lsquic_enc_session_decrypt (lsquic_enc_session_t *enc_session, 1624 enum lsquic_version version, 1625 uint8_t path_id, uint64_t pack_num, 1626 unsigned char *buf, size_t *header_len, size_t data_len, 1627 unsigned char *diversification_nonce, 1628 unsigned char *buf_out, size_t max_out_len, size_t *out_len) 1629{ 1630 /* Client: got SHLO which should have diversification_nonce */ 1631 if (diversification_nonce && enc_session && enc_session->have_key == 1) 1632 { 1633 determine_diversification_key(enc_session, diversification_nonce); 1634 enc_session->have_key = 2; 1635 } 1636 1637 if (lsquic_enc_session_have_key_gt_one(enc_session)) 1638 return decrypt_packet(enc_session, path_id, pack_num, buf, 1639 header_len, data_len, buf_out, max_out_len, out_len); 1640 else if (0 == verify_packet_hash(enc_session, version, buf, header_len, 1641 data_len, buf_out, max_out_len, out_len)) 1642 return ENC_LEV_CLEAR; 1643 else 1644 return -1; 1645} 1646 1647 1648static enum enc_level 1649lsquic_enc_session_encrypt (lsquic_enc_session_t *enc_session, 1650 enum lsquic_version version, 1651 uint8_t path_id, uint64_t pack_num, 1652 const unsigned char *header, size_t header_len, 1653 const unsigned char *data, size_t data_len, 1654 unsigned char *buf_out, size_t max_out_len, size_t *out_len, 1655 int is_hello) 1656{ 1657 uint8_t md[HS_PKT_HASH_LENGTH]; 1658 uint128 hash; 1659 int ret; 1660 enum enc_level enc_level; 1661 int is_chlo = (is_hello && ((IS_SERVER(enc_session)) == 0)); 1662 int is_shlo = (is_hello && (IS_SERVER(enc_session))); 1663 1664 /* Comment: 12 = sizeof(dec_key_iv] 4 + sizeof(pack_num) 8 */ 1665 uint8_t nonce[12]; 1666 uint64_t path_id_packet_number; 1667 EVP_AEAD_CTX *key; 1668 1669 if (enc_session) 1670 LSQ_DEBUG("%s: hsk_state: %d", __func__, enc_session->hsk_state); 1671 else 1672 LSQ_DEBUG("%s: enc_session is not set", __func__); 1673 1674 if (!enc_session || enc_session->have_key == 0 || is_chlo) 1675 { 1676 *out_len = header_len + data_len + HS_PKT_HASH_LENGTH; 1677 if (max_out_len < *out_len) 1678 return -1; 1679 1680 if (version >= LSQVER_039) 1681 { 1682 hash = fnv1a_128_3(header, header_len, data, data_len, 1683 (unsigned char *) "Client", 6); 1684 } 1685 else 1686 { 1687 hash = fnv1a_128_2(header, header_len, data, data_len); 1688 } 1689 1690 serialize_fnv128_short(hash, md); 1691 memcpy(buf_out, header, header_len); 1692 memcpy(buf_out + header_len, md, HS_PKT_HASH_LENGTH); 1693 memcpy(buf_out + header_len + HS_PKT_HASH_LENGTH, data, data_len); 1694 return ENC_LEV_CLEAR; 1695 } 1696 else 1697 { 1698 if (enc_session->have_key != 3 || is_shlo || 1699 ((IS_SERVER(enc_session)) && 1700 enc_session->server_start_use_final_key == 0)) 1701 { 1702 LSQ_DEBUG("lsquic_enc_session_encrypt using 'I' key..."); 1703 key = enc_session->enc_ctx_i; 1704 memcpy(nonce, enc_session->enc_key_nonce_i, 4); 1705 if (is_shlo && enc_session->have_key == 3) 1706 { 1707 enc_session->server_start_use_final_key = 1; 1708 } 1709 enc_level = ENC_LEV_INIT; 1710 } 1711 else 1712 { 1713 LSQ_DEBUG("lsquic_enc_session_encrypt using 'F' key..."); 1714 key = enc_session->enc_ctx_f; 1715 memcpy(nonce, enc_session->enc_key_nonce_f, 4); 1716 enc_level = ENC_LEV_FORW; 1717 } 1718 path_id_packet_number = combine_path_id_pack_num(path_id, pack_num); 1719 memcpy(nonce + 4, &path_id_packet_number, 1720 sizeof(path_id_packet_number)); 1721 1722 memcpy(buf_out, header, header_len); 1723 *out_len = max_out_len - header_len; 1724 1725 ret = aes_aead_enc(key, header, header_len, nonce, 12, data, 1726 data_len, buf_out + header_len, out_len); 1727 if (ret == 0) 1728 { 1729 *out_len += header_len; 1730 return enc_level; 1731 } 1732 else 1733 return -1; 1734 } 1735} 1736 1737 1738static int 1739lsquic_enc_session_get_peer_option (const lsquic_enc_session_t *enc_session, 1740 uint32_t tag) 1741{ 1742 switch (tag) 1743 { 1744 case QTAG_NSTP: 1745 return !!(enc_session->hs_ctx.opts & HOPT_NSTP); 1746 case QTAG_SREJ: 1747 return !!(enc_session->hs_ctx.opts & HOPT_SREJ); 1748 default: 1749 assert(0); 1750 return 0; 1751 } 1752} 1753 1754 1755/* Query a several parameters sent by the peer that are required by 1756 * connection. 1757 */ 1758static int 1759lsquic_enc_session_get_peer_setting (const lsquic_enc_session_t *enc_session, 1760 uint32_t tag, uint32_t *val) 1761{ 1762 switch (tag) 1763 { 1764 case QTAG_TCID: 1765 if (enc_session->hs_ctx.set & HSET_TCID) 1766 { 1767 *val = enc_session->hs_ctx.tcid; 1768 return 0; 1769 } 1770 else 1771 return -1; 1772 case QTAG_SMHL: 1773 if (enc_session->hs_ctx.set & HSET_SMHL) 1774 { 1775 *val = enc_session->hs_ctx.smhl; 1776 return 0; 1777 } 1778 else 1779 return -1; 1780 case QTAG_IRTT: 1781 if (enc_session->hs_ctx.set & HSET_IRTT) 1782 { 1783 *val = enc_session->hs_ctx.irtt; 1784 return 0; 1785 } 1786 else 1787 return -1; 1788 } 1789 1790 /* XXX For the following values, there is no record which were present 1791 * in CHLO or SHLO and which were not. Assume that zero means that 1792 * they weren't present. 1793 */ 1794 switch (tag) 1795 { 1796 case QTAG_CFCW: 1797 if (enc_session->hs_ctx.cfcw) 1798 { 1799 *val = enc_session->hs_ctx.cfcw; 1800 return 0; 1801 } 1802 else 1803 return -1; 1804 case QTAG_SFCW: 1805 if (enc_session->hs_ctx.sfcw) 1806 { 1807 *val = enc_session->hs_ctx.sfcw; 1808 return 0; 1809 } 1810 else 1811 return -1; 1812 case QTAG_MIDS: 1813 if (enc_session->hs_ctx.mids) 1814 { 1815 *val = enc_session->hs_ctx.mids; 1816 return 0; 1817 } 1818 else 1819 return -1; 1820 default: 1821 return -1; 1822 } 1823} 1824 1825 1826#if LSQUIC_KEEP_ENC_SESS_HISTORY 1827static void 1828lsquic_get_enc_hist (const lsquic_enc_session_t *enc_session, 1829 char buf[(1 << ESHIST_BITS) + 1]) 1830{ 1831 const unsigned hist_idx = ESHIST_MASK & enc_session->es_hist_idx; 1832 if (enc_session->es_hist_buf[hist_idx] == ESHE_EMPTY) 1833 memcpy(buf, enc_session->es_hist_buf, hist_idx + 1); 1834 else 1835 { 1836 memcpy(buf, enc_session->es_hist_buf + hist_idx, sizeof(enc_session->es_hist_buf) - hist_idx); 1837 memcpy(buf + hist_idx, enc_session->es_hist_buf, hist_idx); 1838 buf[(1 << ESHIST_BITS)] = '\0'; 1839 } 1840} 1841 1842 1843#endif 1844 1845 1846 1847 1848static size_t 1849lsquic_enc_session_mem_used (struct lsquic_enc_session *enc_session) 1850{ 1851 size_t size; 1852 1853 size = sizeof(*enc_session); 1854 1855 size += lsquic_str_len(&enc_session->chlo); 1856 size += lsquic_str_len(&enc_session->sstk); 1857 size += lsquic_str_len(&enc_session->ssno); 1858 1859 size += lsquic_str_len(&enc_session->hs_ctx.ccs); 1860 size += lsquic_str_len(&enc_session->hs_ctx.sni); 1861 size += lsquic_str_len(&enc_session->hs_ctx.ccrt); 1862 size += lsquic_str_len(&enc_session->hs_ctx.stk); 1863 size += lsquic_str_len(&enc_session->hs_ctx.sno); 1864 size += lsquic_str_len(&enc_session->hs_ctx.prof); 1865 size += lsquic_str_len(&enc_session->hs_ctx.csct); 1866 size += lsquic_str_len(&enc_session->hs_ctx.crt); 1867 1868 if (enc_session->info) 1869 { 1870 size += sizeof(*enc_session->info); 1871 size += lsquic_str_len(&enc_session->info->sstk); 1872 size += lsquic_str_len(&enc_session->info->scfg); 1873 size += lsquic_str_len(&enc_session->info->sni_key); 1874 } 1875 1876 /* TODO: calculate memory taken up by SSL stuff */ 1877 1878 return size; 1879} 1880 1881 1882static int 1883lsquic_enc_session_verify_reset_token (lsquic_enc_session_t *enc_session, 1884 const unsigned char *buf, size_t bufsz) 1885{ 1886 if (bufsz == SRST_LENGTH 1887 && (enc_session->hs_ctx.set & HSET_SRST) 1888 && 0 == memcmp(buf, enc_session->hs_ctx.srst, SRST_LENGTH)) 1889 return 0; 1890 else 1891 return -1; 1892} 1893 1894 1895static int 1896lsquic_enc_session_did_zero_rtt_succeed (const lsquic_enc_session_t *enc_session) 1897{ 1898 return !(enc_session->es_flags & ES_RECV_REJ); 1899} 1900 1901 1902static int 1903lsquic_enc_session_is_zero_rtt_enabled (const lsquic_enc_session_t *enc_session) 1904{ 1905 return enc_session->info && enc_session->cert_item; 1906} 1907 1908 1909static c_cert_item_t * 1910lsquic_enc_session_get_cert_item (const lsquic_enc_session_t *enc_session) 1911{ 1912 return enc_session->cert_item; 1913} 1914 1915 1916static STACK_OF(X509) * 1917lsquic_enc_session_get_server_cert_chain (lsquic_enc_session_t *enc_session) 1918{ 1919 const struct c_cert_item_st *item; 1920 STACK_OF(X509) *chain; 1921 X509 *cert; 1922 int i; 1923 1924 item = enc_session->cert_item; 1925 if (!item) 1926 { 1927 LSQ_WARN("could not find certificates for `%.*s'", 1928 (int) lsquic_str_len(&enc_session->hs_ctx.sni), 1929 lsquic_str_cstr(&enc_session->hs_ctx.sni)); 1930 return NULL; 1931 } 1932 1933 chain = sk_X509_new_null(); 1934 for (i = 0; i < item->count; ++i) 1935 { 1936 cert = bio_to_crt(lsquic_str_cstr(&item->crts[i]), 1937 lsquic_str_len(&item->crts[i]), 0); 1938 if (cert) 1939 sk_X509_push(chain, cert); 1940 else 1941 { 1942 sk_X509_free(chain); 1943 return NULL; 1944 } 1945 } 1946 1947 return chain; 1948} 1949 1950 1951ssize_t 1952lsquic_enc_session_get_zero_rtt (lsquic_enc_session_t *enc_session, 1953 enum lsquic_version version, 1954 void *buf, size_t len) 1955{ 1956 int i; 1957 size_t sz = 0; 1958 if (!enc_session->info || !enc_session->cert_item) 1959 { 1960 LSQ_DEBUG("client asked for rtt_into but it is not available"); 1961 return 0; 1962 } 1963 for (i = 0; i < enc_session->cert_item->count; ++i) 1964 { 1965 sz += sizeof(uint32_t); 1966 sz += lsquic_str_len(&enc_session->cert_item->crts[i]); 1967 } 1968 sz += sizeof(struct lsquic_zero_rtt_storage); 1969 if (len < sz) 1970 { 1971 LSQ_DEBUG("client provided buf is too small %zu < %zu", len, sz); 1972 errno = ENOBUFS; 1973 return -1; 1974 } 1975 lsquic_enc_session_serialize_zero_rtt((struct lsquic_zero_rtt_storage *)buf, 1976 version, enc_session->info, 1977 enc_session->cert_item); 1978 return sz; 1979} 1980 1981 1982#ifdef NDEBUG 1983const 1984#endif 1985struct enc_session_funcs lsquic_enc_session_gquic_1 = 1986{ 1987 .esf_global_init = lsquic_handshake_init, 1988 .esf_global_cleanup = lsquic_handshake_cleanup, 1989#if LSQUIC_KEEP_ENC_SESS_HISTORY 1990 .esf_get_hist = lsquic_get_enc_hist, 1991#endif 1992 .esf_destroy = lsquic_enc_session_destroy, 1993 .esf_is_hsk_done = lsquic_enc_session_is_hsk_done, 1994 .esf_encrypt = lsquic_enc_session_encrypt, 1995 .esf_decrypt = lsquic_enc_session_decrypt, 1996 .esf_get_peer_setting = lsquic_enc_session_get_peer_setting, 1997 .esf_get_peer_option = lsquic_enc_session_get_peer_option, 1998 .esf_create_client = lsquic_enc_session_create_client, 1999 .esf_generate_cid = lsquic_generate_cid, 2000 .esf_gen_chlo = lsquic_enc_session_gen_chlo, 2001 .esf_handle_chlo_reply = lsquic_enc_session_handle_chlo_reply, 2002 .esf_mem_used = lsquic_enc_session_mem_used, 2003 .esf_verify_reset_token = lsquic_enc_session_verify_reset_token, 2004 .esf_did_zero_rtt_succeed = lsquic_enc_session_did_zero_rtt_succeed, 2005 .esf_is_zero_rtt_enabled = lsquic_enc_session_is_zero_rtt_enabled, 2006 .esf_get_cert_item = lsquic_enc_session_get_cert_item, 2007 .esf_get_server_cert_chain = lsquic_enc_session_get_server_cert_chain, 2008 .esf_get_zero_rtt = lsquic_enc_session_get_zero_rtt, 2009}; 2010 2011 2012const char *const lsquic_enclev2str[] = 2013{ 2014 [ENC_LEV_UNSET] = "unset", 2015 [ENC_LEV_CLEAR] = "clear", 2016 [ENC_LEV_INIT] = "initial", 2017 [ENC_LEV_FORW] = "forw-secure", 2018}; 2019 2020 2021enum lsquic_version 2022lsquic_zero_rtt_version (const unsigned char *buf, size_t bufsz) 2023{ 2024 lsquic_ver_tag_t tag; 2025 2026 if (bufsz >= sizeof(tag)) 2027 { 2028 memcpy(&tag, buf, sizeof(tag)); 2029 return lsquic_tag2ver(tag); 2030 } 2031 else 2032 return -1; 2033} 2034