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