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