lsquic_handshake.h revision 50aadb33
1/* Copyright (c) 2017 LiteSpeed Technologies Inc. See LICENSE. */ 2#ifndef LSQUIC_HANDSHAKE_H 3#define LSQUIC_HANDSHAKE_H 4 5#include <stdint.h> 6#include <openssl/base.h> 7#include <openssl/aead.h> 8 9#include <time.h> 10#include "lsquic_str.h" 11 12struct lsquic_engine_public; 13struct sockaddr; 14 15#include "lsquic_qtags.h" 16 17#define STK_LENGTH 60 18#define SNO_LENGTH 56 19#define SCID_LENGTH 16 20#define DNONC_LENGTH 32 21#define aes128_key_len 16 22#define aes128_iv_len 4 23 24/* client side, certs and hashs 25 */ 26typedef struct cert_hash_item_st 27{ 28 struct lsquic_str* domain; /*with port, such as "xyz.com:8088" as the key */ 29 struct lsquic_str* crts; 30 struct lsquic_str* hashs; 31 int count; 32} cert_hash_item_t; 33 34enum handshake_error /* TODO: rename this enum */ 35{ 36 DATA_NOT_ENOUGH = -2, 37 DATA_FORMAT_ERROR = -1, 38 HS_ERROR = -1, 39 DATA_NO_ERROR = 0, 40 HS_SHLO = 0, 41 HS_1RTT = 1, 42 HS_2RTT = 2, 43}; 44 45enum handshake_state 46{ 47 HSK_CHLO_REJ = 0, 48 HSK_SHLO, 49 HSK_COMPLETED, 50 N_HSK_STATES 51}; 52 53typedef struct tag_value_st 54{ 55 uint32_t tag; 56 const char * value; 57 int len; 58} tag_value_t; 59 60typedef struct hs_ctx_st 61{ 62 enum { 63 HSET_TCID = (1 << 0), /* tcid is set */ 64 HSET_SMHL = (1 << 1), /* smhl is set */ 65 HSET_SCID = (1 << 2), 66 } set; 67 enum { 68 HOPT_NSTP = (1 << 0), /* NSTP option present in COPT */ 69 HOPT_SREJ = (1 << 1), /* SREJ option present in COPT */ 70 } opts; 71 uint32_t pdmd; 72 uint32_t aead; 73 uint32_t kexs; 74 75 uint32_t mids; 76 uint32_t scls; 77 uint32_t cfcw; 78 uint32_t sfcw; 79 uint32_t srbf; 80 uint32_t icsl; 81 82 uint32_t irtt; 83 uint64_t rcid; 84 uint32_t tcid; 85 uint32_t smhl; 86 uint64_t ctim; /* any usage? */ 87 uint64_t sttl; 88 unsigned char scid[SCID_LENGTH]; 89 //unsigned char chlo_hash[32]; //SHA256 HASH of CHLO 90 unsigned char nonc[DNONC_LENGTH]; /* 4 tm, 8 orbit ---> REJ, 20 rand */ 91 unsigned char pubs[32]; 92 93 uint32_t rrej; 94 struct lsquic_str ccs; 95 struct lsquic_str sni; /* 0 rtt */ 96 struct lsquic_str ccrt; 97 struct lsquic_str stk; 98 struct lsquic_str sno; 99 struct lsquic_str prof; 100 101 struct lsquic_str csct; 102 struct lsquic_str crt; /* compressed certs buffer */ 103} hs_ctx_t; 104 105/* client side need to store 0rtt info per STK */ 106typedef struct lsquic_session_cache_info_st 107{ 108 unsigned char sscid[SCID_LENGTH]; 109 unsigned char spubs[32]; /* server pub key for next time 0rtt */ 110 uint32_t ver; /* one VERSION */ 111 uint32_t aead; 112 uint32_t kexs; 113 uint32_t pdmd; 114 uint64_t orbt; 115 uint64_t expy; 116 int scfg_flag; /* 0, no-init, 1, no parse, 2, parsed */ 117 struct lsquic_str sstk; 118 struct lsquic_str scfg; 119 struct lsquic_str sni_key; /* This is only used as key */ 120 121} lsquic_session_cache_info_t; 122 123#ifndef LSQUIC_KEEP_ENC_SESS_HISTORY 124# ifndef NDEBUG 125# define LSQUIC_KEEP_ENC_SESS_HISTORY 1 126# else 127# define LSQUIC_KEEP_ENC_SESS_HISTORY 0 128# endif 129#endif 130 131#if LSQUIC_KEEP_ENC_SESS_HISTORY 132 133#define ESHIST_BITS 7 134#define ESHIST_MASK ((1 << ESHIST_BITS) - 1) 135#define ESHIST_STR_SIZE ((1 << ESHIST_BITS) + 1) 136typedef unsigned char eshist_idx_t; 137 138enum enc_sess_history_event 139{ 140 ESHE_EMPTY = '\0', 141 ESHE_SET_SNI = 'I', 142 ESHE_SET_SNO = 'O', 143 ESHE_SET_STK = 'K', 144 ESHE_SET_SCID = 'D', 145 ESHE_SET_PROF = 'P', 146}; 147 148#endif 149 150typedef struct lsquic_enc_session 151{ 152 enum handshake_state hsk_state; 153 154 uint8_t have_key; /* 0, no 1, I, 2, D, 3, F */ 155 uint8_t peer_have_final_key; 156 uint8_t server_start_use_final_key; 157 158 lsquic_cid_t cid; 159 unsigned char priv_key[32]; 160 EVP_AEAD_CTX *enc_ctx_i; 161 EVP_AEAD_CTX *dec_ctx_i; 162 163 /* Have to save the initial key for diversification need */ 164 unsigned char enc_key_i[aes128_key_len]; 165 unsigned char dec_key_i[aes128_key_len]; 166 unsigned char enc_key_nonce_i[aes128_iv_len]; 167 unsigned char dec_key_nonce_i[aes128_iv_len]; 168 169 EVP_AEAD_CTX *enc_ctx_f; 170 EVP_AEAD_CTX *dec_ctx_f; 171 unsigned char enc_key_nonce_f[aes128_iv_len]; 172 unsigned char dec_key_nonce_f[aes128_iv_len]; 173 174 hs_ctx_t hs_ctx; 175 lsquic_session_cache_info_t *info; 176 SSL_CTX * ssl_ctx; 177 const struct lsquic_engine_public *enpub; 178 struct lsquic_str * cert_ptr; /* pointer to the leaf cert of the server, not real copy */ 179 struct lsquic_str chlo; /* real copy of CHLO message */ 180 struct lsquic_str sstk; 181 struct lsquic_str ssno; 182 183#if LSQUIC_KEEP_ENC_SESS_HISTORY 184 eshist_idx_t es_hist_idx; 185 unsigned char es_hist_buf[1 << ESHIST_BITS]; 186#endif 187} lsquic_enc_session_t; 188 189#if LSQUIC_KEEP_ENC_SESS_HISTORY 190void 191lsquic_get_enc_hist (const lsquic_enc_session_t *, char buf[ESHIST_STR_SIZE]); 192#endif 193 194int handshake_init(int flags); 195void handshake_cleanup(); 196 197lsquic_enc_session_t * 198new_enc_session_c(const char *domain, lsquic_cid_t cid, 199 const struct lsquic_engine_public *); 200 201void free_enc_session(lsquic_enc_session_t *enc_session); 202void free_info(lsquic_session_cache_info_t *info); 203 204lsquic_cid_t generate_cid(void); 205 206/* save to hash table */ 207lsquic_session_cache_info_t *retrieve_session_info_entry(const char *key); 208void remove_expire_session_info_entry(); 209void remove_session_info_entry(struct lsquic_str *key); 210 211cert_hash_item_t *make_cert_hash_item(struct lsquic_str *domain, struct lsquic_str **certs, int count); 212void c_free_cert_hash_item(cert_hash_item_t *item); 213cert_hash_item_t* c_find_certs(struct lsquic_str *domain); 214int c_insert_certs(cert_hash_item_t *item); 215 216/* -1 error, 0, OK, response in `buf' */ 217int gen_chlo(lsquic_enc_session_t *enc_session, enum lsquic_version, 218 uint8_t *buf, size_t *len); 219int handle_chlo_reply(lsquic_enc_session_t *enc_session, const uint8_t *data, 220 int len); 221 222int is_hs_done(lsquic_enc_session_t *enc_session); 223 224/** 225 * The belows are global functions 226 */ 227 228int lsquic_enc(lsquic_enc_session_t *enc_session, enum lsquic_version, 229 uint8_t path_id, uint64_t pack_num, 230 const unsigned char *header, size_t header_len, 231 const unsigned char *data, size_t data_len, 232 unsigned char *buf_out, size_t max_out_len, size_t *out_len, 233 int is_hello); 234 235int lsquic_dec(lsquic_enc_session_t *enc_session, enum lsquic_version, 236 uint8_t path_id, uint64_t pack_num, 237 unsigned char *buf, size_t *header_len, size_t data_len, 238 unsigned char *diversification_nonce, 239 unsigned char *buf_out, size_t max_out_len, size_t *out_len); 240 241int 242get_peer_setting (const lsquic_enc_session_t *, uint32_t tag, uint32_t *val); 243 244int 245get_peer_option (const lsquic_enc_session_t *enc_session, uint32_t tag); 246 247#ifdef NDEBUG 248#define lsquic_enc_session_have_key_gt_one(e) ((e) && (e)->have_key > 1) 249#else 250int 251lsquic_enc_session_have_key_gt_one (const lsquic_enc_session_t *enc_session); 252#endif 253 254#endif 255