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