From 931c5e39e8f8bc648f635d507a03acd1483594dd Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Tue, 26 May 2026 21:50:13 +0800 Subject: [PATCH] Update TLS 1.3 --- include/gmssl/tls.h | 67 +++--- src/tls.c | 137 ++--------- src/tls13.c | 262 +++++---------------- src/tls_cookie.c | 5 +- src/tls_ext.c | 4 +- src/tls_ocsp.c | 6 +- src/tls_psk.c | 61 +---- src/tls_sct.c | 25 +- src/tls_sni.c | 59 +++-- tools/tls13_client.c | 540 +++++++++++++++++++++++-------------------- tools/tls13_help.h | 202 ++++++++++++++++ tools/tls13_server.c | 508 +++++++++++++--------------------------- 12 files changed, 796 insertions(+), 1080 deletions(-) create mode 100644 tools/tls13_help.h diff --git a/include/gmssl/tls.h b/include/gmssl/tls.h index 5428d1ec..1f652963 100644 --- a/include/gmssl/tls.h +++ b/include/gmssl/tls.h @@ -372,17 +372,17 @@ typedef enum { TLS_alert_protocol_version = 70, TLS_alert_insufficient_security = 71, TLS_alert_internal_error = 80, - TLS_alert_inappropriate_fallback = 86, + TLS_alert_inappropriate_fallback = 86, TLS_alert_user_canceled = 90, TLS_alert_no_renegotiation = 100, TLS_alert_missing_extension = 109, TLS_alert_unsupported_extension = 110, - TLS_alert_certificate_unobtainable = 111, - TLS_alert_unrecognized_name = 112, - TLS_alert_bad_certificate_status_response = 113, - TLS_alert_unknown_psk_identity = 115, - TLS_alert_certificate_required = 116, - TLS_alert_no_application_protocol = 120, + TLS_alert_certificate_unobtainable = 111, + TLS_alert_unrecognized_name = 112, + TLS_alert_bad_certificate_status_response = 113, + TLS_alert_unknown_psk_identity = 115, + TLS_alert_certificate_required = 116, + TLS_alert_no_application_protocol = 120, TLS_alert_unsupported_site2site = 200, TLS_alert_no_area = 201, TLS_alert_unsupported_areatype = 202, @@ -794,7 +794,6 @@ typedef struct { // CertificateRequest int certificate_request; int client_certificate_optional; // if empty client Certificate is allowed - // TODO: 还没有设置的函数 // NewSessionTicket int new_session_ticket; @@ -1227,9 +1226,13 @@ int tls_recv_record(TLS_CONNECT *conn); // ClientHello/ServerHello // set/get functions use tls_ functions + int tls13_client_hello_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen); int tls13_server_hello_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen); +int tls13_ctx_set_client_hello_key_exchanges_cnt(TLS_CTX *ctx, size_t cnt); + + // HelloRetryRequest @@ -1289,6 +1292,8 @@ int tls13_record_get_handshake_certificate_request(const uint8_t *record, const uint8_t **exts, size_t *exts_len); int tls13_certificate_request_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen); +int tls13_ctx_enable_client_certificate_optional(TLS_CTX *ctx, int enable); + // EndOfEarlyData @@ -1338,11 +1343,9 @@ int tls13_record_get_handshake_new_session_ticket(uint8_t *record, int tls13_new_session_ticket_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen); +// ChangeCipherSpec - - - - +int tls13_ctx_enable_change_cipher_spec(TLS_CTX *ctx, int enable); @@ -1708,10 +1711,13 @@ int tls_ctx_enable_certificate_request(TLS_CTX *ctx, int enable); -// Extensions + +// Extensions + + // 0. server_name (SNI): in ClientHello, EncryptedExtensions int tls_set_server_name(TLS_CONNECT *conn, const uint8_t *host_name, size_t host_name_len); // client only int tls_server_name_ext_to_bytes(const uint8_t *host_name, size_t host_name_len, uint8_t **out, size_t *outlen); @@ -1720,13 +1726,6 @@ int tls_server_name_from_bytes(const uint8_t **host_name, size_t *host_name_len, int tls_server_name_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen); - - - - - - - // 5. status_request (OCSP stapling) enum { TLS_certificate_status_type_ocsp = 1, @@ -1780,10 +1779,6 @@ int tls_server_status_request_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen); - - - - // 10. supported_groups int tls_supported_groups_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen); int tls_supported_groups_ext_to_bytes(const int *groups, size_t groups_cnt, @@ -1796,18 +1791,17 @@ int tls_process_supported_groups(const uint8_t *ext_data, size_t ext_datalen, const int *local_groups, size_t local_groups_cnt, int *common_groups, size_t *common_groups_cnt, size_t max_cnt); + // 11. ec_point_format int tls_ec_point_formats_ext_to_bytes(const int *formats, size_t formats_cnt, uint8_t **out, size_t *outlen); -int tls_ec_point_formats_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen); int tls_process_client_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen, uint8_t **out, size_t *outlen); int tls_process_server_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen); +int tls_ec_point_formats_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen); // 13. signature_algorithms - -int tls_enable_signature_algorithms_cert(TLS_CONNECT *conn); - +int tls_enable_signature_algorithms_cert(TLS_CONNECT *conn, int enable); int tls_signature_algorithms_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen); int tls_signature_algorithms_ext_to_bytes_ex(int ext_type, const int *algs, size_t algs_cnt, uint8_t **out, size_t *outlen); @@ -1821,9 +1815,8 @@ int tls_process_signature_algorithms(const uint8_t *ext_data, size_t ext_datalen // 18. signed_certificate_timestamp (certificate transparency, CT) // signed_certificate_timestamp response is set by tls_ctx_add_certificate_list_and_key() -int tls_ctx_enable_signed_certificate_timestamp(TLS_CTX *ctx); // 这里enable的是什么?是否请求吗? -int tls_enable_signed_certificate_timestamp(TLS_CONNECT *conn); - +int tls_ctx_enable_signed_certificate_timestamp(TLS_CTX *ctx, int enable); // 这里enable的是什么?是否请求吗? +int tls_enable_signed_certificate_timestamp(TLS_CONNECT *conn, int enable); // 客户端需要一组SCT服务器的公钥列表才能够去验证SCT,我们假定这个公钥列表在CTX中 @@ -1844,11 +1837,6 @@ int tls_signed_certificate_timestamp_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen); - - - - - // 41. pre_shared_key int tls13_psk_identity_to_bytes(const uint8_t *ticket, size_t ticketlen, uint32_t obfuscated_ticket_age, uint8_t **out, size_t *outlen); @@ -1891,7 +1879,7 @@ int tls13_early_data_ext_to_bytes(size_t max_early_data_size, uint8_t **out, siz int tls13_early_data_from_bytes(size_t *max_early_data_size, const uint8_t *ext_data, size_t ext_datalen); int tls13_early_data_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen); int tls13_set_early_data(TLS_CONNECT *conn, const uint8_t *data, size_t datalen); -int tls13_enable_early_data(TLS_CONNECT *conn, int enable); +int tls13_ctx_enable_early_data(TLS_CTX *ctx, int enable); int tls13_ctx_set_max_early_data_size(TLS_CTX *ctx, size_t max_early_data_size); int tls13_set_max_early_data_size(TLS_CONNECT *conn, size_t max_early_data_size); @@ -1957,19 +1945,16 @@ int tls13_certificate_authorities_print(FILE *fp, int fmt, int ind, // 48. oid_filters - - // 49. post_handshake_auth int tls13_enable_post_handshake_auth(TLS_CONNECT *conn); - // 50. signature_algorithms_cert int tls13_signature_algorithms_cert_ext_to_bytes(const int *algs, size_t algs_cnt, uint8_t **out, size_t *outlen); int tls13_signature_algorithms_cert_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen); -// 用这个处理,tls_process_signature_algorithms +#define tls13_process_signature_algorithms_cert(ext_data, ext_datalen, in_sigs, in_sigs_cnt, out_sigs, out_sigs_cnt, max_cnt) // 51. key_share diff --git a/src/tls.c b/src/tls.c index 5b37981e..7c75d4c4 100644 --- a/src/tls.c +++ b/src/tls.c @@ -84,13 +84,6 @@ void tls_array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size *outlen += datalen; } -/* -这几个函数要区分data = NULL, datalen = 0 和 data = NULL, datalen != 0的情况 -前者意味着数据为空,因此输出的就是一个长度 -后者意味着数据不为空,只是我们不想输出数据,只输出头部的长度,并且更新整个的输出长度。 这种情况应该避免! - -*/ - void tls_uint8array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen) { tls_uint8_to_bytes((uint8_t)datalen, out, outlen); @@ -302,7 +295,7 @@ int tls_cbc_encrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *enc_key, return -1; } if (inlen > (1 << 14)) { - error_print_msg("invalid tls record data length %zu\n", inlen); + error_print(); return -1; } if ((((size_t)header[3]) << 8) + header[4] != inlen) { @@ -342,8 +335,6 @@ int tls_cbc_encrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *enc_key, return 1; } - -// 这个函数应该把所有的输入的dgst都打印出来!这样就可以容易判断出到底是哪个输入错了 int tls_cbc_decrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *dec_key, const uint8_t seq_num[8], const uint8_t enced_header[5], const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) @@ -886,9 +877,7 @@ int tls_record_set_handshake_server_hello(uint8_t *record, size_t *recordlen, return -1; } if (session_id) { - if (session_id_len == 0 - || session_id_len < TLS_MIN_SESSION_ID_SIZE - || session_id_len > TLS_MAX_SESSION_ID_SIZE) { + if (session_id_len > TLS_MAX_SESSION_ID_SIZE) { error_print(); return -1; } @@ -1337,7 +1326,6 @@ int tls_record_set_handshake_finished(uint8_t *record, size_t *recordlen, return 1; } -// 这个应该改为只支持TLS 1.2的12字节长度判断 int tls_record_get_handshake_finished(const uint8_t *record, const uint8_t **verify_data, size_t *verify_data_len) { int type; @@ -1358,7 +1346,7 @@ int tls_record_get_handshake_finished(const uint8_t *record, const uint8_t **ver error_print(); return -1; } - if (*verify_data_len != 12 && *verify_data_len != 32) { + if (*verify_data_len != 12) { error_print(); return -1; } @@ -1500,13 +1488,6 @@ int tls_type_is_in_list(int type, const int *list, size_t list_count) - - - - - - - static const int tlcp_ciphers[] = { TLS_cipher_ecc_sm4_cbc_sm3, TLS_cipher_ecc_sm4_gcm_sm3, @@ -1682,7 +1663,6 @@ int tls_seq_num_incr(uint8_t seq_num[8]) seq_num[i]++; if (seq_num[i]) break; } - // FIXME: check overflow return 1; } @@ -1965,8 +1945,6 @@ int tls_shutdown(TLS_CONNECT *conn) return 1; } -// ca_names中存储的是什么结构的数据? -// 看来这个函数是有问题的,这里面存储的应该是GeneralNames类型的数据,subject是什么结构? int tls_authorities_from_certs(uint8_t *names, size_t *nameslen, size_t maxlen, const uint8_t *certs, size_t certslen) { const uint8_t *cert; @@ -2004,9 +1982,6 @@ int tls_authorities_from_certs(uint8_t *names, size_t *nameslen, size_t maxlen, return 1; } -// 这个函数在语义上有问题: -// 首先我们判断的是证书链,因此函数名上应该是一个cert_chain -// 调用这个函数传进来的就不是一个证书链 int tls_authorities_issued_certificate(const uint8_t *ca_names, size_t ca_names_len, const uint8_t *certs, size_t certslen) { const uint8_t *cert; @@ -2188,39 +2163,6 @@ int tls_cipher_suites_select(const uint8_t *client_ciphers, size_t client_cipher return 0; } -void tls_ctx_cleanup(TLS_CTX *ctx) -{ - if (ctx) { - gmssl_secure_clear(&ctx->signkey, sizeof(SM2_KEY)); - gmssl_secure_clear(&ctx->kenckey, sizeof(SM2_KEY)); - if (ctx->certs) free(ctx->certs); - if (ctx->cacerts) free(ctx->cacerts); - memset(ctx, 0, sizeof(TLS_CTX)); - } -} - -int tls_ctx_print(FILE *fp, int fmt, int ind, const char *label, const TLS_CTX *ctx) -{ - - - return 0; -} - - - - - - - - - - - - - - - - int tls_ctx_init(TLS_CTX *ctx, int protocol, int is_client) @@ -2265,12 +2207,20 @@ int tls_ctx_init(TLS_CTX *ctx, int protocol, int is_client) ctx->key_exchanges_cnt = TLS_DEFAULT_KEY_EXCHANGES_CNT; - - ctx->change_cipher_spec = 1; - return 1; } +void tls_ctx_cleanup(TLS_CTX *ctx) +{ + if (ctx) { + gmssl_secure_clear(&ctx->signkey, sizeof(SM2_KEY)); + gmssl_secure_clear(&ctx->kenckey, sizeof(SM2_KEY)); + if (ctx->certs) free(ctx->certs); + if (ctx->cacerts) free(ctx->cacerts); + memset(ctx, 0, sizeof(TLS_CTX)); + } +} + int tls_ctx_set_supported_versions(TLS_CTX *ctx, const int *versions, size_t versions_cnt) { size_t i; @@ -2326,24 +2276,6 @@ int tls_ctx_set_cipher_suites(TLS_CTX *ctx, const int *cipher_suites, size_t cip return 1; } -/* -int tls_ctx_set_key_exchange_modes(TLS_CTX *ctx, int modes) -{ - if (!ctx) { - error_print(); - return -1; - } - if (modes & ~(TLS_KE_CERT_DHE|TLS_KE_PSK_DHE|TLS_KE_PSK)) { - error_print(); - return -1; - } - - ctx->key_exchange_modes = modes; - - return 1; -} -*/ - // 这个函数不是很好,直接提供的是一个文件名 int tls_ctx_set_ca_certificates(TLS_CTX *ctx, const char *cacertsfile, int depth) { @@ -2383,7 +2315,6 @@ int tls_ctx_set_ca_certificates(TLS_CTX *ctx, const char *cacertsfile, int depth return 1; } - int tls_ctx_enable_certificate_request(TLS_CTX *ctx, int enable) { if (!ctx) { @@ -2400,7 +2331,6 @@ int tls_ctx_enable_certificate_request(TLS_CTX *ctx, int enable) return 1; } - int tls_ctx_add_certificate_list_and_key(TLS_CTX *ctx, const char *chainfile, const uint8_t *entity_status_request_ocsp_response, size_t entity_status_request_ocsp_response_len, // optional const uint8_t *entity_signed_certificate_timestamp_list, size_t entity_signed_certificate_timestamp_list_len, // optional @@ -2515,7 +2445,6 @@ int tls_ctx_add_certificate_list_and_key(TLS_CTX *ctx, const char *chainfile, return 1; } - int tls_ctx_add_certificate_chain_and_key(TLS_CTX *ctx, const char *chainfile, const char *keyfile, const char *keypass) { @@ -2709,7 +2638,6 @@ int tls_ctx_set_supported_groups(TLS_CTX *ctx, const int *groups, size_t groups_ - int tls_ctx_set_signature_algorithms(TLS_CTX *ctx, const int *sig_algs, size_t sig_algs_cnt) { size_t i; @@ -2750,21 +2678,6 @@ int tls_ctx_set_key_update_seq_num_limit(TLS_CTX *ctx, size_t max_seq_num) } -int tls13_ctx_set_client_hello_key_exchanges_cnt(TLS_CTX *ctx, size_t cnt) -{ - if (!ctx) { - error_print(); - return -1; - } - if (cnt > sizeof(((TLS_CONNECT *)NULL)->key_exchanges)/sizeof(((TLS_CONNECT *)NULL)->key_exchanges[0])) { - error_print(); - return -1; - } - - ctx->key_exchanges_cnt = cnt; - - return 1; -} @@ -2773,13 +2686,11 @@ int tls13_ctx_set_client_hello_key_exchanges_cnt(TLS_CTX *ctx, size_t cnt) int tls_init(TLS_CONNECT *conn, TLS_CTX *ctx) { size_t i; + + memset(conn, 0, sizeof(*conn)); - - - //conn->is_client = ctx->is_client; - conn->protocol = ctx->protocol; /* @@ -2835,7 +2746,6 @@ int tls_init(TLS_CONNECT *conn, TLS_CTX *ctx) fprintf(stderr, "%s %d: conn->key_exchange_modes = %d\n", __FILE__, __LINE__, conn->key_exchange_modes); - if (conn->key_exchange_modes & (TLS_KE_CERT_DHE|TLS_KE_PSK_DHE)) { conn->key_share = 1; } @@ -2846,7 +2756,6 @@ int tls_init(TLS_CONNECT *conn, TLS_CTX *ctx) conn->early_data = ctx->early_data; conn->max_early_data_size = ctx->max_early_data_size; - // pre_shared_key if (conn->key_exchange_modes & (TLS_KE_PSK_DHE|TLS_KE_PSK)) { conn->pre_shared_key = 1; @@ -2861,18 +2770,6 @@ void tls_cleanup(TLS_CONNECT *conn) gmssl_secure_clear(conn, sizeof(TLS_CONNECT)); } -/* -int tls_set_hostname(TLS_CONNECT *conn, const char *hostname) -{ - if (strlen(hostname) > 255) { - error_print(); - return -1; - } - conn->hostname = hostname; - return 1; -} -*/ - int tls_set_socket(TLS_CONNECT *conn, tls_socket_t sock) { #ifdef WIN32 @@ -2964,7 +2861,6 @@ int tls_uint16array_from_file(uint8_t *arr, size_t *arrlen, size_t maxlen, FILE return 1; } - int tls_key_exchange_modes_print(FILE *fp, int fmt, int ind, const char *label, int modes) { int first = 1; @@ -2990,4 +2886,3 @@ int tls_key_exchange_modes_print(FILE *fp, int fmt, int ind, const char *label, return 1; } - diff --git a/src/tls13.c b/src/tls13.c index 49a3547a..383f541c 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -1559,7 +1559,6 @@ int tls13_client_supported_versions_print(FILE *fp, int fmt, int ind, return 1; } - /* struct { ProtocolVersion selected_version; @@ -2091,14 +2090,6 @@ int tls13_key_share_hello_retry_request_print(FILE *fp, int fmt, int ind, } -static const unsigned char TLS13_HELLO_RETRY_REQUEST_RANDOM[32] = { - 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, - 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91, - 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, - 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C -}; - - // Handshakes // ClientHello // ServerHello @@ -2128,6 +2119,21 @@ opaque Random[32]; uint8 CipherSuite[2]; */ +int tls13_ctx_set_client_hello_key_exchanges_cnt(TLS_CTX *ctx, size_t cnt) +{ + if (!ctx) { + error_print(); + return -1; + } + if (cnt > sizeof(((TLS_CONNECT *)NULL)->key_exchanges)/sizeof(((TLS_CONNECT *)NULL)->key_exchanges[0])) { + error_print(); + return -1; + } + + ctx->key_exchanges_cnt = cnt; + return 1; +} + int tls13_client_hello_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen) { uint16_t protocol; @@ -2276,6 +2282,14 @@ int tls13_client_hello_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_ return 1; } +// ServerHello.random if HelloRetryReqeust +static const unsigned char TLS13_HELLO_RETRY_REQUEST_RANDOM[32] = { + 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, + 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91, + 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, + 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C +}; + /* ServerHello @@ -2973,7 +2987,7 @@ int tls13_record_get_handshake_certificate(const uint8_t *record, return -1; } - // 客户端的证书链中的cert_list 可能为空 + // client Certificate.certificate_list might be empty/null if (!cert_list) { *cert_chain_len = 0; *entity_status_request_ocsp_response = NULL; @@ -3010,7 +3024,6 @@ int tls13_record_get_handshake_certificate(const uint8_t *record, } // 这里的解析可能是有问题的 - x509_cert_to_der(cert, certlen, &cert_chain, cert_chain_len); } @@ -3107,9 +3120,6 @@ struct { opaque certificate_request_context<0..2^8-1>; Extension extensions<2..2^16-1>; } CertificateRequest; - -extensiosns: - signature_algorithms MUST be specified 这个应该放在代码中 */ int tls13_record_set_handshake_certificate_request(uint8_t *record, size_t *recordlen, const uint8_t *request_context, size_t request_context_len, @@ -3123,6 +3133,12 @@ int tls13_record_set_handshake_certificate_request(uint8_t *record, size_t *reco error_print(); return -1; } + if (!exts || !extslen) { + // signature_algorithms extension must exist + error_print(); + return -1; + } + data = tls_handshake_data(tls_record_data(record)); tls_uint8array_to_bytes(request_context, request_context_len, &data, &datalen); tls_uint16array_to_bytes(exts, extslen, &data, &datalen); @@ -3152,6 +3168,11 @@ int tls13_record_get_handshake_certificate_request(const uint8_t *record, error_print(); return -1; } + if (!exts) { + // signature_algorithms extension must exist + error_print(); + return -1; + } return 1; } @@ -3195,13 +3216,13 @@ int tls13_certificate_request_print(FILE *fp, int fmt, int ind, const uint8_t *d tls13_certificate_authorities_print(fp, fmt, ind, ext_data, ext_datalen); break; case TLS_extension_status_request: - //tls13_status_request_print(fp, fmt, ind, ext_data, ext_datalen); + //tls13_status_request_print(fp, fmt, ind, ext_data, ext_datalen); break; case TLS_extension_signature_algorithms_cert: tls_signature_algorithms_print(fp, fmt, ind, ext_data, ext_datalen); break; case TLS_extension_client_certificate_type: - //tls13_client_certificate_type_print(fp, fmt, ind, ext_data, ext_datalen); + //tls13_client_certificate_type_print(fp, fmt, ind, ext_data, ext_datalen); break; default: error_print(); @@ -3215,6 +3236,16 @@ int tls13_certificate_request_print(FILE *fp, int fmt, int ind, const uint8_t *d return 1; } +int tls13_ctx_enable_client_certificate_optional(TLS_CTX *ctx, int enable) +{ + if (!ctx) { + error_print(); + return -1; + } + ctx->client_certificate_optional = enable ? 1 : 0; + return 1; +} + /* CertificateVerify @@ -3306,7 +3337,6 @@ struct { } Finished; */ - int tls13_record_set_handshake_finished(uint8_t *record, size_t *recordlen, const uint8_t *verify_data, size_t verify_data_len) { @@ -3367,13 +3397,13 @@ enum { */ int tls13_record_set_handshake_key_update(uint8_t *record, size_t *recordlen, - int request_update) + int req_update) { int type = TLS_handshake_key_update; - uint8_t data[1]; // 这个值不太好 + uint8_t request_update; - data[0] = request_update ? 1 : 0; - if (tls_record_set_handshake(record, recordlen, type, data, sizeof(data)) != 1) { + request_update = req_update ? 1 : 0; + if (tls_record_set_handshake(record, recordlen, type, &request_update, sizeof(request_update)) != 1) { error_print(); return -1; } @@ -3433,6 +3463,18 @@ int tls13_key_update_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t return 1; } +// ChangeCipherSpec + +int tls13_ctx_enable_change_cipher_spec(TLS_CTX *ctx, int enable) +{ + if (!ctx) { + error_print(); + return -1; + } + ctx->change_cipher_spec = enable ? 1 : 0; + return 1; +} + int tls13_handshake_print(FILE *fp, int fmt, int ind, const uint8_t *handshake, size_t handshake_len) @@ -3521,12 +3563,7 @@ int tls13_record_print(FILE *fp, int format, int indent, const uint8_t *record, return -1; } - // 最高字节设置后强制打印记录原始数据 - if (format >> 24) { - format_bytes(fp, format, indent, "Data", data, datalen); - fprintf(fp, "\n"); - return 1; - } + //format_bytes(fp, format, indent, "RecordRawData", data, datalen); switch (record[0]) { case TLS_record_handshake: @@ -3568,13 +3605,6 @@ int tls13_record_print(FILE *fp, int format, int indent, const uint8_t *record, - - - - - - - /* Client Server @@ -3623,9 +3653,6 @@ Auth | {CertificateVerify*} - - - int tls13_init(TLS_CONNECT *conn, TLS_CTX *ctx) { size_t i; @@ -3723,29 +3750,6 @@ int tls13_init(TLS_CONNECT *conn, TLS_CTX *ctx) return 1; } - -/* -ClientHello中的很多扩展是和证书有关的 -如果客户端在ClientHello中已经明确不支持证书认证(没有提供group + sig_alg的组合) -那么就不应该在ClientHello中包含这些扩展 -*/ - - - -/* -1. 客户端发送 ClientHello,包含 early_data 扩展 -2. 客户端设置 cipher_suite 和 early_secret -3. 客户端发送 {EarlyData} -4. 客户端发送 {EndOfEarlyData} -5. 客户端接收 ServerHello -6. 客户端设置 handshake_secret -7. 客户端接收 {EncryptedExtensions} - - - -*/ - - int tls13_send_client_hello(TLS_CONNECT *conn) { int ret; @@ -6106,9 +6110,6 @@ int tls13_recv_client_certificate_verify(TLS_CONNECT *conn) return 1; } - -// ServerFinished消息之前有可能是什么消息? - int tls13_recv_server_finished(TLS_CONNECT *conn) { int ret; @@ -6181,8 +6182,6 @@ int tls13_recv_server_finished(TLS_CONNECT *conn) return 1; } -// 需要验证,当cipher_suite为AES,服务器证书为P-256,客户端证书为SM2的情况 - int tls13_send_client_certificate(TLS_CONNECT *conn) { int ret; @@ -6467,7 +6466,6 @@ int tls13_recv_client_hello(TLS_CONNECT *conn) tls_client_verify_init(&conn->client_verify_ctx); */ - tls_trace("recv ClientHello\n"); if ((ret = tls_recv_record(conn)) != 1) { @@ -8082,7 +8080,6 @@ int tls13_send_server_finished(TLS_CONNECT *conn) tls_trace("send server {Finished}\n"); - if (conn->recordlen == 0) { uint8_t verify_data[64]; size_t verify_data_len; @@ -8116,38 +8113,9 @@ int tls13_send_server_finished(TLS_CONNECT *conn) } tls_seq_num_incr(conn->server_seq_num); - // 必须在这里生成client_application_traffic_secret,否则dgst_ctx就变了 - // 但是必须在ClientFinished之后再更新密钥 - // 因此application_secrets是可以同时生成的 - - tls13_generate_application_secrets(conn); - // Generate client_application_traffic_secret - ///* 11 */ tls13_derive_secret(conn->master_secret, "c ap traffic", &conn->dgst_ctx, conn->client_application_traffic_secret); - // generate server_application_traffic_secret - ///* 12 */ tls13_derive_secret(conn->master_secret, "s ap traffic", &conn->dgst_ctx, conn->server_application_traffic_secret); - - - // 这里只生成服务器端的密钥 - tls13_generate_server_application_keys(conn); - - // update server_write_key, server_write_iv, reset server_seq_num - /* - tls13_hkdf_expand_label(conn->digest, conn->server_application_traffic_secret, "key", NULL, 0, 16, server_write_key); - block_cipher_set_encrypt_key(&conn->server_write_key, conn->cipher, server_write_key); - tls13_hkdf_expand_label(conn->digest, conn->server_application_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); - tls_seq_num_reset(conn->server_seq_num); - - format_print(stderr, 0, 0, "update server secrets\n"); - format_bytes(stderr, 0, 4, "server_application_traffic_secret", conn->server_application_traffic_secret, 32); - format_bytes(stderr, 0, 4, "server_write_key", server_write_key, 16); - format_bytes(stderr, 0, 4, "server_write_iv", conn->server_write_iv, 12); - format_bytes(stderr, 0, 4, "server_seq_num", conn->server_seq_num, 8); - format_print(stderr, 0, 0, "\n"); - */ - } if ((ret = tls_send_record(conn)) != 1) { @@ -8374,22 +8342,8 @@ int tls13_recv_client_finished(TLS_CONNECT *conn) return -1; } - tls13_generate_client_application_keys(conn); - /* - // update client_write_key, client_write_iv, reset client_seq_num - tls13_hkdf_expand_label(conn->digest, conn->client_application_traffic_secret, "key", NULL, 0, 16, client_write_key); - block_cipher_set_encrypt_key(&conn->client_write_key, conn->cipher, client_write_key); - tls13_hkdf_expand_label(conn->digest, conn->client_application_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); - tls_seq_num_reset(conn->client_seq_num); - - format_print(stderr, 0, 0, "update client secrets\n"); - format_bytes(stderr, 0, 4, "client_write_key", client_write_key, 16); - format_bytes(stderr, 0, 4, "client_write_iv", conn->client_write_iv, 12); - format_print(stderr, 0, 0, "\n"); - */ - return 1; } @@ -8425,25 +8379,6 @@ int tls13_send_early_data(TLS_CONNECT *conn) return 1; } - - - - - - - - -// 参数request_update应该根据当前状态设置 - - -/* -如果我方是首先发送KeyUpdate一方,那么默认设置要求对方也更新密钥 - - -如果我们接收到对方的要求,并且满足我方的一个最低限度,那么就设置key_update的标志位,下次send的时候就会启动更新 - -*/ - int tls13_send_client_key_update(TLS_CONNECT *conn, int request_update) { int ret; @@ -8498,31 +8433,6 @@ int tls13_send_client_key_update(TLS_CONNECT *conn, int request_update) } return ret; - - - - /* - while (conn->recordlen) { - tls_ret_t n; - - if ((n = tls_socket_send(conn->sock, conn->record + conn->record_offset, conn->recordlen, 0)) <= 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - return TLS_ERROR_SEND_AGAIN; - } else { - if (n == 0) { - error_puts("TCP connection closed"); - } - error_print(); - return -1; - } - } - conn->recordlen -= n; - conn->record_offset += n; - } - */ - - - return 1; } int tls13_send_server_key_update(TLS_CONNECT *conn, int request_update) @@ -8579,50 +8489,6 @@ int tls13_send_server_key_update(TLS_CONNECT *conn, int request_update) } - - -/* -Post-Handshake-Auth - - 客户端在 ClientHello 中发送post_handshake_auht说明支持PHA - - 在握手完成并进行数据通信时,如果客户端请求一个特殊的地址 比如 GET /admin - 默认未认证的客户端不能访问此地址,因此服务器端如果发现客户端支持PHA,那么就会给客户端发送一个CertificateRequest - - 客户端不需要立即响应,但是如果客户端响应 - 则需要发出连续的 Certificate, CertificateVerify, Finished消息 - - - -这意味着如果客户端开始发送Certificate - 服务器就必须再次进入到握手的状态机中 - 这意味着SSL再次进入到状态机中 - - -是否意味着每次不论上层调用是read/write,SSL都是按照状态机来处理 - - -*/ - - - - - - - - - - - - - - - - - - - - int tls13_do_client_handshake(TLS_CONNECT *conn) { diff --git a/src/tls_cookie.c b/src/tls_cookie.c index 161ff2f6..07c12bde 100644 --- a/src/tls_cookie.c +++ b/src/tls_cookie.c @@ -23,12 +23,9 @@ #include #include -#include -#include -#include /* -cookie +44. cookie * server HelloRetryReqeust * client ClientHello (again) diff --git a/src/tls_ext.c b/src/tls_ext.c index 3ffd2259..3ea575d2 100644 --- a/src/tls_ext.c +++ b/src/tls_ext.c @@ -419,7 +419,7 @@ int tls_signature_algorithms_print(FILE *fp, int fmt, int ind, const uint8_t *d, } -int tls_enable_signature_algorithms_cert(TLS_CONNECT *conn) +int tls_enable_signature_algorithms_cert(TLS_CONNECT *conn, int enable) { if (!conn) { error_print(); @@ -429,7 +429,7 @@ int tls_enable_signature_algorithms_cert(TLS_CONNECT *conn) error_print(); return -1; } - conn->signature_algorithms_cert = 1; + conn->signature_algorithms_cert = enable ? 1 : 0; return 1; } diff --git a/src/tls_ocsp.c b/src/tls_ocsp.c index 901e31fd..f8373b5f 100644 --- a/src/tls_ocsp.c +++ b/src/tls_ocsp.c @@ -29,7 +29,7 @@ /* -status_request(5) +5. status_request ClientHello.status_request ext_data := CertificateStatusRequest; @@ -326,6 +326,7 @@ int tls13_set_client_status_request(TLS_CONNECT *conn, int ocsp_response_verify(const uint8_t *ocsp_response, size_t ocsp_response_len, const uint8_t *ca_certs, size_t ca_certs_len) { + error_print(); return 1; } @@ -334,7 +335,6 @@ int tls_ocsp_response_match_status_request( const uint8_t *responder_id_list, size_t responder_id_list_len, const uint8_t *request_exts, size_t request_exts_len) { + error_print(); return 1; } - - diff --git a/src/tls_psk.c b/src/tls_psk.c index 4283ee27..da6d47c0 100644 --- a/src/tls_psk.c +++ b/src/tls_psk.c @@ -23,21 +23,15 @@ #include #include -#include -#include -#include - - /* -psk_key_exchange_modes +45. psk_key_exchange_modes enum { psk_ke(0), psk_dhe_ke(1), (255) } PskKeyExchangeMode; struct { PskKeyExchangeMode ke_modes<1..255>; } PskKeyExchangeModes; - */ const char *tls13_psk_key_exchange_mode_name(int mode) @@ -144,48 +138,6 @@ int tls13_ctx_set_psk_key_exchange_modes(TLS_CTX *ctx, int psk_ke, int psk_dhe_k return 1; } - -/* -PSK 功能的关系 - - tls13_ctx_set_session_ticket_key -1. 服务器设定ticket_key - -2. 服务器设定发送NewSessionTicket,并且设定数量 - -3. 服务器 send_new_session_ticket - -4. 客户端 recv_new_session_ticket - -5. 客户端将session保存到文件中 - -6. 客户端载入session - -7. 客户端发送 pre_shared_key, 其中 ticket 来自session - -8. 服务器获取 pre_shared_key, 解密ticket,得到PSK - -9. 服务器发送 pre_shared_key, 告知客户端选定的密钥编号 - - - -基于外部预置PSK - -1. 服务器添加PSK - -2. 客户端添加PSK - -3. 客户端发送pre_shared_key - -4. 服务器用PSK去pre_shared_key查找是否有满足的 - -5. 服务器发送pre_shared_key,告知客户端选定的密钥编号 - - - -*/ - - /* session_ticket_key @@ -1719,18 +1671,16 @@ int tls13_set_early_data(TLS_CONNECT *conn, const uint8_t *data, size_t datalen) return 1; } -// 同时影响客户端和服务器吗? -int tls13_enable_early_data(TLS_CONNECT *conn, int enable) +int tls13_ctx_enable_early_data(TLS_CTX *ctx, int enable) { - if (!conn) { + if (!ctx) { error_print(); return -1; } - conn->early_data = enable ? 1 : 0; + ctx->early_data = enable ? 1 : 0; return 1; } - int tls13_ctx_set_max_early_data_size(TLS_CTX *ctx, size_t max_early_data_size) { if (!ctx) { @@ -1865,7 +1815,6 @@ int tls13_recv_end_of_early_data(TLS_CONNECT *conn) return ret; } - format_bytes(stderr, 0, 4, "client_write_iv", conn->client_write_iv, 12); if (tls13_record_decrypt(&conn->client_write_key, conn->client_write_iv, @@ -1903,5 +1852,3 @@ int tls13_recv_end_of_early_data(TLS_CONNECT *conn) return 1; } - - diff --git a/src/tls_sct.c b/src/tls_sct.c index 1d1908d0..232101d9 100644 --- a/src/tls_sct.c +++ b/src/tls_sct.c @@ -23,18 +23,14 @@ #include #include -#include -#include -#include - /* +18. signed_certificate_timestamp + + ClientHello.exts.signed_certificate_timestamp ext_data := empty -*/ - -/* Certificate.certificate_list.CertificateEntry.exts.signed_certificate_timestamp ext_data := SignedCertificateTimestamp sct_list<0..2^16-1>; struct { @@ -142,33 +138,28 @@ int tls_signed_certificate_timestamp_print(FILE *fp, int fmt, int ind, const uin return 1; } -// 这个应该改为enable, 服务器也可以设定是否响应这个请求 -int tls_enable_signed_certificate_timestamp(TLS_CONNECT *conn) +int tls_enable_signed_certificate_timestamp(TLS_CONNECT *conn, int enable) { if (!conn) { error_print(); return -1; } - conn->signed_certificate_timestamp = 1; + conn->signed_certificate_timestamp = enable ? 1 : 0; return 1; } -int tls_ctx_enable_signed_certificate_timestamp(TLS_CTX *ctx) +int tls_ctx_enable_signed_certificate_timestamp(TLS_CTX *ctx, int enable) { if (!ctx) { error_print(); return -1; } - ctx->signed_certificate_timestamp = 1; + ctx->signed_certificate_timestamp = enable ? 1 : 0; return 1; } - int tls13_signed_certificate_timestamp_verify(const uint8_t *sct_list, size_t sct_list_len) { - //error_print(); + error_print(); return 1; } - - - diff --git a/src/tls_sni.c b/src/tls_sni.c index 1da11e55..ec1879c5 100644 --- a/src/tls_sni.c +++ b/src/tls_sni.c @@ -23,12 +23,9 @@ #include #include -#include -#include -#include /* -server_name (SNI) +0. server_name (SNI) ClientHello.server_name ext_data = ServerName server_name_list<1..2^16-1> @@ -111,34 +108,6 @@ int tls_server_name_from_bytes(const uint8_t **host_name, size_t *host_name_len, return 1; } -int tls_server_name_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen) -{ - const uint8_t *server_name_list; - size_t server_name_list_len; - uint8_t name_type; - const uint8_t *host_name; - size_t host_name_len; - - if (tls_uint16array_from_bytes(&server_name_list, &server_name_list_len, &ext_data, &ext_datalen) != 1) { - error_print(); - return -1; - } - while (server_name_list_len) { - if (tls_uint8_from_bytes(&name_type, &server_name_list, &server_name_list_len) != 1 - || tls_uint16array_from_bytes(&host_name, &host_name_len, &server_name_list, &server_name_list_len) != 1) { - error_print(); - return -1; - } - format_print(fp, fmt, ind, "name_type: %s (%d)\n", name_type == 0 ? "host_name" : "(unknown)", name_type); - format_string(fp, fmt, ind, "host_name", host_name, host_name_len); // TODO: print string - } - if (ext_datalen) { - error_print(); - return -1; - } - return 1; -} - int tls_set_server_name(TLS_CONNECT *conn, const uint8_t *host_name, size_t host_name_len) { if (!conn || !host_name || !host_name_len) { @@ -160,4 +129,30 @@ int tls_set_server_name(TLS_CONNECT *conn, const uint8_t *host_name, size_t host return 1; } +int tls_server_name_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen) +{ + const uint8_t *server_name_list; + size_t server_name_list_len; + uint8_t name_type; + const uint8_t *host_name; + size_t host_name_len; + if (tls_uint16array_from_bytes(&server_name_list, &server_name_list_len, &ext_data, &ext_datalen) != 1) { + error_print(); + return -1; + } + while (server_name_list_len) { + if (tls_uint8_from_bytes(&name_type, &server_name_list, &server_name_list_len) != 1 + || tls_uint16array_from_bytes(&host_name, &host_name_len, &server_name_list, &server_name_list_len) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "name_type: %s (%d)\n", name_type == 0 ? "host_name" : "(unknown)", name_type); + format_string(fp, fmt, ind, "host_name", host_name, host_name_len); + } + if (ext_datalen) { + error_print(); + return -1; + } + return 1; +} diff --git a/tools/tls13_client.c b/tools/tls13_client.c index 5d1b6006..a07454c6 100644 --- a/tools/tls13_client.c +++ b/tools/tls13_client.c @@ -16,9 +16,6 @@ #include #include -// 检查密码参数和CA根证书是否适配 -// 检查密码参数和客户端证书是否适配 - static const char *http_get = "GET / HTTP/1.1\r\n" @@ -37,6 +34,7 @@ static const char *help = " -sig_alg str Supported signature algorithms\n" " -max_key_exchanges num Number of key exchanges in key_share extension\n" " -cacert file Root CA certificate\n" +" -verify_depth num Certificate verification depth\n" " -cert file Client's certificate chain in PEM format\n" " -key file Client's encrypted private key in PEM format\n" " -pass str Password to decrypt private key\n" @@ -55,112 +53,104 @@ static const char *help = " -early_data file Send early data, -psk_ke and/or -psk_dhe_ke should be set\n" " -key_update_seq_num num Send KeyUpdate handshake after sending/receiving records\n" " -post_handshake_auth Support post_handshake_auth\n" +" -client_cert_optional Allow client send empty Certificate\n" +" -tls13_change_cipher_spec Support ChangeCipherSpec in TLS 1.3 to be compatible with middlebox\n" "\n" -"CipherSuites\n" -" TLS_SM4_GCM_SM3 TLS 1.3\n" -" TLS_AES_128_GCM_SHA256 TLS 1.3\n" -" TLS_ECC_SM4_CBC_SM3 TLCP\n" -" TLS_ECDHE_SM4_CBC_SM3 TLCP TLS 1.2\n" -" TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 TLS 1.2\n" -"\n" -" -supported_group\n" -" sm2p256v1\n" -" prime256v1\n" -"Examples\n" -"\n" -" gmssl sm2keygen -pass 1234 -out rootcakey.pem\n" -" gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 \\\n" -" -key rootcakey.pem -pass 1234 -out rootcacert.pem \\\n" -" -key_usage keyCertSign -key_usage cRLSign -ca\n" -"\n" -" gmssl sm2keygen -pass 1234 -out cakey.pem\n" -" gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN \"Sub CA\" \\\n" -" -key cakey.pem -pass 1234 -out careq.pem\n" -" gmssl reqsign -in careq.pem -days 365 -key_usage keyCertSign -cacert rootcacert.pem -key rootcakey.pem -pass 1234 \\\n" -" -out cacert.pem -ca -path_len_constraint 0\n" -"\n" -" gmssl sm2keygen -pass 1234 -out signkey.pem\n" -" gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -key signkey.pem -pass 1234 -out signreq.pem\n" -" gmssl reqsign -in signreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out signcert.pem\n" -"\n" -" cat signcert.pem > certs.pem\n" -" cat cacert.pem >> certs.pem\n" -"\n" -" sudo gmssl tls13_server -port 4430 -cert certs.pem -key signkey.pem -pass 1234\n" -" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacert.pem\n" -" -sess_in session.bin -sess_out session.bin\n" +#include "tls13_help.h" "\n"; int tls13_client_main(int argc, char *argv[]) { int ret = -1; char *prog = argv[0]; - char *host = NULL; - int port = 443; - char *cacertfile = NULL; - char *certfile = NULL; - char *keyfile = NULL; - char *pass = NULL; + + TLS_CTX ctx; + TLS_CONNECT conn; + struct hostent *hp; struct sockaddr_in server; tls_socket_t sock = -1; - TLS_CTX ctx; - TLS_CONNECT conn; char buf[1024] = {0}; size_t len = sizeof(buf); char send_buf[1024] = {0}; size_t sent_len = 0; size_t sent_offset = 0; + char *host = NULL; + int port = 443; - char *sess_in = NULL; + // cipher_suites + int cipher_suites[4]; + size_t cipher_suites_cnt = 0; + + // CA certificates + char *cacertfile = NULL; + int verify_depth = TLS_DEFAULT_VERIFY_DEPTH; + + // CertificateRequest + char *certfile = NULL; + char *keyfile = NULL; + char *pass = NULL; + int client_cert_optional = 0; + + // supported_groups + int supported_groups[4]; + size_t supported_groups_cnt = 0; + + // key_share + char *max_key_exchanges = NULL; + int max_key_exchanges_cnt; + + // signature_algorithms + int sig_algs[4]; + size_t sig_algs_cnt = 0; + + // server_name + int server_name = 0; + + // certificate_authorities + int certificate_authorities = 0; + + // signature_algorithms_cert + int signature_algorithms_cert = 0; + + // status_request + int status_request = 0; + + // signed_certificate_timestamp + int signed_certificate_timestamp = 0; + + // post_handshake_auth + int post_handshake_auth = 0; + + // NewSessionTicket char *sess_out = NULL; + // psk_key_exchange_modes int psk_ke = 0; int psk_dhe_ke = 0; - // psk external + // pre_shared_key from NewSessionTicket + char *sess_in = NULL; + + // pre_shared_key from external char *psk_identities[16]; size_t psk_identities_cnt = 0; - char *psk_cipher_suites[16]; + int psk_cipher_suites[16]; size_t psk_cipher_suites_cnt = 0; char *psk_keys[16]; size_t psk_keys_cnt = 0; - + // EarlyData char *early_data_file = NULL; FILE *early_data_fp = NULL; int max_early_data_size = 0; - char *cipher_suite; - int cipher; - int cipher_suites[4]; - size_t cipher_suites_cnt = 0; - - char *supported_group_name; - int supported_group; - int supported_groups[4]; - size_t supported_groups_cnt = 0; - - char *max_key_exchanges = NULL; - int max_key_exchanges_cnt; - - char *sig_alg_name; - int sig_alg; - int sig_algs[4]; - size_t sig_algs_cnt = 0; - - - int certificate_authorities = 0; - - int server_name = 0; - int signature_algorithms_cert = 0; - int status_request = 0; - int signed_certificate_timestamp = 0; - + // KeyUpdate int key_update_seq_num = 0; - int post_handshake_auth = 0; + // ChangeCipherSpec + int tls13_change_cipher_spec = 0; int send_again = 0; @@ -182,9 +172,31 @@ int tls13_client_main(int argc, char *argv[]) } else if (!strcmp(*argv, "-port")) { if (--argc < 1) goto bad; port = atoi(*(++argv)); + } else if (!strcmp(*argv, "-cipher_suite")) { + char *cipher_suite_name; + int cipher_suite; + if (cipher_suites_cnt >= sizeof(cipher_suites)/sizeof(cipher_suites[0])) { + fprintf(stderr, "%s: too much -cipher_suite\n", prog); + return -1; + } + if (--argc < 1) goto bad; + cipher_suite_name = *(++argv); + if ((cipher_suite = tls_cipher_suite_from_name(cipher_suite_name)) == 0) { + fprintf(stderr, "%s: invalid -cipher_suite '%s' value\n", prog, cipher_suite_name); + return -1; + } + cipher_suites[cipher_suites_cnt] = cipher_suite; + cipher_suites_cnt++; } else if (!strcmp(*argv, "-cacert")) { if (--argc < 1) goto bad; cacertfile = *(++argv); + } else if (!strcmp(*argv, "-verify_depth")) { + if (--argc < 1) goto bad; + verify_depth = atoi(*(++argv)); + if (verify_depth < 1) { + fprintf(stderr, "%s: invalid -verify_depth value '%d'\n", prog, verify_depth); + return -1; + } } else if (!strcmp(*argv, "-cert")) { if (--argc < 1) goto bad; certfile = *(++argv); @@ -212,78 +224,75 @@ int tls13_client_main(int argc, char *argv[]) } else if (!strcmp(*argv, "-sess_out")) { if (--argc < 1) goto bad; sess_out = *(++argv); - } else if (!strcmp(*argv, "-psk_ke")) { psk_ke = 1; } else if (!strcmp(*argv, "-psk_dhe_ke")) { psk_dhe_ke = 1; } else if (!strcmp(*argv, "-psk_identity")) { - if (--argc < 1) goto bad; if (psk_identities_cnt > sizeof(psk_identities)/sizeof(psk_identities[0])) { - error_print(); + fprintf(stderr, "%s: too much -psk_identity\n", prog); return -1; } + if (--argc < 1) goto bad; psk_identities[psk_identities_cnt++] = *(++argv); } else if (!strcmp(*argv, "-psk_cipher_suite")) { - if (--argc < 1) goto bad; + char *cipher_suite_name; + int cipher_suite; if (psk_cipher_suites_cnt > sizeof(psk_cipher_suites)/sizeof(psk_cipher_suites[0])) { - error_print(); + fprintf(stderr, "%s: too much -psk_cipher_suite\n", prog); return -1; } - psk_cipher_suites[psk_cipher_suites_cnt++] = *(++argv); - } else if (!strcmp(*argv, "-psk_key")) { if (--argc < 1) goto bad; - if (psk_keys_cnt > sizeof(psk_keys)/sizeof(psk_keys[0])) { - error_print(); + cipher_suite_name = *(++argv); + if ((cipher_suite = tls_cipher_suite_from_name(cipher_suite_name)) == 0) { + fprintf(stderr, "%s: -psk_cipher_suite '%s' not supported\n", prog, cipher_suite_name); return -1; } - psk_keys[psk_keys_cnt++] = *(++argv); + psk_cipher_suites[psk_cipher_suites_cnt++] = cipher_suite; + } else if (!strcmp(*argv, "-psk_key")) { + char *psk_key_hex; + if (psk_keys_cnt > sizeof(psk_keys)/sizeof(psk_keys[0])) { + fprintf(stderr, "%s: too much -psk_key\n", prog); + return -1; + } + if (--argc < 1) goto bad; + psk_key_hex = *(++argv); + if (strlen(psk_key_hex) != 64) { + fprintf(stderr, "%s: invalid -psk_key '%s' length\n", prog, psk_key_hex); + return -1; + } + psk_keys[psk_keys_cnt++] = psk_key_hex; } else if (!strcmp(*argv, "-early_data")) { if (--argc < 1) goto bad; early_data_file = *(++argv); } else if (!strcmp(*argv, "-max_early_data_size")) { if (--argc < 1) goto bad; max_early_data_size = atoi(*(++argv)); - } else if (!strcmp(*argv, "-cipher_suite")) { - if (--argc < 1) goto bad; - cipher_suite = *(++argv); - if ((cipher = tls_cipher_suite_from_name(cipher_suite)) == 0) { - error_print(); - fprintf(stderr, "%s: cipher suite '%s' not supported\n", prog, cipher_suite); - return -1; - } - if (cipher_suites_cnt >= sizeof(cipher_suites)/sizeof(cipher_suites[0])) { - error_print(); - fprintf(stderr, "%s: too much cipher suites\n", prog); - return -1; - } - cipher_suites[cipher_suites_cnt] = cipher; - cipher_suites_cnt++; } else if (!strcmp(*argv, "-supported_group")) { + char *supported_group_name; + int supported_group; + if (supported_groups_cnt >= sizeof(supported_groups)/sizeof(supported_groups[0])) { + fprintf(stderr, "%s: too much -supported_group\n", prog); + return -1; + } if (--argc < 1) goto bad; supported_group_name = *(++argv); if ((supported_group = tls_named_curve_from_name(supported_group_name)) == 0) { - error_print(); - fprintf(stderr, "%s: supported_group '%s' not supported\n", prog, supported_group_name); - return -1; - } - if (supported_groups_cnt >= sizeof(supported_groups)/sizeof(supported_groups[0])) { - error_print(); - fprintf(stderr, "%s: too much supported_group\n", prog); + fprintf(stderr, "%s: -supported_group '%s' not supported\n", prog, supported_group_name); return -1; } supported_groups[supported_groups_cnt++] = supported_group; } else if (!strcmp(*argv, "-sig_alg")) { + char *sig_alg_name; + int sig_alg; + if (sig_algs_cnt >= sizeof(sig_algs)/sizeof(sig_algs[0])) { + fprintf(stderr, "%s: too much -sig_alg\n", prog); + return -1; + } if (--argc < 1) goto bad; sig_alg_name = *(++argv); if ((sig_alg = tls_signature_scheme_from_name(sig_alg_name)) == 0) { - error_print(); - fprintf(stderr, "%s: sig_alg '%s' not supported\n", prog, sig_alg_name); - return -1; - } - if (sig_algs_cnt >= sizeof(sig_algs)/sizeof(sig_algs[0])) { - error_print(); - fprintf(stderr, "%s: too much sig_algs\n", prog); + fprintf(stderr, "%s: -sig_alg '%s' not supported\n", prog, sig_alg_name); return -1; } sig_algs[sig_algs_cnt++] = sig_alg; @@ -292,17 +301,20 @@ int tls13_client_main(int argc, char *argv[]) max_key_exchanges = *(++argv); max_key_exchanges_cnt = atoi(max_key_exchanges); if (max_key_exchanges_cnt < 0) { - error_print(); + fprintf(stderr, "%s: -max_key_exchanges value '%s' invalid\n", prog, max_key_exchanges); return -1; } } else if (!strcmp(*argv, "-key_update_seq_num")) { if (--argc < 1) goto bad; key_update_seq_num = atoi(*(++argv)); if (key_update_seq_num < 0) { - error_print(); - fprintf(stderr, "%s: invalid '-key_update_seq_num' value\n", prog); + fprintf(stderr, "%s: invalid -key_update_seq_num value\n", prog); return -1; } + } else if (!strcmp(*argv, "-client_cert_optional")) { + client_cert_optional = 1; + } else if (!strcmp(*argv, "-tls13_change_cipher_spec")) { + tls13_change_cipher_spec = 1; } else { fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); return 1; @@ -315,117 +327,135 @@ bad: } if (!host) { - fprintf(stderr, "%s: '-in' option required\n", prog); + fprintf(stderr, "%s: '-host' option required\n", prog); return -1; } - if (tls_socket_lib_init() != 1) { - error_print(); + if (!cipher_suites_cnt) { + fprintf(stderr, "%s: option '-cipher_suite' required\n", prog); return -1; } - if (!(hp = gethostbyname(host))) { - //herror("tls13_client: '-host' invalid"); - goto end; - } - - memset(&ctx, 0, sizeof(ctx)); - memset(&conn, 0, sizeof(conn)); - - - + // TLS_CTX if (tls_ctx_init(&ctx, TLS_protocol_tls13, TLS_client_mode) != 1) { - fprintf(stderr, "%s: context init error\n", prog); - goto end; - } - - /* - if (!cipher_suites_cnt) { error_print(); - fprintf(stderr, "%s: option '-cipher_suite' required\n", prog); - goto end; + return -1; } - */ + // cipher_suites if (tls_ctx_set_cipher_suites(&ctx, cipher_suites, cipher_suites_cnt) != 1) { - fprintf(stderr, "%s: context init error\n", prog); + error_print(); goto end; } + // supported_groups if (supported_groups_cnt > 0) { if (tls_ctx_set_supported_groups(&ctx, supported_groups, supported_groups_cnt) != 1) { error_print(); - return -1; + goto end; } } - if (max_key_exchanges) { - tls13_ctx_set_max_key_exchanges(&ctx, max_key_exchanges_cnt); - } - - + // signature_algorithms if (sig_algs_cnt > 0) { if (tls_ctx_set_signature_algorithms(&ctx, sig_algs, sig_algs_cnt) != 1) { error_print(); - return -1; - } - } - - if (cacertfile) { - if (tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1) { - fprintf(stderr, "%s: context init error\n", prog); - goto end; - } - - - - } - if (certfile) { - if (tls_ctx_add_certificate_chain_and_key(&ctx, certfile, keyfile, pass) != 1) { - fprintf(stderr, "%s: context init error\n", prog); goto end; } } - if (psk_ke || psk_dhe_ke) { - if (!sess_in && !psk_keys_cnt) { - fprintf(stderr, "%s: -sess_in or -psk is required\n", prog); + // key_share + if (max_key_exchanges) { + if (tls13_ctx_set_max_key_exchanges(&ctx, max_key_exchanges_cnt) != 1) { error_print(); - return -1; + goto end; } - tls13_ctx_set_psk_key_exchange_modes(&ctx, psk_ke, psk_dhe_ke); } + // CA certificates + if (cacertfile) { + if (tls_ctx_set_ca_certificates(&ctx, cacertfile, verify_depth) != 1) { + fprintf(stderr, "%s: load CA certificates file '%s' failure\n", prog, cacertfile); + goto end; + } + } + // CertificateRequest + if (certfile) { + if (!keyfile) { + fprintf(stderr, "%s: option '-key' required\n", prog); + goto end; + } + if (!pass) { + fprintf(stderr, "%s: option '-pass' requried\n", prog); + goto end; + } + if (tls_ctx_add_certificate_chain_and_key(&ctx, certfile, keyfile, pass) != 1) { + fprintf(stderr, "%s: load certificate chain and key failed\n", prog); + goto end; + } + } + // psk_key_exchange_modes + if (psk_ke || psk_dhe_ke) { + // allow ClientHello with psk_key_exchange_modes, but no pre_shared_key + if (tls13_ctx_set_psk_key_exchange_modes(&ctx, psk_ke, psk_dhe_ke) != 1) { + error_print(); + goto end; + } + } + + // KeyUpdate if (key_update_seq_num > 0) { if (tls_ctx_set_key_update_seq_num_limit(&ctx, key_update_seq_num) != 1) { error_print(); - return -1; + goto end; } } - - if (tls13_init(&conn, &ctx) != 1) { - fprintf(stderr, "%s: error\n", prog); - goto end; - } - - - if (server_name) { - error_print(); - if (tls_set_server_name(&conn, (uint8_t *)host, strlen(host)) != 1) { + // CertificateRequest + if (client_cert_optional) { + if (tls13_ctx_enable_client_certificate_optional(&ctx, 1) != 1) { error_print(); goto end; } - fprintf(stderr, "conn->server_name= %d\n", conn.server_name); + } + + // ChangeCipherSpec + if (tls13_change_cipher_spec) { + if (tls13_ctx_enable_change_cipher_spec(&ctx, 1) != 1) { + error_print(); + goto end; + } + } + + + // TLS_CONNECT + + if (tls13_init(&conn, &ctx) != 1) { + error_print(); + goto end; } if (signature_algorithms_cert) { - if (tls_enable_signature_algorithms_cert(&conn) != 1) { + if (tls_enable_signature_algorithms_cert(&conn, 1) != 1) { error_print(); - return -1; + goto end; + } + } + + if (certificate_authorities) { + if (tls13_enable_certificate_authorities(&conn, 1) != 1) { + error_print(); + goto end; + } + } + + if (server_name) { + if (tls_set_server_name(&conn, (uint8_t *)host, strlen(host)) != 1) { + error_print(); + goto end; } } @@ -435,44 +465,18 @@ bad: goto end; } } + if (signed_certificate_timestamp) { - if (tls_enable_signed_certificate_timestamp(&conn) != 1) { + if (tls_enable_signed_certificate_timestamp(&conn, 1) != 1) { error_print(); goto end; } } - if (certificate_authorities) { - if (tls13_enable_certificate_authorities(&conn, 1) != 1) { - error_print(); - return -1; - } - } - - if (sess_in) { - FILE *sess_infp; - int psk_ret = 1; - - if (!(sess_infp = fopen(sess_in, "rb"))) { - error_print(); - goto end; - } - - while (psk_ret) { - if ((psk_ret = tls13_add_pre_shared_key_from_session_file(&conn, sess_infp)) < 0) { - error_print(); - fclose(sess_infp); - return -1; - } - } - fclose(sess_infp); - - - // 客户端是否发送pre_shared_key是由什么决定的?需要显式的支持吗 - // 我觉得应该是不需要的,因为如果设置了psk_key_exchange_mode,那么自然要发送pre_shared_key - tls13_enable_pre_shared_key(&conn, 1); + if (post_handshake_auth) { } + // NewSessionTicket if (sess_out) { if (tls13_set_session_outfile(&conn, sess_out) != 1) { error_print(); @@ -480,80 +484,118 @@ bad: } } + // pre_shared_key from external if (psk_keys_cnt) { const uint32_t obfuscated_ticket_age = 0; size_t i; if (psk_identities_cnt != psk_keys_cnt || psk_cipher_suites_cnt != psk_keys_cnt) { error_print(); - return -1; + goto end; } for (i = 0; i < psk_keys_cnt; i++) { - int psk_cipher_suite; const BLOCK_CIPHER *psk_cipher; const DIGEST *psk_digest; uint8_t psk_key[64]; size_t psk_key_len; - if (!(psk_cipher_suite = tls_cipher_suite_from_name(psk_cipher_suites[i]))) { + if (tls13_cipher_suite_get(psk_cipher_suites[i], &psk_cipher, &psk_digest) != 1) { error_print(); - return -1; - } - if (tls13_cipher_suite_get(psk_cipher_suite, &psk_cipher, &psk_digest) != 1) { - error_print(); - return -1; + goto end; } if (strlen(psk_keys[i]) != psk_digest->digest_size * 2) { error_print(); - return -1; + goto end; } if (hex_to_bytes(psk_keys[i], strlen(psk_keys[i]), psk_key, &psk_key_len) != 1) { error_print(); - return -1; + goto end; } if (tls13_add_pre_shared_key(&conn, (uint8_t *)psk_identities[i], strlen(psk_identities[i]), - psk_key, psk_key_len, psk_cipher_suite, obfuscated_ticket_age) != 1) { + psk_key, psk_key_len, psk_cipher_suites[i], obfuscated_ticket_age) != 1) { error_print(); - return -1; + goto end; } } tls13_enable_pre_shared_key(&conn, 1); + + // pre_shared_key from NewSessionTicket + } else if (sess_in) { + FILE *sess_infp; + + if (!psk_dhe_ke && !psk_ke) { + fprintf(stderr, "%s: option '-psk_dhe_ke' or '-psk_ke' required\n", prog); + goto end; + } + + if (!(sess_infp = fopen(sess_in, "rb"))) { + fprintf(stderr, "%s: open file '%s' failure\n", prog, sess_in); + goto end; + } + + do { + if ((ret = tls13_add_pre_shared_key_from_session_file(&conn, sess_infp)) < 0) { + fclose(sess_infp); + fprintf(stderr, "%s: load session file '%s' failure\n", prog, sess_in); + goto end; + } + } while (ret); + + fclose(sess_infp); + + if (tls13_enable_pre_shared_key(&conn, 1) != 1) { + error_print(); + goto end; + } } + // EarlyData if (early_data_file) { uint8_t early_data[8192]; size_t early_data_len; - if (!psk_ke && !psk_dhe_ke) { - error_print(); - fprintf(stderr, "%s: -early_data need -psk_ke and/or -psk_dhe_ke set\n", prog); - return -1; + if (!psk_keys_cnt && !sess_in) { + fprintf(stderr, "%s: -psk_key or -sess_in required by -early_data\n", prog); + goto end; } if (!(early_data_fp = fopen(early_data_file, "rb"))) { - error_print(); - return -1; + fprintf(stderr, "%s: open file '%s' failure\n", prog, early_data_file); + goto end; } - early_data_len = fread(early_data, 1, sizeof(early_data), early_data_fp); - - if (early_data_len) { - - if (tls13_set_early_data(&conn, early_data, early_data_len) != 1) { + if (!(early_data_len = fread(early_data, 1, sizeof(early_data), early_data_fp))) { + if (feof(early_data_fp)) { + fprintf(stderr, "%s: empty file '%s'\n", prog, early_data_file); + } else { + fprintf(stderr, "%s: read file '%s' failure\n", prog, early_data_file); fclose(early_data_fp); - error_print(); - return -1; + goto end; } } fclose(early_data_fp); - } - if (post_handshake_auth) { + if (early_data_len) { + if (tls13_set_early_data(&conn, early_data, early_data_len) != 1) { + error_print(); + goto end; + } + } } + // socket + if (tls_socket_lib_init() != 1) { + error_print(); + goto end; + } + + if (!(hp = gethostbyname(host))) { + fprintf(stderr, "%s: parse -host value error: %s\n", prog, hstrerror(h_errno)); + goto end; + } server.sin_addr = *((struct in_addr *)hp->h_addr_list[0]); server.sin_family = AF_INET; server.sin_port = htons(port); @@ -567,17 +609,18 @@ bad: goto end; } + if (tls_set_socket(&conn, sock) != 1) { + error_print(); + goto end; + } - if (tls_set_socket(&conn, sock) != 1 - || tls_do_handshake(&conn) != 1) { + if (tls_do_handshake(&conn) != 1) { fprintf(stderr, "%s: error\n", prog); goto end; } - - fprintf(stderr, ">>>>>>>>>>>>\n"); - - + fprintf(stderr, "connected\n"); + fprintf(stderr, "\n"); for (;;) { @@ -624,17 +667,8 @@ bad: fflush(stdout); - - // FIXME: change tls13_recv API - /* - if (conn.datalen == 0) { - error_print(); - break; - } - */ } - // 读用户输入 if (FD_ISSET(fileno(stdin), &fds_recv)) { memset(send_buf, 0, sizeof(send_buf)); diff --git a/tools/tls13_help.h b/tools/tls13_help.h new file mode 100644 index 00000000..0473cf34 --- /dev/null +++ b/tools/tls13_help.h @@ -0,0 +1,202 @@ +"\n" +" -cipher_suite options\n" +" TLS_SM4_GCM_SM3 TLS 1.3\n" +" TLS_AES_128_GCM_SHA256 TLS 1.3\n" +" TLS_ECC_SM4_CBC_SM3 TLCP\n" +" TLS_ECDHE_SM4_CBC_SM3 TLCP TLS 1.2\n" +" TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 TLS 1.2\n" +"\n" +" -supported_group options\n" +" sm2p256v1\n" +" prime256v1\n" +"\n" +" -sig_alg options\n" +" sm2sig_sm3\n" +" ecdsa_secp256r1_sha256\n" +"\n" +"Generate SM2 certificates\n" +"\n" +" gmssl sm2keygen -pass 1234 -out sm2rootcakey.pem\n" +" gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 \\\n" +" -key sm2rootcakey.pem -pass 1234 -out sm2rootcacert.pem \\\n" +" -key_usage keyCertSign -key_usage cRLSign -ca\n" +"\n" +" gmssl sm2keygen -pass 1234 -out sm2cakey.pem\n" +" gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN \"Sub CA\" \\\n" +" -key sm2cakey.pem -pass 1234 -out sm2careq.pem\n" +" gmssl reqsign -in sm2careq.pem -days 365 -key_usage keyCertSign \\\n" +" -cacert sm2rootcacert.pem -key sm2rootcakey.pem -pass 1234 \\\n" +" -ca -path_len_constraint 0 \\\n" +" -out sm2cacert.pem\n" +"\n" +" gmssl sm2keygen -pass 1234 -out sm2signkey.pem\n" +" gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost \\\n" +" -key sm2signkey.pem -pass 1234 -out sm2signreq.pem\n" +" gmssl reqsign -in sm2signreq.pem -days 365 -key_usage digitalSignature \\\n" +" -cacert sm2cacert.pem -key sm2cakey.pem -pass 1234 \\\n" +" -out sm2signcert.pem\n" +"\n" +" cat sm2signcert.pem > sm2certs.pem\n" +" cat sm2cacert.pem >> sm2certs.pem\n" +"\n" +"TLS 1.3 with TLS_SM4_GCM_SM3 cipher suite\n" +"\n" +" sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n" +" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3\n" +"\n" +" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert sm2rootcacert.pem \\\n" +" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3\n" +"\n" +"Generate P-256 certificates\n" +"\n" +" gmssl p256keygen -pass 1234 -out p256rootcakey.pem -export p256rootcakey.exp\n" +" gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN P256ROOTCA -days 3650 \\\n" +" -key p256rootcakey.pem -pass 1234 -out p256rootcacert.pem \\\n" +" -key_usage keyCertSign -key_usage cRLSign -ca\n" +"\n" +" gmssl p256keygen -pass 1234 -out p256cakey.pem -export p256cakey.exp\n" +" gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN \"P256 Sub CA\" \\\n" +" -key p256cakey.pem -pass 1234 -out p256careq.pem\n" +" gmssl reqsign -in p256careq.pem -days 365 -key_usage keyCertSign \\\n" +" -cacert p256rootcacert.pem -key p256rootcakey.pem -pass 1234 \\\n" +" -ca -path_len_constraint 0 \\\n" +" -out p256cacert.pem\n" +"\n" +" gmssl p256keygen -pass 1234 -out p256signkey.pem -export p256signkey.exp\n" +" gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN 127.0.0.1 \\\n" +" -key p256signkey.pem -pass 1234 -out p256signreq.pem\n" +" gmssl reqsign -in p256signreq.pem -days 365 -key_usage digitalSignature \\\n" +" -cacert p256cacert.pem -key p256cakey.pem -pass 1234 \\\n" +" -subject_dns_name 127.0.0.1 \\\n" +" -out p256signcert.pem\n" +"\n" +" cat p256signcert.pem > p256certs.pem\n" +" cat p256cacert.pem >> p256certs.pem\n" +"\n" +" cat sm2rootcacert.pem > rootcacerts.pem\n" +" cat p256rootcacert.pem >> rootcacerts.pem\n" +"\n" +"TLS 1.3 with TLS_AES_128_GCM_SHA256\n" +" sudo gmssl tls13_server -port 4430 \\\n" +" -cipher_suite TLS_AES_128_GCM_SHA256 -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256 \\\n" +" -cert p256certs.pem -key p256signkey.pem -pass 1234\n" +"\n" +" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacerts.pem \\\n" +" -cipher_suite TLS_AES_128_GCM_SHA256 -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256\n" +"\n" +" add `SSL_CTX_clear_options(ctx, SSL_OP_ENABLE_MIDDLEBOX_COMPAT);` to openssl apps/s_server.c\n" +" add `SSL_CTX_clear_options(ctx, SSL_OP_ENABLE_MIDDLEBOX_COMPAT);` to openssl apps/s_client.c\n" +"\n" +" /usr/local/bin/openssl s_server -accept 4430 -cert p256signcert.pem -cert_chain p256cacert.pem -key p256signkey.exp \\\n" +" -tls1_3 -ciphersuites TLS_AES_128_GCM_SHA256 -named_curve prime256v1 \\\n" +" -trace\n" +"\n" +" /usr/local/bin/openssl s_client -connect 127.0.0.1:4430 -tls1_3 -CAfile p256rootcacert.pem -groups prime256v1 -trace\n" +"\n" +"TLS 1.3 SNI\n" +"\n" +" sudo gmssl tls13_server -port 4430 \\\n" +" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n" +" -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n" +" -cipher_suite TLS_AES_128_GCM_SHA256 -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256\n" +" -cert p256certs.pem -key p256signkey.pem -pass 1234 \\\n" +"\n" +" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacerts.pem \\\n" +" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n" +" -cipher_suite TLS_AES_128_GCM_SHA256 -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256\n" +" -server_name\n" +"\n" +"HelloRetryRequest\n" +"\n" +" sudo gmssl tls13_server -port 4430 \\\n" +" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n" +" -cert sm2certs.pem -key sm2signkey.pem -pass 1234\n" +"\n" +" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacerts.pem \\\n" +" -cipher_suite TLS_AES_128_GCM_SHA256 -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256 \\\n" +" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n" +" -max_key_exchanges 1 # or -max_key_exchanges 0 \n" +"\n" +"ClientHello with OCSP request, CT, and other extensions\n" +"\n" +" sudo gmssl tls13_server -port 4430 \\\n" +" -cipher_suite TLS_SM4_GCM_SM3 -cipher_suite TLS_AES_128_GCM_SHA256 \\\n" +" -supported_group sm2p256v1 -supported_group prime256v1 \\\n" +" -sig_alg sm2sig_sm3 -sig_alg ecdsa_secp256r1_sha256 \\\n" +" -cert sm2certs.pem -key sm2signkey.pem -pass 1234\n" +"\n" +" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacerts.pem \\\n" +" -cipher_suite TLS_SM4_GCM_SM3 -cipher_suite TLS_AES_128_GCM_SHA256 \\\n" +" -supported_group sm2p256v1 -supported_group prime256v1 \\\n" +" -sig_alg sm2sig_sm3 -sig_alg ecdsa_secp256r1_sha256 \\\n" +" -max_key_exchanges 2 \\\n" +" -server_name \\\n" +" -signature_algorithms_cert \\\n" +" -status_request \\\n" +" -post_handshake_auth \\\n" +" -ct\n" +"\n" +"NewSessionTicket\n" +"\n" +" TICKET_KEY=11223344556677881122334455667788\n" +"\n" +" sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n" +" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n" +" -new_session_ticket 2 -ticket_key $TICKET_KEY\n" +"\n" +" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacerts.pem \\\n" +" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n" +" -sess_out session.bin\n" +"\n" +"PSK-DHE from session ticket\n" +"\n" +" sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n" +" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 \\\n" +" -psk_dhe_ke -ticket_key $TICKET_KEY\n" +"\n" +" gmssl tls13_client -host 127.0.0.1 -port 4430 \\\n" +" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 \\\n" +" -psk_dhe_ke -sess_in session.bin\n" +"\n" +"PSK-DHE/PSK from external\n" +"\n" +" PSK=1122334455667788112233445566778811223344556677881122334455667788\n" +"\n" +" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n" +" -supported_group sm2p256v1 -psk_dhe_ke \\\n" +" -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n" +"\n" +" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n" +" -supported_group sm2p256v1 -psk_dhe_ke \\\n" +" -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n" +"\n" +" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n" +" -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n" +"\n" +" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n" +" -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n" +"\n" +"EarlyData (0-RTT)\n" +"\n" +" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n" +" -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK \\\n" +" -early_data\n" +"\n" +" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n" +" -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK \\\n" +" -early_data early_data.txt\n" +"\n" +"CertificateRequest\n" +"\n" +" sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n" +" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n" +" -cert_request -cacert sm2rootcacert.pem\n" +"\n" +" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert sm2rootcacert.pem \\\n" +" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n" +" -cert sm2certs.pem -key sm2signkey.pem -pass 1234\n" +"\n" +"CertificateRequest without CertificateVerify\n" +"\n" +" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert sm2rootcacert.pem \\\n" +" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3\n" diff --git a/tools/tls13_server.c b/tools/tls13_server.c index 626ec1ef..48381799 100644 --- a/tools/tls13_server.c +++ b/tools/tls13_server.c @@ -19,22 +19,6 @@ #include -// 服务器在启动时是否检查密码参数和证书适配的问题 -// 服务器设置 -psk_dhe_ke,启动的时候没有检查是否提供了 supported_group 参数 -// psk_cipher_suite 和 cipher_suite 是冗余的 - - -// 重新思考一下,各个层次如何将各自的输入输出打印出来,特别是在record层 -// 每个报文包括密文和明文,应该将两者紧密连在一起,没有空格 -// 在报文层,只显示明文的16进制,但是在上层,应该显示明文的ASCII和HEX,能够看清楚消息 - - -// 为了保证能够和openssl互通,需要将PKCS8的私钥导出为openssl可以识别的格式。 -// 或者P256的私钥应该用AES-128 + SHA-256加密 - - -// 应该首先打印openssl的密钥序列,early_secret, pre_master_secret, 以及 handshake_secret 等 - static const char *options = "[-port num] -cert file -key file -pass str [-cacert file]"; @@ -48,8 +32,10 @@ static const char *help = " -cert file Server's certificate chain in PEM format\n" " -key file Server's encrypted private key in PEM format\n" " -pass str Password to decrypt private key\n" -" -new_session_ticket num Send NewSessionTicket times\n" -" -ticket_key hex Session ticket encrypt/decrypt key in HEX format\n" +" -cert_request Client certificate request\n" +" -client_cert_optional Allow client send empty Certificate\n" +" -cacert file CA certificate for client certificate verification\n" +" -verify_depth num Certificate verification depth\n" " -psk_ke Support PSK-only key exchange\n" " -psk_dhe_ke Support PSK with (EC)DHE key exchange\n" " -psk_identity str PSK Identity\n" @@ -57,256 +43,53 @@ static const char *help = " -psk_key hex PSK key in HEX format, of PSK hash length\n" " -early_data Accept EarlyData, support 0-RTT\n" " -max_early_data_size num Set extension max_early_data_size\n" -" -cert_request Client certificate request\n" -" -cacert file CA certificate for client certificate verification\n" +" -new_session_ticket num Send NewSessionTicket times\n" +" -ticket_key hex Session ticket encrypt/decrypt key in HEX format\n" " -key_update_seq_num num Send KeyUpdate handshake after sending/receiving records\n" +" -tls13_change_cipher_spec Support ChangeCipherSpec in TLS 1.3 to be compatible with middlebox\n" "\n" -" -cipher_suite options\n" -" TLS_SM4_GCM_SM3 TLS 1.3\n" -" TLS_AES_128_GCM_SHA256 TLS 1.3\n" -" TLS_ECC_SM4_CBC_SM3 TLCP\n" -" TLS_ECDHE_SM4_CBC_SM3 TLCP TLS 1.2\n" -" TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 TLS 1.2\n" -"\n" -" -supported_group options\n" -" sm2p256v1\n" -" prime256v1\n" -"\n" -" -sig_alg options\n" -" sm2sig_sm3\n" -" ecdsa_secp256r1_sha256\n" -"\n" -"Generate SM2 certificates\n" -"\n" -" gmssl sm2keygen -pass 1234 -out sm2rootcakey.pem\n" -" gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 \\\n" -" -key sm2rootcakey.pem -pass 1234 -out sm2rootcacert.pem \\\n" -" -key_usage keyCertSign -key_usage cRLSign -ca\n" -"\n" -" gmssl sm2keygen -pass 1234 -out sm2cakey.pem\n" -" gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN \"Sub CA\" \\\n" -" -key sm2cakey.pem -pass 1234 -out sm2careq.pem\n" -" gmssl reqsign -in sm2careq.pem -days 365 -key_usage keyCertSign \\\n" -" -cacert sm2rootcacert.pem -key sm2rootcakey.pem -pass 1234 \\\n" -" -ca -path_len_constraint 0 \\\n" -" -out sm2cacert.pem\n" -"\n" -" gmssl sm2keygen -pass 1234 -out sm2signkey.pem\n" -" gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost \\\n" -" -key sm2signkey.pem -pass 1234 -out sm2signreq.pem\n" -" gmssl reqsign -in sm2signreq.pem -days 365 -key_usage digitalSignature \\\n" -" -cacert sm2cacert.pem -key sm2cakey.pem -pass 1234 \\\n" -" -out sm2signcert.pem\n" -"\n" -" cat sm2signcert.pem > sm2certs.pem\n" -" cat sm2cacert.pem >> sm2certs.pem\n" -"\n" -"TLS 1.3 with TLS_SM4_GCM_SM3 cipher suite\n" -"\n" -" sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n" -" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3\n" -"\n" -" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert sm2rootcacert.pem \\\n" -" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3\n" -"\n" -"Generate P-256 certificates\n" -"\n" -" gmssl p256keygen -pass 1234 -out p256rootcakey.pem -export p256rootcakey.exp\n" -" gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN P256ROOTCA -days 3650 \\\n" -" -key p256rootcakey.pem -pass 1234 -out p256rootcacert.pem \\\n" -" -key_usage keyCertSign -key_usage cRLSign -ca\n" -"\n" -" gmssl p256keygen -pass 1234 -out p256cakey.pem -export p256cakey.exp\n" -" gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN \"P256 Sub CA\" \\\n" -" -key p256cakey.pem -pass 1234 -out p256careq.pem\n" -" gmssl reqsign -in p256careq.pem -days 365 -key_usage keyCertSign \\\n" -" -cacert p256rootcacert.pem -key p256rootcakey.pem -pass 1234 \\\n" -" -ca -path_len_constraint 0 \\\n" -" -out p256cacert.pem\n" -"\n" -" gmssl p256keygen -pass 1234 -out p256signkey.pem -export p256signkey.exp\n" -" gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN 127.0.0.1 \\\n" -" -key p256signkey.pem -pass 1234 -out p256signreq.pem\n" -" gmssl reqsign -in p256signreq.pem -days 365 -key_usage digitalSignature \\\n" -" -cacert p256cacert.pem -key p256cakey.pem -pass 1234 \\\n" -" -subject_dns_name 127.0.0.1 \\\n" -" -out p256signcert.pem\n" -"\n" -" cat p256signcert.pem > p256certs.pem\n" -" cat p256cacert.pem >> p256certs.pem\n" -"\n" -" cat sm2rootcacert.pem > rootcacerts.pem\n" -" cat p256rootcacert.pem >> rootcacerts.pem\n" -"\n" -"TLS 1.3 with TLS_AES_128_GCM_SHA256\n" -" sudo gmssl tls13_server -port 4430 \\\n" -" -cipher_suite TLS_AES_128_GCM_SHA256 -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256 \\\n" -" -cert p256certs.pem -key p256signkey.pem -pass 1234\n" -"\n" -" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacerts.pem \\\n" -" -cipher_suite TLS_AES_128_GCM_SHA256 -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256\n" -"\n" -" add `SSL_CTX_clear_options(ctx, SSL_OP_ENABLE_MIDDLEBOX_COMPAT);` to openssl apps/s_server.c\n" -" add `SSL_CTX_clear_options(ctx, SSL_OP_ENABLE_MIDDLEBOX_COMPAT);` to openssl apps/s_client.c\n" -"\n" -" /usr/local/bin/openssl s_server -accept 4430 -cert p256signcert.pem -cert_chain p256cacert.pem -key p256signkey.exp \\\n" -" -tls1_3 -ciphersuites TLS_AES_128_GCM_SHA256 -named_curve prime256v1 \\\n" -" -trace\n" -"\n" -" /usr/local/bin/openssl s_client -connect 127.0.0.1:4430 -tls1_3 -CAfile p256rootcacert.pem -groups prime256v1 -trace\n" -"\n" -"TLS 1.3 SNI\n" -"\n" -" sudo gmssl tls13_server -port 4430 \\\n" -" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n" -" -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n" -" -cipher_suite TLS_AES_128_GCM_SHA256 -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256\n" -" -cert p256certs.pem -key p256signkey.pem -pass 1234 \\\n" -"\n" -" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacerts.pem \\\n" -" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n" -" -cipher_suite TLS_AES_128_GCM_SHA256 -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256\n" -" -server_name\n" -"\n" -"HelloRetryRequest\n" -"\n" -" sudo gmssl tls13_server -port 4430 \\\n" -" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n" -" -cert sm2certs.pem -key sm2signkey.pem -pass 1234\n" -"\n" -" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacerts.pem \\\n" -" -cipher_suite TLS_AES_128_GCM_SHA256 -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256 \\\n" -" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n" -" -max_key_exchanges 1 # or -max_key_exchanges 0 \n" -"\n" -"ClientHello with OCSP request, CT, and other extensions\n" -"\n" -" sudo gmssl tls13_server -port 4430 \\\n" -" -cipher_suite TLS_SM4_GCM_SM3 -cipher_suite TLS_AES_128_GCM_SHA256 \\\n" -" -supported_group sm2p256v1 -supported_group prime256v1 \\\n" -" -sig_alg sm2sig_sm3 -sig_alg ecdsa_secp256r1_sha256 \\\n" -" -cert sm2certs.pem -key sm2signkey.pem -pass 1234\n" -"\n" -" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacerts.pem \\\n" -" -cipher_suite TLS_SM4_GCM_SM3 -cipher_suite TLS_AES_128_GCM_SHA256 \\\n" -" -supported_group sm2p256v1 -supported_group prime256v1 \\\n" -" -sig_alg sm2sig_sm3 -sig_alg ecdsa_secp256r1_sha256 \\\n" -" -max_key_exchanges 2 \\\n" -" -server_name \\\n" -" -signature_algorithms_cert \\\n" -" -status_request \\\n" -" -post_handshake_auth \\\n" -" -ct\n" -"\n" -"NewSessionTicket\n" -"\n" -" TICKET_KEY=11223344556677881122334455667788\n" -"\n" -" sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n" -" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n" -" -new_session_ticket 2 -ticket_key $TICKET_KEY\n" -"\n" -" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacerts.pem \\\n" -" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n" -" -sess_out session.bin\n" -"\n" -"PSK-DHE from session ticket\n" -"\n" -" sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n" -" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 \\\n" -" -psk_dhe_ke -ticket_key $TICKET_KEY\n" -"\n" -" gmssl tls13_client -host 127.0.0.1 -port 4430 \\\n" -" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 \\\n" -" -psk_dhe_ke -sess_in session.bin\n" -"\n" -"PSK-DHE/PSK from external\n" -"\n" -" PSK=1122334455667788112233445566778811223344556677881122334455667788\n" -"\n" -" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n" -" -supported_group sm2p256v1 -psk_dhe_ke \\\n" -" -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n" -"\n" -" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n" -" -supported_group sm2p256v1 -psk_dhe_ke \\\n" -" -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n" -"\n" -" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n" -" -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n" -"\n" -" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n" -" -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n" -"\n" -"EarlyData (0-RTT)\n" -"\n" -" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n" -" -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK \\\n" -" -early_data\n" -"\n" -" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n" -" -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK \\\n" -" -early_data early_data.txt\n" -"\n" -"CertificateRequest\n" -"\n" -" sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n" -" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n" -" -cert_request -cacert sm2rootcacert.pem\n" -"\n" -" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert sm2rootcacert.pem \\\n" -" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n" -" -cert sm2certs.pem -key sm2signkey.pem -pass 1234\n" -"\n" -"CertificateRequest without CertificateVerify\n" -"\n" -" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert sm2rootcacert.pem \\\n" -" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3\n" +#include "tls13_help.h" "\n"; - - - int tls13_server_main(int argc , char **argv) { int ret = 1; char *prog = argv[0]; int port = 443; - char *certfile = NULL; - char *keyfile = NULL; - char *pass = NULL; - char *certfiles[4]; - char *keyfiles[sizeof(certfiles)/sizeof(certfiles[0])]; - char *passes[sizeof(certfiles)/sizeof(certfiles[0])]; size_t certfiles_cnt = 0; + char *keyfiles[sizeof(certfiles)/sizeof(certfiles[0])]; size_t keyfiles_cnt = 0; + char *passes[sizeof(certfiles)/sizeof(certfiles[0])]; size_t passes_cnt = 0; - - - int server_ciphers[] = { TLS_cipher_sm4_gcm_sm3, }; TLS_CTX ctx; TLS_CONNECT conn; - char buf[1600] = {0}; - size_t len = sizeof(buf); tls_socket_t sock; tls_socket_t conn_sock; struct sockaddr_in server_addr; struct sockaddr_in client_addr; + char buf[1600] = {0}; + size_t len = sizeof(buf); + + int cipher_suites[4]; + size_t cipher_suites_cnt = 0; + + + // NewSessionTicket int new_session_ticket = 0; char *ticket_key = NULL; uint8_t ticket_key_buf[16]; + // psk_key_exchange_modes int psk_ke = 0; int psk_dhe_ke = 0; - - // external psk + // pre_shared_key from external char *psk_identities[16]; size_t psk_identities_cnt = 0; char *psk_cipher_suites[16]; @@ -314,35 +97,35 @@ int tls13_server_main(int argc , char **argv) char *psk_keys[16]; size_t psk_keys_cnt = 0; - + // early_data int early_data = 0; int max_early_data_size = 0; - char *cipher_suite_name; - int cipher_suite; - int cipher_suites[4]; - size_t cipher_suites_cnt = 0; - - char *supported_group_name; - int supported_group; + // supported_groups int supported_groups[4]; size_t supported_groups_cnt = 0; - char *sig_alg_name; - int sig_alg; + // signature_algorithms int sig_algs[4]; size_t sig_algs_cnt = 0; + // KeyUpdate int key_update_seq_num = 0; + // CertificateRequest + int client_cert_optional = 0; + + // ChangeCipherSpec + int tls13_change_cipher_spec = 0; + size_t i; - - + // CertificateRequest int cert_request = 0; char *cacertfile = NULL; + int verify_depth = TLS_DEFAULT_VERIFY_DEPTH; argc--; argv++; @@ -360,44 +143,46 @@ int tls13_server_main(int argc , char **argv) } else if (!strcmp(*argv, "-port")) { if (--argc < 1) goto bad; port = atoi(*(++argv)); - } else if (!strcmp(*argv, "-cert")) { - if (--argc < 1) goto bad; - certfile = *(++argv); if (certfiles_cnt >= sizeof(certfiles)/sizeof(certfiles[0])) { - error_print(); + fprintf(stderr, "%s: too much -cert\n", prog); return -1; } - certfiles[certfiles_cnt++] = certfile; - + if (--argc < 1) goto bad; + certfiles[certfiles_cnt++] = *(++argv); } else if (!strcmp(*argv, "-key")) { - if (--argc < 1) goto bad; - keyfile = *(++argv); - if (keyfiles_cnt >= sizeof(keyfiles)/sizeof(keyfiles[0])) { - error_print(); + fprintf(stderr, "%s: too much -key\n", prog); return -1; } - keyfiles[keyfiles_cnt++] = keyfile; - - } else if (!strcmp(*argv, "-pass")) { if (--argc < 1) goto bad; - pass = *(++argv); - + keyfiles[keyfiles_cnt++] = *(++argv); + } else if (!strcmp(*argv, "-pass")) { if (passes_cnt >= sizeof(passes)/sizeof(passes[0])) { - error_print(); + fprintf(stderr, "%s: too much -pass\n", prog); return -1; } - passes[passes_cnt++] = pass; - + if (--argc < 1) goto bad; + passes[passes_cnt++] = *(++argv); } else if (!strcmp(*argv, "-cert_request")) { cert_request = 1; } else if (!strcmp(*argv, "-cacert")) { if (--argc < 1) goto bad; cacertfile = *(++argv); + } else if (!strcmp(*argv, "-verify_depth")) { + if (--argc < 1) goto bad; + verify_depth = atoi(*(++argv)); + if (verify_depth < 1) { + fprintf(stderr, "%s: invalid -verify_depth value '%d'\n", prog, verify_depth); + return -1; + } } else if (!strcmp(*argv, "-new_session_ticket")) { if (--argc < 1) goto bad; new_session_ticket = atoi(*(++argv)); + if (new_session_ticket < 0) { + fprintf(stderr, "%s: invalid -new_session_ticket value\n", prog); + return -1; + } } else if (!strcmp(*argv, "-ticket_key")) { if (--argc < 1) goto bad; ticket_key = *(++argv); @@ -432,45 +217,45 @@ int tls13_server_main(int argc , char **argv) if (--argc < 1) goto bad; max_early_data_size = atoi(*(++argv)); } else if (!strcmp(*argv, "-cipher_suite")) { + char *cipher_suite_name; + int cipher_suite; + if (cipher_suites_cnt >= sizeof(cipher_suites)/sizeof(cipher_suites[0])) { + fprintf(stderr, "%s: too much -cipher_suite\n", prog); + return -1; + } if (--argc < 1) goto bad; cipher_suite_name = *(++argv); if ((cipher_suite = tls_cipher_suite_from_name(cipher_suite_name)) == 0) { - error_print(); - fprintf(stderr, "%s: cipher suite '%s' not supported\n", prog, cipher_suite_name); - return -1; - } - if (cipher_suites_cnt >= sizeof(cipher_suites)/sizeof(cipher_suites[0])) { - error_print(); - fprintf(stderr, "%s: too much cipher suites\n", prog); + fprintf(stderr, "%s: -cipher suite value '%s' invalid\n", prog, cipher_suite_name); return -1; } cipher_suites[cipher_suites_cnt] = cipher_suite; cipher_suites_cnt++; } else if (!strcmp(*argv, "-supported_group")) { + char *supported_group_name; + int supported_group; + if (supported_groups_cnt >= sizeof(supported_groups)/sizeof(supported_groups[0])) { + fprintf(stderr, "%s: too much -supported_group\n", prog); + return -1; + } if (--argc < 1) goto bad; supported_group_name = *(++argv); if ((supported_group = tls_named_curve_from_name(supported_group_name)) == 0) { - error_print(); - fprintf(stderr, "%s: supported_group '%s' not supported\n", prog, supported_group_name); - return -1; - } - if (supported_groups_cnt >= sizeof(supported_groups)/sizeof(supported_groups[0])) { - error_print(); - fprintf(stderr, "%s: too much supported_group\n", prog); + fprintf(stderr, "%s: -supported_group value '%s' invalid\n", prog, supported_group_name); return -1; } supported_groups[supported_groups_cnt++] = supported_group; } else if (!strcmp(*argv, "-sig_alg")) { + char *sig_alg_name; + int sig_alg; + if (sig_algs_cnt >= sizeof(sig_algs)/sizeof(sig_algs[0])) { + fprintf(stderr, "%s: too much -sig_alg\n", prog); + return -1; + } if (--argc < 1) goto bad; sig_alg_name = *(++argv); if ((sig_alg = tls_signature_scheme_from_name(sig_alg_name)) == 0) { - error_print(); - fprintf(stderr, "%s: sig_alg '%s' not supported\n", prog, sig_alg_name); - return -1; - } - if (sig_algs_cnt >= sizeof(sig_algs)/sizeof(sig_algs[0])) { - error_print(); - fprintf(stderr, "%s: too much sig_algs\n", prog); + fprintf(stderr, "%s: -sig_alg value '%s' invalid\n", prog, sig_alg_name); return -1; } sig_algs[sig_algs_cnt++] = sig_alg; @@ -479,9 +264,13 @@ int tls13_server_main(int argc , char **argv) key_update_seq_num = atoi(*(++argv)); if (key_update_seq_num < 0) { error_print(); - fprintf(stderr, "%s: invalid '-key_update_seq_num' value\n", prog); + fprintf(stderr, "%s: invalid -key_update_seq_num value\n", prog); return -1; } + } else if (!strcmp(*argv, "-client_cert_optional")) { + client_cert_optional = 1; + } else if (!strcmp(*argv, "-tls13_change_cipher_spec")) { + tls13_change_cipher_spec = 1; } else { fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); return 1; @@ -493,17 +282,18 @@ bad: argv++; } + + // 不应该放在这里啊 if (certfiles_cnt != keyfiles_cnt || keyfiles_cnt != passes_cnt) { error_print(); return -1; } - /* if (!cipher_suites_cnt) { error_print(); goto end; } - */ + if (tls_socket_lib_init() != 1) { error_print(); @@ -513,6 +303,9 @@ bad: memset(&ctx, 0, sizeof(ctx)); memset(&conn, 0, sizeof(conn)); + + + if (tls_ctx_init(&ctx, TLS_protocol_tls13, TLS_server_mode) != 1) { error_print(); return -1; @@ -523,104 +316,119 @@ bad: goto end; } - // FIXME: 打印载入的证书信息 - for (i = 0; i < certfiles_cnt; i++) { - if (tls_ctx_add_certificate_chain_and_key(&ctx, certfiles[i], keyfiles[i], passes[i]) != 1) { - error_print(); - return -1; - } - } - + // supported_groups if (supported_groups_cnt > 0) { if (tls_ctx_set_supported_groups(&ctx, supported_groups, supported_groups_cnt) != 1) { error_print(); - return -1; + goto end; } } + // signature_algorithms if (sig_algs_cnt > 0) { if (tls_ctx_set_signature_algorithms(&ctx, sig_algs, sig_algs_cnt) != 1) { error_print(); - return -1; + goto end; } } + // Certificate + for (i = 0; i < certfiles_cnt; i++) { + if (tls_ctx_add_certificate_chain_and_key(&ctx, certfiles[i], keyfiles[i], passes[i]) != 1) { + error_print(); + goto end;; + } + } + + // CertificateRequest if (cert_request) { - if (!cacertfile) { - error_print(); - return -1; + fprintf(stderr, "%s: -cacert required by -cert_request\n", prog); + goto end; } - if (tls_ctx_set_ca_certificates(&ctx, cacertfile, TLS_DEFAULT_VERIFY_DEPTH) != 1) { + if (tls_ctx_set_ca_certificates(&ctx, cacertfile, verify_depth) != 1) { error_print(); - return -1; + goto end; } - - // 在发送CertificateRequest的时候,需要把CA的DN发送给客户端 - // 这里dn_names是在什么时候设置好的? - if (tls_ctx_enable_certificate_request(&ctx, 1) != 1) { error_print(); - return -1; + goto end; + } + if (client_cert_optional) { + if (tls13_ctx_enable_client_certificate_optional(&ctx, 1) != 1) { + error_print(); + goto end; + } } } + // psk_key_exchange_modes if (psk_ke || psk_dhe_ke) { if (tls13_ctx_set_psk_key_exchange_modes(&ctx, psk_ke, psk_dhe_ke) != 1) { error_print(); - return -1; + goto end; } } - if (new_session_ticket < 0) { - fprintf(stderr, "%s: '-ticket_key' is required by '-new_session_ticket'\n", prog); - return -1; - } + // NewSessionTicket if (new_session_ticket > 0) { - if (!ticket_key) { - error_print(); + size_t ticket_key_len; - return -1; + if (!ticket_key) { + fprintf(stderr, "%s: -ticket_key is required by -new_session_ticket\n", prog); + goto end; } + if (tls13_ctx_enable_new_session_ticket(&ctx, new_session_ticket) != 1) { error_print(); - return -1; + goto end; } - } - if (ticket_key) { - size_t ticket_key_len; if (strlen(ticket_key) != sizeof(ticket_key_buf) * 2) { error_print(); - return -1; + goto end; } if (hex_to_bytes(ticket_key, strlen(ticket_key), ticket_key_buf, &ticket_key_len) != 1) { error_print(); - return -1; + goto end; } if (tls13_ctx_set_session_ticket_key(&ctx, ticket_key_buf, ticket_key_len) != 1) { error_print(); - return -1; + goto end; } - tls13_enable_pre_shared_key(&conn, 1); - } - - if (early_data) { - ctx.early_data = 1; - } - - - if (max_early_data_size > 0) { - if (tls13_ctx_set_max_early_data_size(&ctx, max_early_data_size) != 1) { + if (tls13_enable_pre_shared_key(&conn, 1) != 1) { error_print(); - return -1; + goto end; } } + // early_data + if (early_data) { + if (tls13_ctx_enable_early_data(&ctx, 1) != 1) { + error_print(); + goto end; + } + if (max_early_data_size > 0) { + if (tls13_ctx_set_max_early_data_size(&ctx, max_early_data_size) != 1) { + error_print(); + goto end; + } + } + } + + // KeyUpdate if (key_update_seq_num > 0) { if (tls_ctx_set_key_update_seq_num_limit(&ctx, key_update_seq_num) != 1) { error_print(); - return -1; + goto end; + } + } + + // ChangeCipherSpec + if (tls13_change_cipher_spec) { + if (tls13_ctx_enable_change_cipher_spec(&ctx, 1) != 1) { + error_print(); + goto end; } } @@ -638,15 +446,13 @@ bad: if (tls13_init(&conn, &ctx) != 1) { error_print(); - return -1; + goto end; } puts("start listen ...\n"); tls_socket_listen(sock, 1); - - restart: //client_addrlen = sizeof(client_addr); @@ -658,9 +464,11 @@ restart: if (tls_set_socket(&conn, conn_sock) != 1) { error_print(); - return -1; + goto end; } + + // pre_shared_key from external if (psk_keys_cnt) { const uint32_t obfuscated_ticket_age = 0; size_t i; @@ -678,24 +486,24 @@ restart: if (!(psk_cipher_suite = tls_cipher_suite_from_name(psk_cipher_suites[i]))) { error_print(); - return -1; + goto end; } if (tls13_cipher_suite_get(psk_cipher_suite, &psk_cipher, &psk_digest) != 1) { error_print(); - return -1; + goto end; } if (strlen(psk_keys[i]) != psk_digest->digest_size * 2) { error_print(); - return -1; + goto end; } if (hex_to_bytes(psk_keys[i], strlen(psk_keys[i]), psk_key, &psk_key_len) != 1) { error_print(); - return -1; + goto end; } if (tls13_add_pre_shared_key(&conn, (uint8_t *)psk_identities[i], strlen(psk_identities[i]), psk_key, psk_key_len, psk_cipher_suite, obfuscated_ticket_age) != 1) { error_print(); - return -1; + goto end; } } @@ -704,7 +512,7 @@ restart: if (tls_do_handshake(&conn) != 1) { error_print(); - return -1; + goto end; } if (conn.early_data && conn.early_data_len) { @@ -716,10 +524,6 @@ restart: - // 如果客户端发送的数据比较长,会被切分为多个record - // 服务器在接收到record之后,必须做同步,就是每收到一个record必须返回一个record - // 也就是server必须有一个同步机制 - for (;;) { fd_set fds_recv;