diff --git a/include/gmssl/tls.h b/include/gmssl/tls.h index 2c6345eb..a635b202 100644 --- a/include/gmssl/tls.h +++ b/include/gmssl/tls.h @@ -107,6 +107,9 @@ int tls_cipher_suites_select(const uint8_t *client_ciphers, size_t client_cipher int tls_cipher_suite_in_list(int cipher, const int *list, size_t list_count); int tls_cipher_suite_support_protocol(int cipher, int protocol); +int tls_type_is_in_list(int cipher, const int *list, size_t list_count); + + typedef enum { TLS_compression_null = 0, TLS_compression_default = 1, @@ -274,7 +277,7 @@ typedef enum { const char *tls_named_curve_name(int named_curve); int tls_named_curve_oid(int named_curve); - +int tls_named_curve_from_oid(int oid); typedef enum { TLS_sig_rsa_pkcs1_sha1 = 0x0201, @@ -288,7 +291,7 @@ typedef enum { TLS_sig_rsa_pkcs1_sha512 = 0x0601, TLS_sig_ecdsa_secp521r1_sha512 = 0x0603, TLS_sig_rsa_pkcs1_sha512_legacy = 0x0620, - TLS_sig_sm2sig_sm3 = 0x0708, // GmSSLv2: 0x0707 + TLS_sig_sm2sig_sm3 = 0x0708, TLS_sig_rsa_pss_rsae_sha256 = 0x0804, TLS_sig_rsa_pss_rsae_sha384 = 0x0805, TLS_sig_rsa_pss_rsae_sha512 = 0x0806, @@ -303,7 +306,7 @@ typedef enum { } TLS_SIGNATURE_SCHEME; const char *tls_signature_scheme_name(int scheme); -int tls_signature_scheme_match_cipher_suite(int sig_alg, int cipher_suite); +int tls_signature_scheme_match_cipher_suite(int sig_alg, int cipher_suite); typedef enum { @@ -345,6 +348,7 @@ typedef enum { TLS_alert_internal_error = 80, TLS_alert_user_canceled = 90, TLS_alert_no_renegotiation = 100, + TLS_alert_missing_extension = 109, // 查以下RFC TLS_alert_unsupported_extension = 110, TLS_alert_unsupported_site2site = 200, TLS_alert_no_area = 201, @@ -442,6 +446,8 @@ typedef struct { //#define tls_handshake_data_length(p) +int tls_record_set_handshake_header(uint8_t *record, size_t *recordlen, + int type, int length); int tls_record_set_handshake(uint8_t *record, size_t *recordlen, int type, const uint8_t *data, size_t datalen); int tls_record_get_handshake(const uint8_t *record, @@ -483,22 +489,33 @@ int tls_process_client_ec_point_formats(const uint8_t *ext_data, size_t ext_data uint8_t **out, size_t *outlen); int tls_process_server_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen); + +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, uint8_t **out, size_t *outlen); int tls_process_client_supported_groups(const uint8_t *ext_data, size_t ext_datalen, uint8_t **out, size_t *outlen); int tls_process_server_supported_groups(const uint8_t *ext_data, size_t ext_datalen); +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); + + +// 这里有个问题,为什么这里面我们都不给出名字呢? +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); int tls_signature_algorithms_ext_to_bytes(const int *algs, size_t algs_cnt, uint8_t **out, size_t *outlen); int tls13_signature_algorithms_cert_ext_to_bytes(const int *algs, size_t algs_cnt, uint8_t **out, size_t *outlen); -int tls_process_client_signature_algorithms(const uint8_t *ext_data, size_t ext_datalen, - uint8_t **out, size_t *outlen); -int tls_process_server_signature_algors(const uint8_t *ext_data, size_t ext_datalen); +int tls_process_signature_algorithms(const uint8_t *ext_data, size_t ext_datalen, + const int *local_sig_algs, size_t local_sig_algs_cnt, + int *common_sig_algs, size_t *common_sig_algs_cnt, size_t max_cnt); + +/* int tls13_supported_versions_ext_to_bytes(int handshake_type, const int *protos, size_t protos_cnt, uint8_t **out, size_t *outlen); int tls13_process_client_supported_versions(const uint8_t *ext_data, size_t ext_datalen, @@ -517,6 +534,7 @@ int tls13_process_server_key_share(const uint8_t *ext_data, size_t ext_datalen, int tls13_certificate_authorities_ext_to_bytes(const uint8_t *ca_names, size_t ca_names_len, uint8_t **out, size_t *outlen); +*/ int tls_ext_from_bytes(int *type, const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen); int tls_process_client_exts(const uint8_t *exts, size_t extslen, uint8_t *out, size_t *outlen, size_t maxlen); @@ -694,19 +712,45 @@ enum { typedef struct { int protocol; + + int is_client; + int cipher_suites[TLS_MAX_CIPHER_SUITES_COUNT]; size_t cipher_suites_cnt; + uint8_t *cacerts; size_t cacertslen; uint8_t *certs; size_t certslen; + + // extensions + int supported_versions[4]; + size_t supported_versions_cnt; + + int supported_groups[32]; + size_t supported_groups_cnt; + + int signature_algorithms[2]; + size_t signature_algorithms_cnt; + + int protocols[4]; + size_t protocols_cnt; + + X509_KEY signkey; X509_KEY kenckey; int verify_depth; + // 这个应该是和服务器证书相关的 + const uint8_t *certificate_status; + size_t certificate_status_len; + + const uint8_t *signed_certificate_timestamp; + size_t signed_certificate_timestamp_len; + int quiet; } TLS_CTX; @@ -744,6 +788,7 @@ enum { TLS_state_handshake_init = 0, TLS_state_client_hello, TLS_state_server_hello, + TLS_state_encrypted_extensions, TLS_state_server_certificate, TLS_state_server_key_exchange, TLS_state_certificate_request, @@ -751,6 +796,7 @@ enum { TLS_state_client_certificate, TLS_state_client_key_exchange, TLS_state_certificate_verify, + TLS_state_client_certificate_verify, TLS_state_generate_keys, TLS_state_client_change_cipher_spec, TLS_state_client_finished, @@ -785,7 +831,8 @@ typedef struct { int cipher_suites[TLS_MAX_CIPHER_SUITES_COUNT]; size_t cipher_suites_cnt; int cipher_suite; - + const DIGEST *digest; + const BLOCK_CIPHER *cipher; tls_socket_t sock; @@ -796,10 +843,14 @@ typedef struct { uint8_t record[TLS_MAX_RECORD_SIZE]; size_t record_offset; // offset of processed record + size_t recordlen; + + + uint8_t plain_record[TLS_MAX_RECORD_SIZE]; + size_t plain_recordlen; int record_state; - size_t recordlen; uint8_t databuf[TLS_MAX_RECORD_SIZE]; uint8_t *data; @@ -819,9 +870,9 @@ typedef struct { X509_KEY server_enc_key; int verify_result; - uint8_t pre_master_secret[48]; // 是否可以重用master_secret作为pre_master_secret呢? - uint8_t master_secret[48]; - uint8_t key_block[96]; + + + SM3_HMAC_CTX client_write_mac_ctx; SM3_HMAC_CTX server_write_mac_ctx; @@ -840,7 +891,14 @@ typedef struct { // handshake state for state machine int state; + + + SM3_CTX sm3_ctx; + + DIGEST_CTX dgst_ctx; + + SM2_SIGN_CTX sign_ctx; TLS_CLIENT_VERIFY_CTX client_verify_ctx; uint8_t client_random[32]; @@ -861,14 +919,45 @@ typedef struct { uint16_t ecdh_named_curve; + + X509_KEY ecdh_keys[2]; + size_t ecdh_keys_cnt; + X509_KEY ecdh_key; + + int peer_group; uint8_t peer_ecdh_point[65]; size_t peer_ecdh_point_len; + + + // tls13 需要提前生成每一种曲线的密钥 + SM2_KEY sm2_ecdhe; + SECP256R1_KEY p256_ecdhe; + uint8_t peer_sm2_ecdhe[65]; + uint8_t peer_p256_ecdhe[65]; + int client_certificate_verify; // 是否验证客户端证书 int verify_depth; // 这个可能没有被设置 + const TLS_CTX *ctx; + + uint8_t pre_master_secret[48]; // 是否可以重用master_secret作为pre_master_secret呢? + uint8_t master_secret[48]; + uint8_t key_block[96]; + + uint8_t early_secret[32]; + uint8_t handshake_secret[32]; + uint8_t client_handshake_traffic_secret[32]; + uint8_t server_handshake_traffic_secret[32]; + uint8_t client_application_traffic_secret[32]; + uint8_t server_application_traffic_secret[32]; + + + int hello_retry_request; + + int key_exchange_group; } TLS_CONNECT; @@ -876,6 +965,9 @@ typedef struct { +int tls_send_record(TLS_CONNECT *conn); +int tls_recv_record(TLS_CONNECT *conn); + int tls_send_client_hello(TLS_CONNECT *conn); int tls_recv_client_hello(TLS_CONNECT *conn); @@ -1000,13 +1092,43 @@ int tls_encrypted_record_print(FILE *fp, const uint8_t *record, size_t recordle +// supported_groups +int tls13_client_supported_versions_ext_to_bytes(const int *versions, size_t versions_cnt, + uint8_t **out, size_t *outlen); +int tls13_process_client_supported_versions(const uint8_t *ext_data, size_t ext_datalen, + const int *server_versions, size_t server_versions_cnt, + int *common_versions, size_t *common_versions_cnt, size_t max_cnt); +int tls13_client_supported_versions_print(FILE *fp, int fmt, int ind, + const uint8_t *ext_data, size_t ext_datalen); +int tls13_server_supported_versions_ext_to_bytes(int selected_version, uint8_t **out, size_t *outlen); +int tls13_server_supported_versions_from_bytes(int *selected_version, const uint8_t *ext_data, size_t ext_datalen); +int tls13_process_server_supported_versions(const int *client_versions, size_t client_versions_cnt, + const uint8_t *server_ext_data, size_t server_ext_datalen, + int *selected_version); +int tls13_server_supported_versions_print(FILE *fp, int fmt, int ind, + const uint8_t *ext_data, size_t ext_datalen); +// key_share +int tls13_key_share_entry_to_bytes(const X509_KEY *key, uint8_t **out, size_t *outlen); +int tls13_key_share_entry_from_bytes(int *group, const uint8_t **key_exchange, size_t *key_exchange_len, + const uint8_t **in, size_t *inlen); + +int tls13_key_share_client_hello_ext_to_bytes(const X509_KEY *keys, size_t keys_cnt, uint8_t **out, size_t *outlen); +int tls13_process_key_share_client_hello(const uint8_t *ext_data, size_t ext_datalen, + const int *common_groups, size_t common_groups_cnt, + int *group, const uint8_t **key_exchange, size_t *key_exchange_len); +int tls13_key_share_client_hello_print(FILE *fp, int fmt, int ind, + const uint8_t *data, size_t datalen); + +int tls13_key_share_server_hello_ext_to_bytes(const X509_KEY *key, uint8_t **out, size_t *outlen); +int tls13_key_share_server_hello_from_bytes(int *group, const uint8_t **key_exchange, size_t *key_exchange_len, + const uint8_t *ext_data, size_t ext_datalen); +int tls13_key_share_server_hello_print(FILE *fp, int fmt, int ind, + const uint8_t *data, size_t datalen); - - - +int tls13_signature_algorithms_cert_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen); #ifdef __cplusplus diff --git a/include/gmssl/x509_key.h b/include/gmssl/x509_key.h index 03f00eb9..e947b8d9 100644 --- a/include/gmssl/x509_key.h +++ b/include/gmssl/x509_key.h @@ -186,7 +186,7 @@ typedef struct { /* algor: OID_sm2sign_with_sm3 - OID_ecdss_with_sha256 + OID_ecdsa_with_sha256 OID_lms_hashsig OID_hss_lms_hashsig OID_xmss_hashsig diff --git a/src/tlcp.c b/src/tlcp.c index 67b0ac0a..0e99f902 100644 --- a/src/tlcp.c +++ b/src/tlcp.c @@ -244,11 +244,14 @@ int _tlcp_do_connect(TLS_CONNECT *conn) error_print(); goto end; } + + /* if (tls_cipher_suite_in_list(cipher_suite, tlcp_ciphers, tlcp_ciphers_count) != 1) { tls_send_alert(conn, TLS_alert_handshake_failure); error_print(); goto end; } + */ if (exts) { error_print(); tls_send_alert(conn, TLS_alert_unexpected_message); diff --git a/src/tls.c b/src/tls.c index f4ae2ce4..509804af 100644 --- a/src/tls.c +++ b/src/tls.c @@ -630,6 +630,16 @@ int tls_record_set_handshake(uint8_t *record, size_t *recordlen, return 1; } +int tls_record_set_handshake_header(uint8_t *record, size_t *recordlen, + int type, int length) +{ + if (tls_record_set_handshake(record, recordlen, type, NULL, length) != 1) { + error_print(); + return -1; + } + return 1; +} + int tls_record_get_handshake(const uint8_t *record, int *type, const uint8_t **data, size_t *datalen) { @@ -893,6 +903,13 @@ int tls_record_set_handshake_server_hello(uint8_t *record, size_t *recordlen, return 1; } + +/* +如果报文的结构正确,但是数据不合法的时候,应该返回TLS_alert_illegal_parameter +例如服务器的选择不在ClientHello提供的列表中 +因此涉及到语义错误的,应该返回这个错误。 +如果语义我们不能理解,但是格式正确,那么应该忽略 +*/ int tls_record_get_handshake_server_hello(const uint8_t *record, int *protocol, const uint8_t **random, const uint8_t **session_id, size_t *session_id_len, int *cipher_suite, const uint8_t **exts, size_t *exts_len) @@ -915,7 +932,7 @@ int tls_record_get_handshake_server_hello(const uint8_t *record, } if (type != TLS_handshake_server_hello) { error_print(); - return -1; + return 0; } if (tls_uint16_from_bytes(&ver, &p, &len) != 1 || tls_array_from_bytes(random, 32, &p, &len) != 1 @@ -951,6 +968,7 @@ int tls_record_get_handshake_server_hello(const uint8_t *record, } *cipher_suite = cipher; + // 这个值应该返回给上一层,这样上面才能够返回正确的错误值 if (comp_meth != TLS_compression_null) { error_print(); return -1; @@ -1056,6 +1074,13 @@ int tls_record_get_handshake_certificate(const uint8_t *record, uint8_t *certs, return 1; } +/* +struct { + ClientCertificateType certificate_types<1..2^8-1>; + SignatureAndHashAlgorithm supported_signature_algorithms<2^16-1>; // 可能缺少这个参数 + DistinguishedName certificate_authorities<0..2^16-1>; +} CertificateRequest; +*/ int tls_record_set_handshake_certificate_request(uint8_t *record, size_t *recordlen, const uint8_t *cert_types, size_t cert_types_len, const uint8_t *ca_names, size_t ca_names_len) @@ -1291,6 +1316,7 @@ 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; @@ -1440,13 +1466,9 @@ int tls_record_get_application_data(uint8_t *record, return 1; } -int tls_cipher_suite_in_list(int cipher, const int *list, size_t list_count) +int tls_type_is_in_list(int cipher, const int *list, size_t list_count) { size_t i; - if (!list || !list_count) { - error_print(); - return -1; - } for (i = 0; i < list_count; i++) { if (cipher == list[i]) { return 1; @@ -1455,6 +1477,15 @@ int tls_cipher_suite_in_list(int cipher, const int *list, size_t list_count) return 0; } + + + + + + + + + static const int tlcp_ciphers[] = { TLS_cipher_ecc_sm4_cbc_sm3, TLS_cipher_ecc_sm4_gcm_sm3, @@ -1496,10 +1527,13 @@ int tls_cipher_suite_support_protocol(int cipher, int protocol) return -1; } + /* + if (!tls_cipher_suite_in_list(cipher, ciphers, ciphers_cnt)) { error_print(); return 0; } + */ return 1; } @@ -2082,6 +2116,8 @@ void tls_client_verify_cleanup(TLS_CLIENT_VERIFY_CTX *ctx) } } + +// 这个函数不对啊,应该以服务器优先来选择参数 int tls_cipher_suites_select(const uint8_t *client_ciphers, size_t client_ciphers_len, const int *server_ciphers, size_t server_ciphers_cnt, int *selected_cipher) @@ -2121,8 +2157,118 @@ void tls_ctx_cleanup(TLS_CTX *ctx) } } + + + + +int tls_ctx_set_supported_versions(TLS_CTX *ctx, const int *versions, size_t versions_cnt) +{ + size_t i; + + if (!ctx || !versions || !versions_cnt) { + error_print(); + return -1; + } + if (versions_cnt > sizeof(ctx->supported_versions)/sizeof(ctx->supported_versions[0])) { + error_print(); + return -1; + } + for (i = 0; i < versions_cnt; i++) { + switch (versions[i]) { + case TLS_protocol_tls13: + case TLS_protocol_tls12: + case TLS_protocol_tlcp: + break; + default: + error_print(); + return -1; + } + ctx->supported_versions[i] = versions[i]; + } + ctx->supported_versions_cnt = versions_cnt; + return 1; +} + +int tls_ctx_set_supported_groups(TLS_CTX *ctx, const int *groups, size_t groups_cnt) +{ + size_t i; + + if (!ctx || !groups || !groups_cnt) { + error_print(); + return -1; + } + if (groups_cnt > sizeof(ctx->supported_groups)/sizeof(ctx->supported_groups[0])) { + error_print(); + return -1; + } + for (i = 0; i < groups_cnt; i++) { + switch (groups[i]) { + case TLS_curve_sm2p256v1: + case TLS_curve_secp256r1: + break; + default: + error_print(); + return -1; + } + ctx->supported_groups[i] = groups[i]; + } + ctx->supported_groups_cnt = groups_cnt; + return 1; +} + +int tls_ctx_set_signature_algorithms(TLS_CTX *ctx, const int *sig_algs, size_t sig_algs_cnt) +{ + size_t i; + + if (!ctx || !sig_algs || !sig_algs_cnt) { + error_print(); + return -1; + } + if (sig_algs_cnt > sizeof(ctx->signature_algorithms)/sizeof(ctx->signature_algorithms[0])) { + error_print(); + return -1; + } + for (i = 0; i < sig_algs_cnt; i++) { + switch (sig_algs[i]) { + case TLS_sig_sm2sig_sm3: + case TLS_sig_ecdsa_secp256r1_sha256: + break; + default: + error_print(); + return -1; + } + ctx->signature_algorithms[i] = sig_algs[i]; + } + ctx->signature_algorithms_cnt = sig_algs_cnt; + return 1; +} + + + int tls_ctx_init(TLS_CTX *ctx, int protocol, int is_client) { + + + const int supported_versions[] = { + TLS_protocol_tls13, + TLS_protocol_tls12, + TLS_protocol_tlcp, + }; + size_t supported_versions_cnt = sizeof(supported_versions)/sizeof(supported_versions[0]); + + const int supported_groups[] = { + TLS_curve_sm2p256v1, + TLS_curve_secp256r1, + }; + size_t supported_groups_cnt = sizeof(supported_groups)/sizeof(supported_groups[0]); + + const int signature_algorithms[] = { + TLS_sig_sm2sig_sm3, + TLS_sig_ecdsa_secp256r1_sha256, + }; + size_t signature_algorithms_cnt = sizeof(signature_algorithms)/sizeof(signature_algorithms[0]); + + if (!ctx) { error_print(); return -1; @@ -2142,10 +2288,22 @@ int tls_ctx_init(TLS_CTX *ctx, int protocol, int is_client) ctx->is_client = is_client ? 1 : 0; + if (tls_ctx_set_supported_versions(ctx, supported_versions, supported_versions_cnt) != 1 + || tls_ctx_set_supported_groups(ctx, supported_groups, supported_groups_cnt) != 1 + || tls_ctx_set_signature_algorithms(ctx, signature_algorithms, signature_algorithms_cnt) != 1) { + error_print(); + return -1; + } + + + ctx->verify_depth = 5; return 1; } + + + int tls_ctx_set_cipher_suites(TLS_CTX *ctx, const int *cipher_suites, size_t cipher_suites_cnt) { size_t i; @@ -2407,6 +2565,8 @@ int tls_init(TLS_CONNECT *conn, const TLS_CTX *ctx) conn->verify_depth = ctx->verify_depth; + conn->ctx = ctx; + return 1; } diff --git a/src/tls12.c b/src/tls12.c index cb957900..b508faff 100644 --- a/src/tls12.c +++ b/src/tls12.c @@ -1,4 +1,4 @@ -/* +/* * Copyright 2014-2026 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may @@ -197,8 +197,6 @@ int tls_named_curve_from_oid(int oid) - - // 这个是必选的 const int ec_point_formats[] = { TLS_point_uncompressed }; size_t ec_point_formats_cnt = sizeof(ec_point_formats)/sizeof(ec_point_formats[0]); @@ -352,6 +350,8 @@ int tls_handshake_init(TLS_CONNECT *conn) { sm3_init(&conn->sm3_ctx); + digest_init(&conn->dgst_ctx, DIGEST_sm3()); + if (conn->client_certs_len) { //sm2_sign_init(&conn->sign_ctx, &conn->sign_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH); @@ -476,6 +476,16 @@ int tlcp_send_client_hello(TLS_CONNECT *conn) return 1; } + + + + + + + + + + int tlcp_recv_client_hello(TLS_CONNECT *conn) { int ret; @@ -493,7 +503,7 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn) const uint8_t *client_exts; size_t client_exts_len; - sm3_init(&conn->sm3_ctx); + //sm3_init(&conn->sm3_ctx); // 服务器端如果设置了CA @@ -785,11 +795,14 @@ int tls_recv_server_hello(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_protocol_version); return -1; } + + /* if (tls_cipher_suite_in_list(cipher_suite, conn->cipher_suites, conn->cipher_suites_cnt) != 1) { error_print(); tls_send_alert(conn, TLS_alert_handshake_failure); return -1; } + */ /* 对于扩展的处理 @@ -2402,6 +2415,9 @@ int tls_recv_server_finished(TLS_CONNECT *conn) Application Data <-------> Application Data + + + */ int tls12_do_client_handshake(TLS_CONNECT *conn) @@ -2671,6 +2687,9 @@ int tls12_do_connect(TLS_CONNECT *conn) conn->state = TLS_state_client_hello; sm3_init(&conn->sm3_ctx); + + digest_init(&conn->dgst_ctx, DIGEST_sm3()); + while (1) { ret = tls12_client_handshake(conn); @@ -2707,6 +2726,7 @@ int tls12_do_accept(TLS_CONNECT *conn) conn->state = TLS_state_client_hello; sm3_init(&conn->sm3_ctx); + digest_init(&conn->dgst_ctx, DIGEST_sm3()); while (1) { diff --git a/src/tls13.c b/src/tls13.c index bf5a3d5e..3705fefe 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -34,7 +34,41 @@ static int tls13_client_hello_exts[] = { TLS_extension_padding, }; -// FIXME: remove block_cipher.h +#define TLS_state_hello_retry_request 111111 +#define TLS_state_client_hello_again 12222 + +int tls13_cipher_suite_get(int cipher_suite, const BLOCK_CIPHER **cipher, const DIGEST **digest) +{ + switch (cipher_suite) { + case TLS_cipher_sm4_gcm_sm3: + *digest = DIGEST_sm3(); + *cipher = BLOCK_CIPHER_sm4(); + break; +#if defined(ENABLE_AES) && defined(ENABLE_SHA2) + case TLS_cipher_aes_128_gcm_sha256: + *digest = DIGEST_sha256(); + *cipher = BLOCK_CIPHER_aes128(); + break; +#endif + default: + error_print(); + return -1; + } + return 1; +} + + +int tls13_padding_len_rand(size_t *padding_len) +{ + uint8_t val; + rand_bytes(&val, 1); + *padding_len = val % 128; + return 1; +} + + + + int gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen, const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, uint8_t *out, size_t taglen, uint8_t *tag) @@ -44,6 +78,7 @@ int gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen, error_print(); return -1; } +// 避免在tls13.c中引入宏 #ifdef ENABLE_AES } else if (key->cipher == BLOCK_CIPHER_aes128()) { if (aes_gcm_encrypt(&(key->u.aes_key), iv, ivlen, aad, aadlen, in, inlen, out, taglen, tag) != 1) { @@ -81,7 +116,6 @@ int gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen, return 1; } - /* struct { opaque content[TLSPlaintext.length]; @@ -191,6 +225,8 @@ int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], return 1; } +// TODO: 将这个函数改为协议版本号无关的,能够支持不同的协议,主要是让TLS 1.2和TLCP可以支持GCM + // TODO: check this func again int tls13_record_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], const uint8_t seq_num[8], const uint8_t *record, size_t recordlen, size_t padding_len, @@ -271,7 +307,7 @@ int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *s recordlen += 5; tls_record_send(record, recordlen, conn->sock); - tls_record_trace(stderr, record, tls_record_length(record), 0, 0); + //tls_record_trace(stderr, record, tls_record_length(record), 0, 0); tls_seq_num_incr(seq_num); @@ -280,56 +316,6 @@ int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *s return 1; } -/* -int tls13_recv(TLS_CONNECT *conn, uint8_t *data, size_t *datalen) -{ - int record_type; - uint8_t *record = conn->record; - size_t recordlen; - const BLOCK_CIPHER_KEY *key; - const uint8_t *iv; - uint8_t *seq_num; - - - tls_trace("recv {ApplicationData}\n"); - - if (conn->is_client) { - key = &conn->server_write_key; - iv = conn->server_write_iv; - seq_num = conn->server_seq_num; - } else { - key = &conn->client_write_key; - iv = conn->client_write_iv; - seq_num = conn->client_seq_num; - } - - if (tls_record_recv(record, &recordlen, conn->sock) != 1) { - error_print(); - return -1; - } - if (record[0] != TLS_record_application_data) { - error_print(); - return -1; - } - - if (tls13_gcm_decrypt(key, iv, - seq_num, record + 5, recordlen - 5, - &record_type, data, datalen) != 1) { - error_print(); - return -1; - } - - tls_record_trace(stderr, record, tls_record_length(record), 0, 0); - tls_seq_num_incr(seq_num); - - if (record_type != TLS_record_application_data) { - error_print(); - return -1; - } - return 1; -} -*/ - int tls13_do_recv(TLS_CONNECT *conn) { int ret; @@ -368,8 +354,8 @@ int tls13_do_recv(TLS_CONNECT *conn) tls_seq_num_incr(seq_num); tls_record_set_data(record, conn->data, conn->datalen); - tls_trace("decrypt ApplicationData\n"); - tls_record_trace(stderr, record, tls_record_length(record), 0, 0); + //tls_trace("decrypt ApplicationData\n"); + //tls_record_trace(stderr, record, tls_record_length(record), 0, 0); if (record_type != TLS_record_application_data) { @@ -467,6 +453,7 @@ static const uint8_t TLS13_server_context_str_and_zero[] = "TLS 1.3, server Cert static size_t TLS13_client_context_str_and_zero_size = sizeof(TLS13_client_context_str_and_zero); static size_t TLS13_server_context_str_and_zero_size = sizeof(TLS13_server_context_str_and_zero); +// 这个函数需要改为支持X509_KEY的版本 int tls13_sign_certificate_verify(int tls_mode, const SM2_KEY *key, const char *signer_id, size_t signer_id_len, const DIGEST_CTX *tbs_dgst_ctx, @@ -509,6 +496,7 @@ int tls13_sign_certificate_verify(int tls_mode, return 1; } +//同上 int tls13_verify_certificate_verify(int tls_mode, const X509_KEY *public_key, const char *signer_id, size_t signer_id_len, const DIGEST_CTX *tbs_dgst_ctx, const uint8_t *sig, size_t siglen) @@ -598,319 +586,635 @@ int tls13_compute_verify_data(const uint8_t *handshake_traffic_secret, return 1; } -/* -Handshakes -*/ -int tls13_client_hello_exts_set(uint8_t *exts, size_t *extslen, size_t maxlen, - const SM2_Z256_POINT *client_ecdhe_public) + + + + + + + + + + + + + + + + + + + + + + + + + +// extensions + +int tls_ext_to_bytes(int ext_type, const uint8_t *ext_data, size_t ext_datalen, + uint8_t **out, size_t *outlen) { - int protocols[] = { TLS_protocol_tls13 }; - int supported_groups[] = { TLS_curve_sm2p256v1 }; - int sig_algs[] = { TLS_sig_sm2sig_sm3 }; - size_t protocols_cnt = sizeof(protocols)/sizeof(int); - size_t supported_groups_cnt = sizeof(supported_groups)/sizeof(int); - size_t sig_algs_cnt = sizeof(sig_algs)/sizeof(int); - - - if (!exts || !extslen || !client_ecdhe_public) { - error_print(); - return -1; - } - - *extslen = 0; - if (tls13_supported_versions_ext_to_bytes(TLS_client_mode, protocols, protocols_cnt, NULL, extslen) != 1 - || tls_supported_groups_ext_to_bytes(supported_groups, supported_groups_cnt, NULL, extslen) != 1 - || tls_signature_algorithms_ext_to_bytes(sig_algs, sig_algs_cnt, NULL, extslen) != 1 - || tls13_client_key_share_ext_to_bytes(client_ecdhe_public, NULL, extslen) != 1) { - error_print(); - return -1; - } - if (*extslen > maxlen) { - error_print(); - return -1; - } - *extslen = 0; - tls13_supported_versions_ext_to_bytes(TLS_client_mode, protocols, protocols_cnt, &exts, extslen); - tls_supported_groups_ext_to_bytes(supported_groups, supported_groups_cnt, &exts, extslen); - tls_signature_algorithms_ext_to_bytes(sig_algs, sig_algs_cnt, &exts, extslen); - tls13_client_key_share_ext_to_bytes(client_ecdhe_public, &exts, extslen); + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16array_to_bytes(ext_data, ext_datalen, out, outlen); return 1; } -int tls13_process_client_hello_exts(const uint8_t *exts, size_t extslen, - const SM2_KEY *server_ecdhe_key, SM2_KEY *client_ecdhe_public, - uint8_t *server_exts, size_t *server_exts_len, size_t server_exts_maxlen) -{ - size_t len = 0; - *server_exts_len = 0; - while (extslen) { - uint16_t ext_type; - const uint8_t *ext_data; - size_t ext_datalen; - - if (tls_uint16_from_bytes(&ext_type, &exts, &extslen) != 1 - || tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen) != 1) { - error_print(); - return -1; - } - - switch (ext_type) { - /* - // tls13_process_client_hello_exts API should be fixed, output some exts to server_exts中 - case TLS_extension_supported_groups: // should be in EE - if (tls_process_client_supported_groups(ext_data, ext_datalen, NULL, &len) != 1 - || len > server_exts_maxlen) { - error_print(); - return -1; - } - tls_process_client_supported_groups(ext_data, ext_datalen, &server_exts, server_exts_len); - break; - case TLS_extension_signature_algorithms: // client notify, server no need to response - if (tls_process_client_signature_algorithms(ext_data, ext_datalen, NULL, &len) != 1 - || len > server_exts_maxlen) { - error_print(); - return -1; - } - tls_process_client_signature_algorithms(ext_data, ext_datalen, &server_exts, server_exts_len); - break; - */ - case TLS_extension_supported_versions: - if (tls13_process_client_supported_versions(ext_data, ext_datalen, NULL, &len) != 1 - || len > server_exts_maxlen) { - error_print(); - return -1; - } - tls13_process_client_supported_versions(ext_data, ext_datalen, &server_exts, server_exts_len); - break; - case TLS_extension_key_share: - if (tls13_process_client_key_share(ext_data, ext_datalen, server_ecdhe_key, client_ecdhe_public, &server_exts, server_exts_len) != 1 - || len > server_exts_maxlen) { - error_print(); - return -1; - } - break; - - default: - ; // server ignore unkonwn extensions - } - } - - return 1; -} - -int tls_client_key_shares_from_bytes(SM2_Z256_POINT *sm2_point, const uint8_t **in, size_t *inlen) -{ - const uint8_t *key_shares; - size_t key_shares_len; - - tls_uint16array_from_bytes(&key_shares, &key_shares_len, in, inlen); - - while (key_shares_len) { - uint16_t group; - const uint8_t *key_exch; - size_t key_exch_len; - - tls_uint16_from_bytes(&group, &key_shares, &key_shares_len); - tls_uint16array_from_bytes(&key_exch, &key_exch_len, &key_shares, &key_shares_len); - - if (key_exch_len != 65) { - error_print(); - return -1; - } - - switch (group) { - case TLS_curve_sm2p256v1: - sm2_z256_point_from_octets(sm2_point, key_exch, key_exch_len); - break; - default: - error_print(); - return -1; - } - } - - return 1; -} - -// FIXME: should be a process function -int tls13_server_hello_extensions_get(const uint8_t *exts, size_t extslen, SM2_KEY *sm2_key) -{ - uint16_t version; - while (extslen) { - uint16_t ext_type; - const uint8_t *ext_data; - size_t ext_datalen; - - tls_uint16_from_bytes(&ext_type, &exts, &extslen); - tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen); - - switch (ext_type) { - case TLS_extension_supported_versions: - if (tls_uint16_from_bytes(&version, &ext_data, &ext_datalen) != 1 - || ext_datalen > 0) { - error_print(); - return -1; - } - if (version != TLS_protocol_tls13) { - error_print(); - return -1; - } - break; - case TLS_extension_key_share: - memset(sm2_key, 0, sizeof(SM2_KEY)); - if (tls13_process_server_key_share(ext_data, ext_datalen, &sm2_key->public_key) != 1) { - error_print(); - return -1; - } - break; - //default: - // FIXME: not all exts handled - //error_print(); - //return -1; - } - } - return 1; -} /* struct { - Extension extensions<0..2^16-1>; -} EncryptedExtensions; + ProtocolVersion versions<2..254>; +} SupportedVersions; -- in ClientHello */ -static int tls13_encrypted_exts[] = { - TLS_extension_server_name, - TLS_extension_max_fragment_length, - TLS_extension_supported_groups, - TLS_extension_use_srtp, - TLS_extension_heartbeat, - TLS_extension_application_layer_protocol_negotiation, - TLS_extension_client_certificate_type, - TLS_extension_server_certificate_type, - TLS_extension_early_data, -}; - -int tls13_encrypted_extensions_print(FILE *fp, int fmt, int ind, const uint8_t *data, size_t datalen) +int tls13_client_supported_versions_ext_to_bytes(const int *versions, size_t versions_cnt, + uint8_t **out, size_t *outlen) { - const uint8_t *exts; - size_t extslen; + uint16_t ext_type = TLS_extension_supported_versions; + size_t ext_datalen; + size_t versions_len; + size_t i; - format_print(fp, fmt, ind, "EncryptedExtensions\n"); + if (!versions || !versions_cnt || !outlen) { + error_print(); + return -1; + } + if (versions_cnt > 254/2) { + error_print(); + return -1; + } + for (i = 0; i < versions_cnt; i++) { + if (!tls_protocol_name(versions[i])) { + error_print(); + return -1; + } + } + versions_len = tls_uint16_size() * versions_cnt; + ext_datalen = tls_uint8_size() + versions_len; + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); + tls_uint8_to_bytes((uint8_t)versions_len, out, outlen); + for (i = 0; i < versions_cnt; i++) { + tls_uint16_to_bytes((uint16_t)versions[i], out, outlen); + } + return 1; +} + +int tls13_process_client_supported_versions(const uint8_t *ext_data, size_t ext_datalen, + const int *server_versions, size_t server_versions_cnt, + int *common_versions, size_t *common_versions_cnt, size_t max_cnt) +{ + const uint8_t *versions; + size_t versions_len; + const uint8_t *cp; + size_t len; + uint16_t version; + size_t i, j = 0; + + if (tls_uint8array_from_bytes(&versions, &versions_len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + if (versions_len < 2 || versions_len > 254) { + error_print(); + return -1; + } + + cp = versions; + len = versions_len; + while (len) { + if (tls_uint16_from_bytes(&version, &cp, &len) != 1) { + error_print(); + return -1; + } + if (!tls_protocol_name(version)) { + error_print(); + return -1; + } + if (version == server_versions[0] && j < max_cnt) { + common_versions[j++] = version; + } + } + for (i = 1; i < server_versions_cnt && j < max_cnt; i++) { + cp = versions; + len = versions_len; + while (len) { + tls_uint16_from_bytes(&version, &cp, &len); + if (version == server_versions[i]) { + common_versions[j++] = version; + break; + } + } + } + *common_versions_cnt = j; + if (*common_versions_cnt == 0) { + error_print(); + return 0; + } + return 1; +} + +int tls13_client_supported_versions_print(FILE *fp, int fmt, int ind, + const uint8_t *ext_data, size_t ext_datalen) +{ + const uint8_t *versions; + size_t versions_len; + + format_print(fp, fmt, ind, "versions\n"); ind += 4; - if (tls_uint16array_from_bytes(&exts, &extslen, &data, &datalen) != 1) { + if (tls_uint8array_from_bytes(&versions, &versions_len, &ext_data, &ext_datalen) != 1) { error_print(); return -1; } - if (exts) { - tls13_extensions_print(fp, fmt, ind, TLS_handshake_encrypted_extensions, exts, extslen); + if (versions_len < 2 || versions_len > 254) { + error_print(); + return -1; } - if (tls_length_is_zero(datalen) != 1) { + while (versions_len) { + uint16_t version; + if (tls_uint16_from_bytes(&version, &versions, &versions_len) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "%s (0x%04x)\n", tls_protocol_name(version), version); + } + if (ext_datalen) { error_print(); return -1; } return 1; } -int tls13_record_set_handshake_encrypted_extensions(uint8_t *record, size_t *recordlen) -{ - int type = TLS_handshake_encrypted_extensions; - uint8_t *p = record + 5 + 4; - size_t len = 0; - uint8_t exts[128]; - size_t extslen = 0; - uint8_t *pexts = exts; - const int supported_groups[] = { TLS_curve_sm2p256v1 }; - - tls_supported_groups_ext_to_bytes(supported_groups, sizeof(supported_groups)/sizeof(int), &pexts, &extslen); - - tls_uint16array_to_bytes(exts, extslen, &p, &len); - tls_record_set_handshake(record, recordlen, type, NULL, len); - - return 1; -} - -int tls13_record_get_handshake_encrypted_extensions(const uint8_t *record) -{ - int type; - const uint8_t *p; - size_t len; - const uint8_t *exts_data; - size_t exts_datalen; - - if (tls_record_get_handshake(record, &type, &p, &len) != 1) { - error_print(); - return -1; - } - if (tls_uint16array_from_bytes(&exts_data, &exts_datalen, &p, &len) != 1) { - error_print(); - return -1; - } - // 当前实现不需要在EncryptedExtensions提供扩展 - if (exts_datalen) { - // FIXME: 实际上supported_groups是放在这里的,应该加以处理 - //error_print(); - //return -1; - } - return 1; -} - - -/* - ClientHello.Extensions.signature_algorithms 列出客户端支持的签名+哈希算法 - ServerHello.Extensions.supported_groups 决定了服务器的公钥类型, - 因此也决定了服务器的签名算法 - ServerHello.cipher_suite决定了哈希函数 -*/ /* struct { - SignatureScheme algorithm; - opaque signature<0..2^16-1>; -} CertificateVerify; - -注意:TLS 1.2中只有RAW signature, 也就是没有经过uint16array封装的,这其实不太符合TLS的设计逻辑 + ProtocolVersion selected_version; +} SupportedVersions; // in ServerHello and HelloRetryRequest */ -int tls13_record_set_handshake_certificate_verify(uint8_t *record, size_t *recordlen, - int sign_algor, const uint8_t *sig, size_t siglen) +int tls13_server_supported_versions_ext_to_bytes(int selected_version, uint8_t **out, size_t *outlen) { - int type = TLS_handshake_certificate_verify; - uint8_t *p = record + 5 + 4; + uint16_t ext_type = TLS_extension_supported_versions; + size_t ext_datalen; + size_t i; + + if (!outlen) { + error_print(); + return -1; + } + if (!tls_protocol_name(selected_version)) { + error_print(); + return -1; + } + ext_datalen = tls_uint16_size(); + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); + tls_uint16_to_bytes(selected_version, out, outlen); + return 1; +} + +// 这个函数可能用不上 +int tls13_server_supported_versions_from_bytes(int *selected_version, const uint8_t *ext_data, size_t ext_datalen) +{ + uint16_t version; + if (tls_uint16_from_bytes(&version, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + if (!tls_protocol_name(version)) { + error_print(); + return -1; + } + *selected_version = version; + return 1; +} + +int tls13_server_supported_versions_print(FILE *fp, int fmt, int ind, + const uint8_t *ext_data, size_t ext_datalen) +{ + uint16_t version; + + if (tls_uint16_from_bytes(&version, &ext_data, &ext_datalen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "selected_version: %s (0x%04x)\n", tls_protocol_name(version), version); + if (ext_datalen) { + error_print(); + return -1; + } + return 1; +} + +int tls13_process_server_supported_versions(const int *client_versions, size_t client_versions_cnt, + const uint8_t *server_ext_data, size_t server_ext_datalen, + int *selected_version) +{ + uint16_t version; + size_t i; + + if (tls_uint16_from_bytes(&version, &server_ext_data, &server_ext_datalen) != 1 + || tls_length_is_zero(server_ext_datalen) != 1) { + error_print(); + return -1; + } + for (i = 0; i < client_versions_cnt; i++) { + if (version == client_versions[i]) { + *selected_version = version; + return 1; + } + } + error_print(); + return -1; +} + +/* +struct { + NamedGroup group; + opaque key_exchange<1..2^16-1>; +} KeyShareEntry; +*/ +int tls13_key_share_entry_to_bytes(const X509_KEY *key, uint8_t **out, size_t *outlen) +{ + uint16_t group; + uint8_t key_exchange[65]; + + if (!key || !outlen) { + error_print(); + return -1; + } + if (key->algor != OID_ec_public_key) { + error_print(); + return -1; + } + if (!(group = tls_named_curve_from_oid(key->algor_param))) { + error_print(); + return -1; + } + if (out && *out) { + uint8_t *p = key_exchange; + size_t len = 0; + if (x509_public_key_to_bytes(key, &p, &len) != 1) { + error_print(); + return -1; + } + if (len != 65) { + error_print(); + return -1; + } + } + tls_uint16_to_bytes(group, out, outlen); + tls_uint16array_to_bytes(key_exchange, 65, out, outlen); + return 1; +} + +int tls13_key_share_entry_from_bytes(int *group, const uint8_t **key_exchange, size_t *key_exchange_len, + const uint8_t **in, size_t *inlen) +{ + uint16_t named_curve; + + if (tls_uint16_from_bytes(&named_curve, in, inlen) != 1 + || tls_uint16array_from_bytes(key_exchange, key_exchange_len, in, inlen) != 1) { + error_print(); + return -1; + } + *group = named_curve; + if (!tls_named_curve_name(named_curve)) { + error_print(); + return -1; + } + if (*key_exchange_len != 65) { + error_print(); + return -1; + } + return 1; +} + +/* +struct { + KeyShareEntry client_shares<0..2^16-1>; +} KeyShareClientHello; +*/ +int tls13_key_share_client_hello_ext_to_bytes(const X509_KEY *keys, size_t keys_cnt, uint8_t **out, size_t *outlen) +{ + uint16_t ext_type = TLS_extension_key_share; + size_t ext_datalen = 0; + size_t client_shares_len = 0; + size_t i; + + for (i = 0; i < keys_cnt; i++) { + if (tls13_key_share_entry_to_bytes(&keys[i], NULL, &client_shares_len) != 1) { + error_print(); + return -1; + } + } + ext_datalen = 2 + client_shares_len; + + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); + tls_uint16_to_bytes((uint16_t)client_shares_len, out, outlen); + for (i = 0; i < keys_cnt; i++) { + tls13_key_share_entry_to_bytes(&keys[i], out, outlen); + } + return 1; +} + +int tls13_process_key_share_client_hello(const uint8_t *ext_data, size_t ext_datalen, + const int *common_groups, size_t common_groups_cnt, + int *group, const uint8_t **key_exchange, size_t *key_exchange_len) +{ + int ret = 0; + const uint8_t *client_shares; + size_t client_shares_len; + const uint8_t *cp; + size_t len; + int curve; + const uint8_t *point; + size_t pointlen; + size_t i; + + if (tls_uint16array_from_bytes(&client_shares, &client_shares_len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + + cp = client_shares; + len = client_shares_len; + while (len) { + if (tls13_key_share_entry_from_bytes(&curve, &point, &pointlen, &cp, &len) != 1) { + error_print(); + return -1; + } + if (curve == common_groups[0]) { + *group = curve; + *key_exchange = point; + *key_exchange_len = pointlen; + ret = 1; + } + } + if (ret == 1) { + return 1; + } + + for (i = 1; i < common_groups_cnt; i++) { + cp = client_shares; + len = client_shares_len; + while (len) { + tls13_key_share_entry_from_bytes(group, key_exchange, key_exchange_len, &cp, &len); + if (curve == common_groups[i]) { + *group = curve; + *key_exchange = point; + *key_exchange_len = pointlen; + return 1; + } + } + } + + error_print(); + return 0; +} + +int tls13_key_share_client_hello_print(FILE *fp, int fmt, int ind, + const uint8_t *data, size_t datalen) +{ + const uint8_t *client_shares; + size_t client_shares_len; + + format_print(fp, fmt, ind, "client_shares\n"); + ind += 4; + if (tls_uint16array_from_bytes(&client_shares, &client_shares_len, &data, &datalen) != 1) { + error_print(); + return -1; + } + while (client_shares_len) { + uint16_t group; + const uint8_t *key_exchange; + size_t key_exchange_len; + + format_print(fp, fmt, ind, "KeyShareEntry\n"); + if (tls_uint16_from_bytes(&group, &client_shares, &client_shares_len) != 1 + || tls_uint16array_from_bytes(&key_exchange, &key_exchange_len, &client_shares, &client_shares_len) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind + 4, "group: %s (0x%04x)\n", tls_named_curve_name(group), group); + format_bytes(fp, fmt, ind + 4, "key_exchange", key_exchange, key_exchange_len); + } + if (datalen) { + error_print(); + return -1; + } + return 1; +} + +/* +struct { + KeyShareEntry server_share; +} KeyShareServerHello; +*/ +int tls13_key_share_server_hello_ext_to_bytes(const X509_KEY *key, uint8_t **out, size_t *outlen) +{ + uint16_t ext_type = TLS_extension_key_share; + size_t ext_datalen = 0; + + if (tls13_key_share_entry_to_bytes(key, NULL, &ext_datalen) != 1) { + error_print(); + return -1; + } + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); + tls13_key_share_entry_to_bytes(key, out, outlen); + return 1; +} + +int tls13_key_share_server_hello_from_bytes(int *group, const uint8_t **key_exchange, size_t *key_exchange_len, + const uint8_t *ext_data, size_t ext_datalen) +{ + if (tls13_key_share_entry_from_bytes(group, key_exchange, key_exchange_len, + &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls13_key_share_server_hello_print(FILE *fp, int fmt, int ind, + const uint8_t *data, size_t datalen) +{ + uint16_t group; + const uint8_t *key_exchange; + size_t key_exchange_len; + + format_print(fp, fmt, ind, "server_share\n"); + ind += 4; + if (tls_uint16_from_bytes(&group, &data, &datalen) != 1 + || tls_uint16array_from_bytes(&key_exchange, &key_exchange_len, &data, &datalen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "group: %s (0x%04x)\n", tls_named_curve_name(group), group); + format_bytes(fp, fmt, ind, "key_exchange", key_exchange, key_exchange_len); + if (datalen) { + error_print(); + return -1; + } + return 1; +} + +/* +struct { + NamedGroup selected_group; +} KeyShareHelloRetryRequest; +*/ +int tls13_key_share_hello_retry_request_ext_to_bytes(int selected_group, uint8_t **out, size_t *outlen) +{ + uint16_t ext_type = TLS_extension_key_share; + + uint8_t ext_data[2]; + uint8_t *p = ext_data; size_t len = 0; - tls_uint16_to_bytes((uint16_t)sign_algor, &p, &len); - tls_uint16array_to_bytes(sig, siglen, &p, &len); + tls_uint16_to_bytes((uint16_t)selected_group, &p, &len); + tls_ext_to_bytes(ext_type, ext_data, sizeof(ext_data), out, outlen); - if (tls_record_set_handshake(record, recordlen, type, NULL, len) != 1) { - error_print(); - return -1; - } return 1; } -int tls13_record_get_handshake_certificate_verify(const uint8_t *record, - int *sign_algor, const uint8_t **sig, size_t *siglen) +int tls13_key_share_hello_retry_request_from_bytes(int *selected_group, const uint8_t *ext_data, size_t ext_datalen) { - int type; - const uint8_t *p; - size_t len ; - uint16_t alg; + uint16_t group; - if (tls_record_get_handshake(record, &type, &p, &len) != 1 - || type != TLS_handshake_certificate_verify) { + if (tls_uint16_from_bytes(&group, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { error_print(); return -1; } - - tls_uint16_from_bytes(&alg, &p, &len); - tls_uint16array_from_bytes(sig, siglen, &p, &len); - *sign_algor = alg; - + if (!tls_named_curve_name(group)) { + error_print(); + return -1; + } + *selected_group = group; return 1; } +int tls13_key_share_hello_retry_request_print(FILE *fp, int fmt, int ind, + const uint8_t *ext_data, size_t ext_datalen) +{ + uint16_t selected_group; + + if (tls_uint16_from_bytes(&selected_group, &ext_data, &ext_datalen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "selected_group: %s (%04x)\n", + tls_named_curve_name(selected_group), selected_group); + if (ext_datalen) { + error_print(); + return -1; + } + return 1; +} + + + +/* +certificate_authorities + + opaque DistinguishedName<1..2^16-1>; + + struct { + DistinguishedName authorities<3..2^16-1>; + } CertificateAuthoritiesExtension; +*/ + +int tls13_certificate_authorities_ext_to_bytes(const uint8_t *ca_names, size_t ca_names_len, + uint8_t **out, size_t *outlen) +{ + int ext_type = TLS_extension_certificate_authorities; + size_t ext_datalen; + size_t authorities_len; + const uint8_t *name; + size_t namelen; + const uint8_t *p; + size_t len; + + p = ca_names; + len = ca_names_len; + authorities_len = 0; + while (len) { + if (x509_name_from_der(&name, &namelen, &p, &len) != 1) { + error_print(); + return -1; + } + tls_uint16array_to_bytes(name, namelen, NULL, &authorities_len); + } + if (authorities_len < 3 || authorities_len > (1 << 16) - 1) { + error_print(); + return -1; + } + ext_datalen = tls_uint16_size() + authorities_len; + + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); + tls_uint16_to_bytes((uint16_t)authorities_len, out, outlen); + while (ca_names_len) { + x509_name_from_der(&name, &namelen, &ca_names, &ca_names_len); + tls_uint16array_to_bytes(name, namelen, out, outlen); + } + return 1; +} + +int tls13_certificate_authorities_print(FILE *fp, int fmt, int ind, + const uint8_t *ext_data, size_t ext_datalen) +{ + const uint8_t *authorities; + size_t authorities_len; + + if (tls_uint16array_from_bytes(&authorities, &authorities_len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + while (authorities_len) { + const uint8_t *dn; + size_t dn_len; + + if (tls_uint16array_from_bytes(&dn, &dn_len, &authorities, &authorities_len) != 1) { + error_print(); + return -1; + } + + x509_name_print(fp, fmt, ind, "DistinguishedName", dn, dn_len); + } + return 1; +} + + + + + + + + + + + + + + + + + + + /* struct { @@ -921,194 +1225,482 @@ struct { certificate_request_context 用于 Post-handshake Authentication,否则应该长度为0 */ -static int tls13_certificate_request_exts[] = { - TLS_extension_signature_algorithms, // 必须包含 - TLS_extension_status_request, - TLS_extension_signed_certificate_timestamp, - TLS_extension_certificate_authorities, - TLS_extension_oid_filters, - TLS_extension_signature_algorithms_cert, -}; +int tls13_client_hello_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen) +{ + uint16_t protocol; + const uint8_t *random; + const uint8_t *session_id; + const uint8_t *cipher_suites; + const uint8_t *comp_meths; + const uint8_t *exts; + size_t session_id_len, cipher_suites_len, comp_meths_len, extslen; + size_t i; + + format_print(fp, fmt, ind, "ClientHello\n"); + ind += 4; + + if (tls_uint16_from_bytes(&protocol, &d, &dlen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "legacy_version: %s (%d.%d)\n", + tls_protocol_name(protocol), protocol >> 8, protocol & 0xff); + + if (tls_array_from_bytes(&random, 32, &d, &dlen) != 1) { + error_print(); + return -1; + } + format_bytes(fp, fmt, ind, "random", random ,32); + + if (tls_uint8array_from_bytes(&session_id, &session_id_len, &d, &dlen) != 1) { + error_print(); + return -1; + } + format_bytes(fp, fmt, ind, "legacy_session_id", session_id, session_id_len); + + format_print(fp, fmt, ind, "cipher_suites\n"); + if (tls_uint16array_from_bytes(&cipher_suites, &cipher_suites_len, &d, &dlen) != 1) { + error_print(); + return -1; + } + while (cipher_suites_len) { + uint16_t cipher; + if (tls_uint16_from_bytes(&cipher, &cipher_suites, &cipher_suites_len) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind+4, "%s (0x%04x)\n", tls_cipher_suite_name(cipher), cipher); + } + + format_print(fp, fmt, ind, "legacy_compression_methods\n"); + if (tls_uint8array_from_bytes(&comp_meths, &comp_meths_len, &d, &dlen) != 1) { + error_print(); + return -1; + } + for (i = 0; i < comp_meths_len; i++) { + format_print(fp, fmt, ind + 4, "%s (%d)\n", + tls_compression_method_name(comp_meths[i]), comp_meths[i]); + } + + format_print(fp, fmt, ind, "extensions\n"); + ind += 4; + if (tls_uint16array_from_bytes(&exts, &extslen, &d, &dlen) != 1) { + error_print(); + return -1; + } + while (extslen) { + uint16_t ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + // tls_ext_from_bytes can not parse unknown ext + if (tls_uint16_from_bytes(&ext_type, &exts, &extslen) != 1 + || tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "%s (%d)\n", tls_extension_name(ext_type), ext_type); + + switch (ext_type) { + case TLS_extension_supported_versions: + tls13_client_supported_versions_print(fp, fmt, ind + 4, ext_data, ext_datalen); + break; + case TLS_extension_supported_groups: + tls_supported_groups_print(fp, fmt, ind + 4, ext_data, ext_datalen); + break; + case TLS_extension_key_share: + tls13_key_share_client_hello_print(fp, fmt, ind + 4, ext_data, ext_datalen); + break; + case TLS_extension_signature_algorithms: + tls_signature_algorithms_print(fp, fmt, ind + 4, ext_data, ext_datalen); + break; + case TLS_extension_psk_key_exchange_modes: + case TLS_extension_pre_shared_key: + case TLS_extension_early_data: + case TLS_extension_cookie: + case TLS_extension_server_name: + case TLS_extension_application_layer_protocol_negotiation: + case TLS_extension_padding: + case TLS_extension_record_size_limit: + default: + error_print(); + return -1; + } + } + if (dlen) { + error_print(); + return -1; + } + return 1; +} + +int tls13_server_hello_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen) +{ + uint16_t protocol; + const uint8_t *random; + const uint8_t *session_id; + uint16_t cipher_suite; + uint8_t comp_meth; + const uint8_t *exts; + size_t session_id_len, extslen; + + format_print(fp, fmt, ind, "ServerHello\n"); + ind += 4; + + if (tls_uint16_from_bytes(&protocol, &d, &dlen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "legacy_version: %s (%d.%d)\n", + tls_protocol_name(protocol), protocol >> 8, protocol & 0xff); + + if (tls_array_from_bytes(&random, 32, &d, &dlen) != 1) { + error_print(); + return -1; + } + format_bytes(fp, fmt, ind, "random", random, 32); + + if (tls_uint8array_from_bytes(&session_id, &session_id_len, &d, &dlen) != 1) { + error_print(); + return -1; + } + format_bytes(fp, fmt, ind, "legacy_session_id", session_id, session_id_len); + + if (tls_uint16_from_bytes(&cipher_suite, &d, &dlen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "cipher_suite: %s (0x%04x)\n", + tls_cipher_suite_name(cipher_suite), cipher_suite); + + if (tls_uint8_from_bytes(&comp_meth, &d, &dlen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "legacy_compression_method: %s (%d)\n", + tls_compression_method_name(comp_meth), comp_meth); + + format_print(fp, fmt, ind, "extensions\n"); + if (tls_uint16array_from_bytes(&exts, &extslen, &d, &dlen) != 1) { + error_print(); + return -1; + } + while (extslen) { + uint16_t ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + if (tls_uint16_from_bytes(&ext_type, &exts, &extslen) != 1 + || tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "%s (%d)\n", tls_extension_name(ext_type), ext_type); + ind += 4; + switch (ext_type) { + case TLS_extension_supported_versions: + tls13_server_supported_versions_print(fp, fmt, ind, ext_data, ext_datalen); + break; + case TLS_extension_key_share: + tls13_key_share_server_hello_print(fp, fmt, ind, ext_data, ext_datalen); + break; + case TLS_extension_pre_shared_key: + //tls13_pre_shared_key_print(fp, fmt, ind, ext_data, ext_datalen); + break; + default: + format_bytes(fp, fmt, ind, "raw_data", ext_data, ext_datalen); + return -1; + } + } + if (dlen) { + error_print(); + return -1; + } + return 1; +} + + /* struct { - opaque certificate_request_context<0..2^8-1>; - Extension extensions<2..2^16-1>; -} CertificateRequest; - -extensiosns: - Extension 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, - const uint8_t *exts, size_t extslen) -{ - int type = TLS_handshake_certificate_request; - uint8_t *data; - size_t datalen = 0; - - if (!record || !recordlen) { - 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); - tls_record_set_handshake(record, recordlen, type, NULL, datalen); - return 1; -} - -int tls13_record_set_handshake_certificate_request_default(uint8_t *record, size_t *recordlen) -{ - int sig_algs[] = { TLS_sig_sm2sig_sm3 }; - uint8_t exts[256]; - uint8_t *p = exts; - size_t extslen = 0; - - tls_signature_algorithms_ext_to_bytes(sig_algs, sizeof(sig_algs)/sizeof(int), &p, &extslen); - tls13_record_set_handshake_certificate_request(record, recordlen, NULL, 0, exts, extslen); - return 1; -} - -int tls13_record_get_handshake_certificate_request(const uint8_t *record, - const uint8_t **requst_context, size_t *request_context_len, - const uint8_t **exts, size_t *exts_len) -{ - int type; - const uint8_t *p; - size_t len; - - if (tls_record_get_handshake(record, &type, &p, &len) != 1) { - error_print(); - return -1; - } - if (type != TLS_handshake_certificate_request) { - error_print(); - return -1; - } - if (tls_uint8array_from_bytes(requst_context, request_context_len, &p, &len) != 1 - || tls_uint16array_from_bytes(exts, exts_len, &p, &len) != 1 - || tls_length_is_zero(len) != 1) { - error_print(); - return -1; - } - return 1; -} - -static const int tls13_handshake_certificate_exts[] = { - TLS_extension_status_request, - TLS_extension_signed_certificate_timestamp, -}; -/* -enum { X509(0), RawPublicKey(2), (255) } CertificateType; - -struct { - select (certificate_type) { - case RawPublicKey: opaque ASN1_subjectPublicKeyInfo<1..2^24-1>; -- TLS 1.3可以只传公钥不传证书 - case X509: opaque cert_data<1..2^24-1>; - }; - Extension extensions<0..2^16-1>; -} CertificateEntry; - -struct { - opaque certificate_request_context<0..2^8-1>; -- 用于客户端证书,服务器证书该域长度为0 - CertificateEntry certificate_list<0..2^24-1>; -} Certificate; - -TLS 1.3 Certificate: - - * TLS 1.3 支持发送公钥,可以去掉嵌入式环境的证书传输开销 - * TLS 1.3 的证书链中增加了 certificate_request_context - 用于客户端发送证书时标识context,服务器端的证书中该域的长度为0 - * 证书链中每个证书都有一个独立的扩展域,TLS 1.2 中的证书相关扩展移至此处 - -Extensions in client Certificate MUST from ClientHello -Extensions in server Certificate MUST from CertificateRequest -Entensions apply to entire chain SHOULD be in the first CertificateEntry - -目前CertificateEntry中的扩展主要用于服务器证书的验证 -客户端在ClientHello中可以包含status_request 和 signed_certificate_timestamp -让服务器提供 OCSP 的状态证明和时间戳信息 -服务器则在证书消息的每个证书否面附带这两个扩展,提供相关信息 - -在 RFC 8446 (TLS 1.3) 中还没有涉及客户端证书的具体扩展 -但是客户端在提供客户端证书时,应该响应服务器CertificateRequest消息中的扩展 - -目前GmSSLv3还不支持这两个证书扩展的生成,但是提供解析和显示 - -Valid extensions for server certificates: - TLS_extension_status_request (5) - TLS_extension_signed_certificate_timestamp (18) + select (Handshake.msg_type) { + case new_session_ticket: uint32 max_early_data_size; + case client_hello: empty; + case encrypted_extensions: empty; + }; +} EarlyDataIndication; */ -int tls13_certificate_print(FILE *fp, int fmt, int ind, const uint8_t *cert, size_t certlen) + +int tls13_new_session_ticket_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen) { - const uint8_t *p; - size_t len; + uint32_t ticket_lifetime; + uint32_t ticket_age_add; + const uint8_t *ticket_nonce; + size_t ticket_nonce_len; + const uint8_t *ticket; + size_t ticket_len; + const uint8_t *exts; + size_t extslen; + + // early_data extension + uint32_t max_early_data_size; + + + format_print(fp, fmt, ind, "NewSessionTicket\n"); + ind += 4; + + if (tls_uint32_from_bytes(&ticket_lifetime, &d, &dlen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "ticket_lifetime: %"PRIu32" seconds\n", ticket_lifetime); + + if (tls_uint32_from_bytes(&ticket_age_add, &d, &dlen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "ticket_age_add: %"PRIu32"\n", ticket_age_add); + + if (tls_uint8array_from_bytes(&ticket_nonce, &ticket_nonce_len, &d, &dlen) != 1) { + error_print(); + return -1; + } + format_bytes(fp, fmt, ind, "ticket_nonce", ticket_nonce, ticket_nonce_len); + + if (tls_uint16array_from_bytes(&ticket, &ticket_len, &d, &dlen) != 1) { + error_print(); + return -1; + } + format_bytes(fp, fmt, ind, "ticket", ticket, ticket_len); + + format_print(fp, fmt, ind, "extensions\n"); + ind += 4; + if (tls_uint16array_from_bytes(&exts, &extslen, &d, &dlen) != 1) { + error_print(); + return -1; + } + while (extslen) { + uint16_t ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + if (tls_uint16_from_bytes(&ext_type, &exts, &extslen) != 1 + || tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + return -1; + } + switch (ext_type) { + case TLS_extension_early_data: + if (tls_uint32_from_bytes(&max_early_data_size, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "max_early_data_size: %"PRIu32"\n", max_early_data_size); + break; + default: + format_print(fp, fmt, ind, "%s (%d)\n", tls_extension_name(ext_type), ext_type); + format_bytes(fp, fmt, ind + 4, "raw_data", ext_data, ext_datalen); + error_print(); + } + } + if (dlen) { + error_print(); + return -1; + } + return 1; +} + +int tls13_end_of_early_data_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen) +{ + format_print(fp, fmt, ind, "EndOfEarlyData\n"); + if (dlen) { + error_print(); + return -1; + } + return 1; +} + +int tls13_encrypted_extensions_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen) +{ + const uint8_t *exts; + size_t extslen; + + format_print(fp, fmt, ind, "EncryptedExtensions\n"); + ind += 4; + + if (tls_uint16array_from_bytes(&exts, &extslen, &d, &dlen) != 1) { + error_print(); + return -1; + } + while (extslen) { + uint16_t ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + if (tls_uint16_from_bytes(&ext_type, &exts, &extslen) != 1 + || tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + return -1; + } + switch (ext_type) { + case TLS_extension_supported_groups: + tls_supported_groups_print(fp, fmt, ind, ext_data, ext_datalen); + break; + case TLS_extension_client_certificate_type: + case TLS_extension_server_certificate_type: + case TLS_extension_server_name: + case TLS_extension_max_fragment_length: + case TLS_extension_use_srtp: + case TLS_extension_heartbeat: + case TLS_extension_application_layer_protocol_negotiation: + case TLS_extension_record_size_limit: + default: + format_bytes(fp, fmt, ind, "raw_data", ext_data, ext_datalen); + } + } + if (dlen) { + error_print(); + return -1; + } + return 1; +} + +int tls13_certificate_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen) +{ + const uint8_t *req_context; + size_t req_context_len; + const uint8_t *cert_list; + size_t cert_list_len; format_print(fp, fmt, ind, "Certificate\n"); ind += 4; - if (tls_uint8array_from_bytes(&p, &len, &cert, &certlen) != 1) { + if (tls_uint8array_from_bytes(&req_context, &req_context_len, &d, &dlen) != 1) { error_print(); return -1; } - format_bytes(fp, fmt, ind, "certificate_request_context", p, len); + format_bytes(fp, fmt, ind, "certificate_request_context", req_context, req_context_len); format_print(fp, fmt, ind, "certificate_list\n"); ind += 4; - if (tls_uint24array_from_bytes(&p, &len, &cert, &certlen) != 1) { + if (tls_uint24array_from_bytes(&cert_list, &cert_list_len, &d, &dlen) != 1) { error_print(); return -1; } - while (len) { + while (cert_list_len) { const uint8_t *cert_data; size_t cert_data_len; const uint8_t *exts; size_t extslen; - if (tls_uint24array_from_bytes(&cert_data, &cert_data_len, &p, &len) != 1 - || tls_uint16array_from_bytes(&exts, &extslen, &p, &len) != 1) { - error_print(); - return -1; - } - if (!cert_data) { - error_print(); - return -1; - } - format_print(fp, fmt, ind, "CertificateEntry\n"); + if (tls_uint24array_from_bytes(&cert_data, &cert_data_len, &cert_list, &cert_list_len) != 1 + || tls_uint16array_from_bytes(&exts, &extslen, &cert_list, &cert_list_len) != 1) { + error_print(); + return -1; + } + if (!cert_data_len) { + error_print(); + return -1; + } x509_cert_print(fp, fmt, ind + 4, "Certificate", cert_data, cert_data_len); x509_cert_to_pem(cert_data, cert_data_len, fp); - tls13_extensions_print(fp, fmt, ind + 4, TLS_handshake_certificate, exts, extslen); + + if (extslen) + format_print(fp, fmt, ind, "extensions\n"); + else format_print(fp, fmt, ind, "extensions: (null)\n"); + + while (extslen) { + uint16_t ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + if (tls_uint16_from_bytes(&ext_type, &exts, &extslen) != 1 + || tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "%s (%d)\n", tls_extension_name(ext_type), ext_type); + ind += 4; + + switch (ext_type) { + case TLS_extension_status_request: + case TLS_extension_signed_certificate_timestamp: + case TLS_extension_server_certificate_type: + case TLS_extension_client_certificate_type: + break; + default: + error_print(); + return -1; + } + } + } + if (dlen) { + error_print(); + return -1; } return 1; } -int tls13_certificate_request_print(FILE *fp, int fmt, int ind, const uint8_t *certreq, size_t certreqlen) +int tls13_certificate_request_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen) { - const uint8_t *p; - size_t len; + const uint8_t *req_context; + size_t req_context_len; + const uint8_t *exts; + size_t extslen; format_print(fp, fmt, ind, "CertificateRequest\n"); ind += 4; - if (tls_uint8array_from_bytes(&p, &len, &certreq, &certreqlen) != 1) { + if (tls_uint8array_from_bytes(&req_context, &req_context_len, &d, &dlen) != 1) { error_print(); return -1; } - format_bytes(fp, fmt, ind, "certificate_request_context", p, len); + format_bytes(fp, fmt, ind, "certificate_request_context", req_context, req_context_len); - if (tls_uint16array_from_bytes(&p, &len, &certreq, &certreqlen) != 1) { + format_print(fp, fmt, ind, "extensions\n"); + ind += 4; + if (tls_uint16array_from_bytes(&exts, &extslen, &d, &dlen) != 1) { error_print(); return -1; } - format_bytes(fp, fmt, ind, "extensions", p, len); + while (extslen) { + uint16_t ext_type; + const uint8_t *ext_data; + size_t ext_datalen; - if (tls_length_is_zero(certreqlen) != 1) { + if (tls_uint16_from_bytes(&ext_type, &exts, &extslen) != 1 + || tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + return -1; + } + switch (ext_type) { + case TLS_extension_signature_algorithms: + tls_signature_algorithms_print(fp, fmt, ind, ext_data, ext_datalen); + break; + case TLS_extension_certificate_authorities: + 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); + break; + case TLS_extension_signature_algorithms_cert: + tls13_signature_algorithms_cert_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); + break; + default: + error_print(); + return -1; + } + } + if (dlen) { error_print(); return -1; } @@ -1141,6 +1733,174 @@ int tls13_certificate_verify_print(FILE *fp, int fmt, int ind, const uint8_t *d, return 1; } +int tls13_key_update_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen) +{ + uint8_t update_requested; + + if (tls_uint8_from_bytes(&update_requested, &d, &dlen) != 1 + || tls_length_is_zero(dlen) != 1) { + error_print(); + return -1; + } + switch (update_requested) { + case 0: + case 1: + break; + default: + error_print(); + return -1; + } + format_print(fp, fmt, ind, "request_update: %d\n", update_requested); + return 1; +} + +int tls13_message_hash_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen) +{ + return 1; +} + +int tls13_finished_print(FILE *fp, int fmt, int ind, const uint8_t *data, size_t datalen) +{ + format_print(fp, fmt, ind, "Finished\n"); + ind += 4; + format_bytes(fp, fmt, ind, "verify_data", data, datalen); + return 1; +} + + +int tls13_handshake_print(FILE *fp, int fmt, int ind, const uint8_t *handshake, size_t handshake_len) +{ + const uint8_t *p = handshake; + size_t len = handshake_len; + uint8_t type; + const uint8_t *data; + size_t datalen; + + if (tls_uint8_from_bytes(&type, &handshake, &handshake_len) != 1 + || tls_uint24array_from_bytes(&data, &datalen, &handshake, &handshake_len) != 1 + || tls_length_is_zero(handshake_len) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "Handshake\n"); + ind += 4; + format_print(fp, fmt, ind, "Type: %s (%d)\n", tls_handshake_type_name(type), type); + format_print(fp, fmt, ind, "Length: %zu\n", datalen); + + switch (type) { + case TLS_handshake_client_hello: + tls13_client_hello_print(fp, fmt, ind, data, datalen); + break; + case TLS_handshake_server_hello: + tls13_server_hello_print(fp, fmt, ind, data, datalen); + break; + case TLS_handshake_new_session_ticket: + tls13_new_session_ticket_print(fp, fmt, ind, data, datalen); + break; + case TLS_handshake_end_of_early_data: + tls13_end_of_early_data_print(fp, fmt, ind, data, datalen); + break; + case TLS_handshake_encrypted_extensions: + tls13_encrypted_extensions_print(fp, fmt, ind, data, datalen); + break; + case TLS_handshake_certificate: + tls13_certificate_print(fp, fmt, ind, data, datalen); + break; + case TLS_handshake_certificate_request: + tls13_certificate_request_print(fp, fmt, ind, data, datalen); + break; + case TLS_handshake_certificate_verify: + tls13_certificate_verify_print(fp, fmt, ind, data, datalen); + break; + case TLS_handshake_finished: + tls13_finished_print(fp, fmt, ind, data, datalen); + break; + case TLS_handshake_key_update: + tls13_key_update_print(fp, fmt, ind, data, datalen); + break; + case TLS_handshake_message_hash: + tls13_message_hash_print(fp, fmt, ind, data, datalen); + break; + default: + error_print(); + return -1; + } + return 1; +} + +int tls13_record_print(FILE *fp, int format, int indent, const uint8_t *record, size_t recordlen) +{ + const uint8_t *data; + size_t datalen; + int protocol; + + format |= TLS_cipher_sm4_gcm_sm3 << 8; + + if (!fp || !record || recordlen < 5) { + error_print(); + return -1; + } + protocol = tls_record_protocol(record); + format_print(fp, format, indent, "Record\n"); indent += 4; + format_print(fp, format, indent, "ContentType: %s (%d)\n", tls_record_type_name(record[0]), record[0]); + format_print(fp, format, indent, "Version: %s (%d.%d)\n", tls_protocol_name(protocol), protocol >> 8, protocol & 0xff); + format_print(fp, format, indent, "Length: %d\n", tls_record_data_length(record)); + + data = tls_record_data(record); + datalen = tls_record_data_length(record); + + if (recordlen < tls_record_length(record)) { + error_print(); + return -1; + } + + // 最高字节设置后强制打印记录原始数据 + if (format >> 24) { + format_bytes(fp, format, indent, "Data", data, datalen); + fprintf(fp, "\n"); + return 1; + } + + switch (record[0]) { + case TLS_record_handshake: + tls13_handshake_print(fp, format, indent, data, datalen); + break; + + case TLS_record_alert: + if (tls_alert_print(fp, data, datalen, format, indent) != 1) { + error_print(); + return -1; + } + break; + case TLS_record_change_cipher_spec: + if (tls_change_cipher_spec_print(fp, data, datalen, format, indent) != 1) { + error_print(); + return -1; + } + break; + case TLS_record_application_data: + if (tls_application_data_print(fp, data, datalen, format, indent) != 1) { + error_print(); + return -1; + } + break; + default: + error_print(); + return -1; + } + + recordlen -= tls_record_length(record); + if (recordlen) { + format_print(fp, 0, 0, "DataLeftInRecord: %zu\n", recordlen); + } + + fprintf(fp, "\n"); + return 1; +} + + + + int tls13_certificate_list_to_bytes(const uint8_t *certs, size_t certslen, uint8_t **out, size_t *outlen) { @@ -1216,9 +1976,206 @@ int tls13_process_certificate_list(const uint8_t *cert_list, size_t cert_list_le return 1; } + +// 1. client_hello +// 2. server_hello + + + + + +// new_session_ticket +int tls13_record_set_handshake_new_session_ticket(uint8_t *record, size_t *recordlen, + uint32_t ticket_lifetime, uint32_t ticket_age_add, + const uint8_t *ticket_nonce, size_t ticket_nonce_len, + const uint8_t *ticket, size_t ticketlen, + const uint8_t *exts, size_t extslen) +{ + int type = TLS_handshake_encrypted_extensions; + uint8_t *p = record + 5 + 4; + size_t len = 0; + + if (ticket_nonce_len > 255 + || ticketlen > 65535 + || extslen > 65534) { + error_print(); + return -1; + } + tls_uint32_to_bytes(ticket_lifetime, &p, &len); + tls_uint32_to_bytes(ticket_age_add, &p, &len); + tls_uint8array_to_bytes(ticket_nonce, ticket_nonce_len, &p, &len); + tls_uint16array_to_bytes(ticket, ticketlen, &p, &len); + tls_uint16array_to_bytes(exts, extslen, &p, &len); + tls_record_set_handshake(record, recordlen, type, NULL, len); + return 1; +} + +int tls13_record_get_handshake_new_session_ticket(uint8_t *record, + uint32_t *ticket_lifetime, uint32_t *ticket_age_add, + const uint8_t **ticket_nonce, size_t *ticket_nonce_len, + const uint8_t **ticket, size_t *ticketlen, + const uint8_t **exts, size_t *extslen) +{ + int type; + const uint8_t *cp; + size_t len; + + if (tls_record_get_handshake(record, &type, &cp, &len) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_encrypted_extensions) { + error_print(); + return -1; + } + if (tls_uint32_from_bytes(ticket_lifetime, &cp, &len) != 1 + || tls_uint32_from_bytes(ticket_age_add, &cp, &len) != 1 + || tls_uint8array_from_bytes(ticket_nonce, ticket_nonce_len, &cp, &len) != 1 + || tls_uint16array_from_bytes(ticket, ticketlen, &cp, &len) != 1 + || tls_uint16array_from_bytes(exts, extslen, &cp, &len) != 1 + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + if (*ticket_lifetime > 60 * 60 * 24 * 7) { + error_print(); + return -1; + } + if (!ticketlen) { + error_print(); + return -1; + } + if (*extslen > 65534) { + error_print(); + return -1; + } + return 1; +} + + +// 5. end_of_early_data +int tls13_record_set_handshake_end_of_early_data(uint8_t *record, size_t *recordlen) +{ + int type = TLS_handshake_end_of_early_data; + tls_record_set_handshake(record, recordlen, type, NULL, 0); + return 1; +} + +int tls13_record_get_handshake_end_of_early_data(uint8_t *record, size_t *recordlen) +{ + int type; + const uint8_t *cp; + size_t len; + + if (tls_record_get_handshake(record, &type, &cp, &len) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_end_of_early_data) { + error_print(); + return -1; + } + if (len) { + error_print(); + return -1; + } + return 1; +} + +// 8. encrypted_extensions +int tls13_record_set_handshake_encrypted_extensions(uint8_t *record, size_t *recordlen, + const uint8_t *exts, size_t extslen) +{ + int type = TLS_handshake_encrypted_extensions; + uint8_t *p = record + 5 + 4; + size_t len = 0; + + tls_uint16array_to_bytes(exts, extslen, &p, &len); + tls_record_set_handshake(record, recordlen, type, NULL, len); + return 1; +} + +int tls13_record_get_handshake_encrypted_extensions(const uint8_t *record, + const uint8_t **exts, size_t *extslen) +{ + int type; + const uint8_t *cp; + size_t len; + + if (tls_record_get_handshake(record, &type, &cp, &len) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_encrypted_extensions) { + error_print(); + return 0; + } + if (tls_uint16array_from_bytes(exts, extslen, &cp, &len) != 1 + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} + + +// 11. certificate + +// 这里有一个问题,就是TLS 1.3的Certificate是由CertificateEntry构成的, +// 每一个Entry都有可选的扩展,都有哪些可选的扩展呢? +/* + + 客户端在ClientHello扩展中对服务器的证书提出要求 + + status_request 证书的OCSP响应 + 这个扩展在ClientHello和ServerCertificate中的格式是不一样的 + 暂时先不要支持了 + 服务器可以忽略这个请求 + 这个信息是需要经常更新的 + 服务器可以每天(根据OCSP的配置)去OCSP服务器获取,并且在初始化的时候提供给ctx + + + signed_certificate_timestamp 证书透明,证明证书已被提交到公共日志系统 + 可能出现在客户端或者服务器端 + 这个扩展本身可以嵌入在证书中,也可以从TLS扩展提供 + 实际上没必要现在就实现 + + certificate_authorities 接收的CA + 应该出现在CertificateRequest和ClientHello中 + 我们需要支持从一组证书中获取这个信息 + 这个已经支持了 + + oid_filters + 仅仅出现在CertificateRequest中 + + 这些扩展处理起来是比较复杂的 + + + 这里的主要问题是,每个证书都带有一组。 + + + 每个CertificateEntry都包含一个extensions,extensions的结构是uint16array + 因此我们可以提供一个exts_list + +Certificate { + opaque certificate_request_context<0..2^8-1>; + CertificateEntry certificate_list<0..2^24-1>; // 证书链,第一个是终端证书 +} + +CertificateEntry { + select (certificate_type) { + case X509: opaque cert_data<1..2^24-1>; // DER编码的X.509证书 + }; + Extension extensions<0..2^16-1>; // 这个证书的扩展列表 +} + + +*/ +// 这个函数还应该提供扩展 int tls13_record_set_handshake_certificate(uint8_t *record, size_t *recordlen, const uint8_t *request_context, size_t request_context_len, - const uint8_t *certs, size_t certslen) + const uint8_t *certs, size_t certslen, + const uint8_t *exts_list, size_t exts_list_len) { int type = TLS_handshake_certificate; uint8_t *data; @@ -1229,6 +2186,9 @@ int tls13_record_set_handshake_certificate(uint8_t *record, size_t *recordlen, return -1; } + // 这个就比较复杂了,需要先计算所有的长度 + // 然后最后再输出 + datalen = 0; tls_uint8array_to_bytes(request_context, request_context_len, NULL, &datalen); tls13_certificate_list_to_bytes(certs, certslen, NULL, &datalen); @@ -1276,6 +2236,131 @@ int tls13_record_get_handshake_certificate(const uint8_t *record, } +// 13. certificate_request +/* +struct { + opaque certificate_request_context<0..2^8-1>; + Extension extensions<2..2^16-1>; +} CertificateRequest; + +extensiosns: + Extension 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, + const uint8_t *exts, size_t extslen) +{ + int type = TLS_handshake_certificate_request; + uint8_t *data; + size_t datalen = 0; + + if (!record || !recordlen) { + 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); + tls_record_set_handshake(record, recordlen, type, NULL, datalen); + return 1; +} + +int tls13_record_set_handshake_certificate_request_default(uint8_t *record, size_t *recordlen) +{ + int sig_algs[] = { TLS_sig_sm2sig_sm3 }; + uint8_t exts[256]; + uint8_t *p = exts; + size_t extslen = 0; + + tls_signature_algorithms_ext_to_bytes(sig_algs, sizeof(sig_algs)/sizeof(int), &p, &extslen); + tls13_record_set_handshake_certificate_request(record, recordlen, NULL, 0, exts, extslen); + return 1; +} + +int tls13_record_get_handshake_certificate_request(const uint8_t *record, + const uint8_t **requst_context, size_t *request_context_len, + const uint8_t **exts, size_t *exts_len) +{ + int type; + const uint8_t *p; + size_t len; + + if (tls_record_get_handshake(record, &type, &p, &len) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_certificate_request) { + error_print(); + return -1; + } + if (tls_uint8array_from_bytes(requst_context, request_context_len, &p, &len) != 1 + || tls_uint16array_from_bytes(exts, exts_len, &p, &len) != 1 + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + return 1; +} + +/* +handshake #15 + +struct { + SignatureScheme algorithm; + opaque signature<0..2^16-1>; +} CertificateVerify; +*/ +int tls13_record_set_handshake_certificate_verify(uint8_t *record, size_t *recordlen, + int sig_alg, const uint8_t *sig, size_t siglen) +{ + int type = TLS_handshake_certificate_verify; + uint8_t *p = record + 5 + 4; // 这里都应该改为tls_record_handshake_data + size_t len = 0; + + if (!tls_signature_scheme_name(sig_alg)) { + error_print(); + return -1; + } + tls_uint16_to_bytes((uint16_t)sig_alg, &p, &len); + tls_uint16array_to_bytes(sig, siglen, &p, &len); + if (tls_record_set_handshake_header(record, recordlen, type, len) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls13_record_get_handshake_certificate_verify(const uint8_t *record, + int *sig_alg, const uint8_t **sig, size_t *siglen) +{ + int type; + const uint8_t *cp; + size_t len ; + uint16_t alg; + + if (tls_record_get_handshake(record, &type, &cp, &len) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_certificate_verify) { + return 0; + } + if (tls_uint16_from_bytes(&alg, &cp, &len) != 1 + || tls_uint16array_from_bytes(sig, siglen, &cp, &len) != 1) { + error_print(); + return -1; + } + if (!tls_signature_scheme_name(alg)) { + error_print(); + return -1; + } + *sig_alg = alg; + return 1; +} + + +// 20. finished + /* finished_key = HKDF-Expand-Label(BaseKey, "finished", "", Hash.length) @@ -1293,11 +2378,19 @@ int tls13_record_set_handshake_finished(uint8_t *record, size_t *recordlen, const uint8_t *verify_data, size_t verify_data_len) { int type = TLS_handshake_finished; - if (!record || !recordlen || !verify_data) { + + if (!verify_data || !verify_data_len) { + error_print(); + return -1; + } + if (verify_data_len != 32) { + error_print(); + return -1; + } + if (tls_record_set_handshake(record, recordlen, type, verify_data, verify_data_len) != 1) { error_print(); return -1; } - tls_record_set_handshake(record, recordlen, type, verify_data, verify_data_len); return 1; } @@ -1311,14 +2404,9 @@ int tls13_record_get_handshake_finished(const uint8_t *record, return -1; } if (type != TLS_handshake_finished) { - error_print(); - return -1; + return 0; } - if (*verify_data_len != SM3_DIGEST_SIZE -#if ENABLE_SHA2 - && *verify_data_len != SHA384_DIGEST_SIZE -#endif - ) { + if (*verify_data_len == 0) { error_print(); return -1; } @@ -1326,29 +2414,47 @@ int tls13_record_get_handshake_finished(const uint8_t *record, } -int tls13_padding_len_rand(size_t *padding_len) +// 24. key_update +int tls13_record_set_handshake_key_update(uint8_t *record, size_t *recordlen, + int request_update) { - uint8_t val; - rand_bytes(&val, 1); - *padding_len = val % 128; + int type = TLS_handshake_key_update; + uint8_t data[1]; // 这个值不太好 + + data[0] = request_update ? 1 : 0; + if (tls_record_set_handshake(record, recordlen, type, data, sizeof(data)) != 1) { + error_print(); + return -1; + } return 1; } - - -int tls13_cipher_suite_get(int cipher_suite, const DIGEST **digest, const BLOCK_CIPHER **cipher) +int tls13_record_get_handshake_key_update(uint8_t *record, size_t *recordlen, + int *request_update) { - switch (cipher_suite) { - case TLS_cipher_sm4_gcm_sm3: - *digest = DIGEST_sm3(); - *cipher = BLOCK_CIPHER_sm4(); + int type; + const uint8_t *cp; + size_t len; + + if (tls_record_get_handshake(record, &type, &cp, &len) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_key_update) { + return 0; + } + + if (len != 1) { + error_print(); + return -1; + } + switch (cp[0]) { + case 0: + *request_update = 0; break; -#if defined(ENABLE_AES) && defined(ENABLE_SHA2) - case TLS_cipher_aes_128_gcm_sha256: - *digest = DIGEST_sha256(); - *cipher = BLOCK_CIPHER_aes128(); + case 1: + *request_update = 1; break; -#endif default: error_print(); return -1; @@ -1358,6 +2464,29 @@ int tls13_cipher_suite_get(int cipher_suite, const DIGEST **digest, const BLOCK_ +// 254. message_hash +int tls13_record_set_message_hash(uint8_t *record, size_t *recordlen) +{ + return -1; +} + +int tls13_record_get_message_hash(uint8_t *record, size_t *recordlen) +{ + return -1; +} + + + + + + + + + + + + + /* Client Server @@ -1399,14 +2528,288 @@ Auth | {CertificateVerify*} [Application Data] <-------> [Application Data] +*/ -TLS 1.3的区别: - * 首先在最开始的握手阶段就协商好了密钥,因此握手之后传输的就是加密消息了 - * 因此在第二阶段,双方不再发送ServerKeyExchange和ClientKeyExchange - * 服务器先发送CertificateRequest,再发送Certificate - * 没有ChangeCipherSpec了 - * 在握手阶段就需要加密,并且Certificate也在其中,因此需要格外的大的密文数据缓冲 + + +int tls13_send_client_hello(TLS_CONNECT *conn) +{ + int ret; + + if (!conn->recordlen) { + const uint8_t *session_id = NULL; + size_t session_id_len = 0; + uint8_t exts[TLS_MAX_EXTENSIONS_SIZE]; + uint8_t *p = exts; + size_t extslen = 0; + size_t i; + + // record_version + tls_record_set_protocol(conn->record, TLS_protocol_tls1); + + if (rand_bytes(conn->client_random, 32) != 1) { + error_print(); + return -1; + } + + // key_share + for (i = 0; i < conn->ctx->supported_groups_cnt && i < 2; i++) { + int curve_oid = tls_named_curve_oid(conn->ctx->supported_groups[i]); + if (x509_key_generate(&conn->ecdh_keys[i], + OID_ec_public_key, &curve_oid, sizeof(curve_oid)) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + } + conn->ecdh_keys_cnt = i; + + + // extensions + if (tls13_client_supported_versions_ext_to_bytes(conn->ctx->supported_versions, + conn->ctx->supported_versions_cnt, &p, &extslen) != 1 + || tls_supported_groups_ext_to_bytes(conn->ctx->supported_groups, + conn->ctx->supported_groups_cnt, &p, &extslen) != 1 + || tls13_key_share_client_hello_ext_to_bytes( + conn->ecdh_keys, i, &p, &extslen) != 1 + || tls_signature_algorithms_ext_to_bytes( + conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt, &p, &extslen) != 1) { + error_print(); + return -1; + } + if (tls_record_set_handshake_client_hello(conn->record, &conn->recordlen, + TLS_protocol_tls12, conn->client_random, + session_id, conn->session_id_len, + conn->ctx->cipher_suites, conn->ctx->cipher_suites_cnt, + exts, extslen) != 1) { + error_print(); + return -1; + } + + tls_trace("send ClientHello\n"); + + tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); + } + + if (conn->client_certificate_verify) { + sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); + } + + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + + // backup ClientHello record for handshake message digest + memcpy(conn->plain_record, conn->record, conn->recordlen); + conn->plain_recordlen = conn->recordlen; + + tls_clean_record(conn); + return 1; +} + +int tls13_recv_server_hello(TLS_CONNECT *conn) +{ + int ret; + + // server_hello + int legacy_version; + const uint8_t *random; + const uint8_t *legacy_session_id_echo; + size_t legacy_session_id_echo_len; + int cipher_suite; + const uint8_t *exts; + size_t extslen; + + // extensions + int selected_version = -1; + int key_share_group = -1; + const uint8_t *key_exchange; + size_t key_exchange_len; + + + tls_trace("recv ServerHello\n"); + + + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { + error_print(); + } + return ret; + } + tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); + + if (tls_record_protocol(conn->record) != TLS_protocol_tls12) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + return -1; + } + + // 这种情况应该调用tls_record_get_handshake, 判断握手消息的类型,再处理吧 + + if ((ret = tls_record_get_handshake_server_hello(conn->record, + &legacy_version, &random, + &legacy_session_id_echo, &legacy_session_id_echo_len, + &cipher_suite, &exts, &extslen)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + + // legacy_version + if (legacy_version != TLS_protocol_tls12) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + return -1; + } + + // random + memcpy(conn->server_random, random, 32); + + // legacy_session_id_echo + if (legacy_session_id_echo_len != conn->session_id_len + || memcmp(legacy_session_id_echo, conn->session_id, conn->session_id_len) != 0) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + + // cipher_suite + if (tls_type_is_in_list(cipher_suite, conn->cipher_suites, conn->cipher_suites_cnt) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + conn->cipher_suite = cipher_suite; + if (tls13_cipher_suite_get(cipher_suite, &conn->cipher, &conn->digest) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + + while (extslen) { + int ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } + + switch (ext_type) { + case TLS_extension_supported_versions: + if (tls13_server_supported_versions_from_bytes(&selected_version, + ext_data, ext_datalen) != 1) { + tls_send_alert(conn, TLS_alert_decode_error); + error_print(); + return -1; + } + if (tls_type_is_in_list(selected_version, + conn->ctx->supported_versions, conn->ctx->supported_versions_cnt) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + if (selected_version != TLS_protocol_tls13) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + break; + + case TLS_extension_key_share: + if (tls13_key_share_server_hello_from_bytes(&key_share_group, + &key_exchange, &key_exchange_len, ext_data, ext_datalen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } + // 需要检查的是,服务器返回的group必须在 + + fprintf(stderr, "key_share_group = %04x\n", key_share_group); + + size_t i; + for (i = 0; i < conn->ecdh_keys_cnt; i++) { + + + int group = tls_named_curve_from_oid(conn->ecdh_keys[i].algor_param); + fprintf(stderr, "local_group = %04x\n", group); + if (group == key_share_group) { + conn->ecdh_key = conn->ecdh_keys[i]; + break; + } + } + if (i == conn->ecdh_keys_cnt) { + error_print(); + return -1; + } + + if (tls_type_is_in_list(key_share_group, conn->ctx->supported_groups, 2) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + if (key_exchange_len != 65) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + memcpy(conn->peer_ecdh_point, key_exchange, key_exchange_len); + conn->peer_ecdh_point_len = 65; + break; + + // extensions MUST NOT be included + case TLS_extension_supported_groups: + case TLS_extension_signature_algorithms: + case TLS_extension_server_name: + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + break; + + // extensions can be ignored + case TLS_extension_pre_shared_key: + default: + warning_print(); + } + } + + if (selected_version < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_missing_extension); + return -1; + } + if (key_share_group < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + printf("plain_record_len = %zu, recordlen = %zu\n", conn->plain_recordlen, conn->recordlen); + + digest_init(&conn->dgst_ctx, conn->digest); + digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5); + digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5); + + + + if (conn->client_certs_len) { + sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); + } + + return 1; +} + + + +/* 0 | @@ -1458,151 +2861,20 @@ TLS 1.3的区别: */ - - -int tls13_do_connect(TLS_CONNECT *conn) +int tls13_generate_keys(TLS_CONNECT *conn) { - int ret = -1; - uint8_t *record = conn->record; - uint8_t *enced_record = conn->enced_record; - size_t recordlen; - - size_t enced_recordlen; - - - int type; - const uint8_t *data; - size_t datalen; - - int protocol; - uint8_t client_random[32]; - uint8_t server_random[32]; - int cipher_suite; - const uint8_t *random; - const uint8_t *session_id; - size_t session_id_len; - - int protocols[] = { TLS_protocol_tls13 }; - int supported_groups[] = { TLS_curve_sm2p256v1 }; - int sign_algors[] = { TLS_sig_sm2sig_sm3 }; - - uint8_t client_exts[TLS_MAX_EXTENSIONS_SIZE]; - size_t client_exts_len; - const uint8_t *server_exts; - size_t server_exts_len; - - uint8_t sig[TLS_MAX_SIGNATURE_SIZE]; - size_t siglen = sizeof(sig); - uint8_t verify_data[32]; - size_t verify_data_len; - - int server_sign_algor; - const uint8_t *server_sig; - size_t server_siglen; - const uint8_t *server_verify_data; - size_t server_verify_data_len; - - SM2_KEY client_ecdhe; - SM2_KEY server_ecdhe_public; - X509_KEY server_sign_key; - - const DIGEST *digest = DIGEST_sm3(); - DIGEST_CTX dgst_ctx; // secret generation过程中需要ClientHello等数据输入的 - DIGEST_CTX null_dgst_ctx; // secret generation过程中不需要握手数据的 - const BLOCK_CIPHER *cipher = NULL; - size_t padding_len; - uint8_t zeros[32] = {0}; uint8_t psk[32] = {0}; uint8_t early_secret[32]; uint8_t handshake_secret[32]; - uint8_t master_secret[32]; - uint8_t client_handshake_traffic_secret[32]; - uint8_t server_handshake_traffic_secret[32]; - uint8_t client_application_traffic_secret[32]; - uint8_t server_application_traffic_secret[32]; + uint8_t pre_master_secret[32]; + size_t pre_master_secret_len; uint8_t client_write_key[16]; uint8_t server_write_key[16]; - - - const uint8_t *request_context; - size_t request_context_len; - const uint8_t *cert_request_exts; - size_t cert_request_extslen; - const uint8_t *cert_list; - size_t cert_list_len; - const uint8_t *cert; - size_t certlen; - - - conn->is_client = 1; - tls_record_set_protocol(enced_record, TLS_protocol_tls12); - - digest_init(&dgst_ctx, digest); - null_dgst_ctx = dgst_ctx; - - - // send ClientHello - tls_trace("send ClientHello\n"); - tls_record_set_protocol(record, TLS_protocol_tls1); - rand_bytes(client_random, 32); // TLS 1.3 Random 不再包含 UNIX Time - sm2_key_generate(&client_ecdhe); - tls13_client_hello_exts_set(client_exts, &client_exts_len, sizeof(client_exts), &(client_ecdhe.public_key)); - tls_record_set_handshake_client_hello(record, &recordlen, - TLS_protocol_tls12, client_random, NULL, 0, - tls13_ciphers, sizeof(tls13_ciphers)/sizeof(tls13_ciphers[0]), - client_exts, client_exts_len); - tls13_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - // 此时尚未确定digest算法,因此无法digest_update - - - // recv ServerHello - tls_trace("recv ServerHello\n"); - if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tls13_record_trace(stderr, enced_record, enced_recordlen, 0, 0); - if (tls_record_get_handshake_server_hello(enced_record, - &protocol, &random, &session_id, &session_id_len, - &cipher_suite, &server_exts, &server_exts_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (protocol != TLS_protocol_tls12) { - error_print(); - tls_send_alert(conn, TLS_alert_protocol_version); - goto end; - } - memcpy(server_random, random, 32); - memcpy(conn->session_id, session_id, session_id_len); - conn->session_id_len = session_id_len; - if (tls_cipher_suite_in_list(cipher_suite, - tls13_ciphers, sizeof(tls13_ciphers)/sizeof(tls13_ciphers[0])) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_handshake_failure); - goto end; - } - conn->cipher_suite = cipher_suite; - if (tls13_server_hello_extensions_get(server_exts, server_exts_len, &server_ecdhe_public) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_handshake_failure); - goto end; - } - conn->protocol = TLS_protocol_tls13; - - tls13_cipher_suite_get(conn->cipher_suite, &digest, &cipher); - digest_update(&dgst_ctx, record + 5, recordlen - 5); - digest_update(&dgst_ctx, enced_record + 5, enced_recordlen - 5); - + DIGEST_CTX null_dgst_ctx; printf("generate handshake secrets\n"); + /* generate handshake keys uint8_t client_write_key[32] @@ -1610,138 +2882,347 @@ int tls13_do_connect(TLS_CONNECT *conn) uint8_t client_write_iv[12] uint8_t server_write_iv[12] */ - uint8_t share_point_x[32]; - sm2_do_ecdh(&client_ecdhe, &server_ecdhe_public, share_point_x); - /* [1] */ tls13_hkdf_extract(digest, zeros, psk, early_secret); + + + if (x509_key_exchange(&conn->ecdh_key, + conn->peer_ecdh_point, conn->peer_ecdh_point_len, + pre_master_secret, &pre_master_secret_len) != 1) { + error_print(); + return -1; + } + + digest_init(&null_dgst_ctx, conn->digest); + + + /* [1] */ tls13_hkdf_extract(conn->digest, zeros, psk, early_secret); /* [5] */ tls13_derive_secret(early_secret, "derived", &null_dgst_ctx, handshake_secret); - /* [6] */ tls13_hkdf_extract(digest, handshake_secret, share_point_x, handshake_secret); - /* [7] */ tls13_derive_secret(handshake_secret, "c hs traffic", &dgst_ctx, client_handshake_traffic_secret); - /* [8] */ tls13_derive_secret(handshake_secret, "s hs traffic", &dgst_ctx, server_handshake_traffic_secret); - /* [9] */ tls13_derive_secret(handshake_secret, "derived", &null_dgst_ctx, master_secret); - /* [10] */ tls13_hkdf_extract(digest, master_secret, zeros, master_secret); + /* [6] */ tls13_hkdf_extract(conn->digest, handshake_secret, pre_master_secret, handshake_secret); + /* [7] */ tls13_derive_secret(handshake_secret, "c hs traffic", &conn->dgst_ctx, conn->client_handshake_traffic_secret); + /* [8] */ tls13_derive_secret(handshake_secret, "s hs traffic", &conn->dgst_ctx, conn->server_handshake_traffic_secret); + /* [9] */ tls13_derive_secret(handshake_secret, "derived", &null_dgst_ctx, conn->master_secret); + /* [10] */ tls13_hkdf_extract(conn->digest, conn->master_secret, zeros, conn->master_secret); //[sender]_write_key = HKDF-Expand-Label(Secret, "key", "", key_length) //[sender]_write_iv = HKDF-Expand-Label(Secret, "iv", "", iv_length) //[sender] in {server, client} - tls13_hkdf_expand_label(digest, server_handshake_traffic_secret, "key", NULL, 0, 16, server_write_key); - tls13_hkdf_expand_label(digest, server_handshake_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); - block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); + tls13_hkdf_expand_label(conn->digest, conn->server_handshake_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_handshake_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); memset(conn->server_seq_num, 0, 8); - tls13_hkdf_expand_label(digest, client_handshake_traffic_secret, "key", NULL, 0, 16, client_write_key); - tls13_hkdf_expand_label(digest, client_handshake_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); - block_cipher_set_encrypt_key(&conn->client_write_key, cipher, client_write_key); + + tls13_hkdf_expand_label(conn->digest, conn->client_handshake_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_handshake_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); memset(conn->client_seq_num, 0, 8); - /* + format_bytes(stderr, 0, 4, "client_write_key", client_write_key, 16); format_bytes(stderr, 0, 4, "server_write_key", server_write_key, 16); format_bytes(stderr, 0, 4, "client_write_iv", conn->client_write_iv, 12); format_bytes(stderr, 0, 4, "server_write_iv", conn->server_write_iv, 12); format_print(stderr, 0, 0, "\n"); - */ - // recv {EncryptedExtensions} + return 1; +} + +int tls13_recv_encrypted_extensions(TLS_CONNECT *conn) +{ + int ret; + const uint8_t *exts; + size_t extslen; + const uint8_t *supported_groups = NULL; + size_t supported_groups_len; + printf("recv {EncryptedExtensions}\n"); - if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_handshake_failure); - goto end; + + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { + error_print(); + } + return ret; } + if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, enced_record, enced_recordlen, - record, &recordlen) != 1) { + conn->server_seq_num, conn->record, conn->recordlen, + conn->plain_record, &conn->plain_recordlen) != 1) { error_print(); tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; + return -1; } - tls13_record_trace(stderr, record, recordlen, 0, 0); - if (tls13_record_get_handshake_encrypted_extensions(record) != 1) { - tls_send_alert(conn, TLS_alert_handshake_failure); + tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); + + if ((ret = tls13_record_get_handshake_encrypted_extensions(conn->plain_record, + &exts, &extslen)) < 0) { error_print(); - goto end; + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; } - digest_update(&dgst_ctx, record + 5, recordlen - 5); + + while (extslen) { + int ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } + switch (ext_type) { + case TLS_extension_supported_groups: + if (supported_groups) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + supported_groups = ext_data; + supported_groups_len = ext_datalen; + break; + // extensions must not be included + case TLS_extension_supported_versions: + case TLS_extension_key_share: + case TLS_extension_early_data: + case TLS_extension_psk_key_exchange_modes: + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + case TLS_extension_server_name: + case TLS_extension_application_layer_protocol_negotiation: + case TLS_extension_record_size_limit: + case TLS_extension_client_certificate_type: + case TLS_extension_server_certificate_type: + case TLS_extension_use_srtp: + case TLS_extension_padding: + case TLS_extension_signed_certificate_timestamp: + case TLS_extension_status_request: + default: + // ignore + warning_print(); + } + } + + if (supported_groups) { + /* + if (tls_supported_groups_from_bytes(conn->server_groups, &conn->server_groups_cnt, + supported_groups, supported_groups_len) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } + */ + } + + digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5); + tls_seq_num_incr(conn->server_seq_num); + return 1; +} - // recv {CertififcateRequest*} or {Certificate} - if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_handshake_failure); - goto end; +int tls13_recv_certificate_request(TLS_CONNECT *conn) +{ + int ret; + + int handshake_type; + const uint8_t *handshake_data; + size_t handshake_datalen; + + // certificate_request + const uint8_t *request_context; + size_t request_context_len; + const uint8_t *exts; + size_t extslen; + + // extensions + const uint8_t *signature_algorithms = NULL; + size_t signature_algorithms_len; + const uint8_t *signature_algorithms_cert = NULL; + size_t signature_algorithms_cert_len; + const uint8_t *certificate_authorities = NULL; + size_t certificate_authorities_len; + const uint8_t *oid_filters = NULL; + size_t oid_filters_len; + + // recv {CertififcateRequest*} + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { + error_print(); + } + return ret; } + if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, enced_record, enced_recordlen, - record, &recordlen) != 1) { + conn->server_seq_num, conn->record, conn->recordlen, + conn->plain_record, &conn->plain_recordlen) != 1) { error_print(); tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; + return -1; } - if (tls_record_get_handshake(record, &type, &data, &datalen) != 1) { + + if (tls_record_get_handshake(conn->plain_record, + &handshake_type, &handshake_data, &handshake_datalen) != 1) { error_print(); - tls_send_alert(conn, TLS_alert_handshake_failure); - goto end; + tls_send_alert(conn, TLS_alert_decode_error); + return -1; } - if (type == TLS_handshake_certificate_request) { - tls_trace("recv {CertificateRequest*}\n"); - tls13_record_trace(stderr, record, recordlen, 0, 0); - if (tls13_record_get_handshake_certificate_request(record, - &request_context, &request_context_len, - &cert_request_exts, &cert_request_extslen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_handshake_failure); - goto end; - } - // 当前忽略 request_context 和 cert_request_exts - // request_context 应该为空,当前实现中不支持Post-Handshake Auth - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->server_seq_num); - - - // recv {Certificate} - if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_handshake_failure); - goto end; - } - if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, enced_record, enced_recordlen, - record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; - } - } else { - conn->client_certs_len = 0; - // 清空客户端签名密钥 + if (handshake_type != TLS_handshake_certificate_request) { + return 0; } - // recv {Certificate} + if ((ret = tls13_record_get_handshake_certificate_request(conn->plain_record, + &request_context, &request_context_len, &exts, &extslen)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + return 0; + } + tls_trace("recv {CertificateRequest*}\n"); + tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); + + if (request_context_len) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + + while (extslen) { + int ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } + switch (ext_type) { + case TLS_extension_signature_algorithms: + signature_algorithms = ext_data; + signature_algorithms_len = ext_datalen; + break; + + case TLS_extension_signature_algorithms_cert: + signature_algorithms_cert = ext_data; + signature_algorithms_cert_len = ext_datalen; + break; + + case TLS_extension_certificate_authorities: + certificate_authorities = ext_data; + certificate_authorities_len = ext_datalen; + break; + + case TLS_extension_oid_filters: + oid_filters = ext_data; + oid_filters_len = ext_datalen; + break; + default: + error_print(); + return -1; + } + } + + if (!signature_algorithms) { + error_print(); + tls_send_alert(conn, TLS_alert_missing_extension); // 这个Alert对吗? + return -1; + } + + if (signature_algorithms_cert) { + // 先做初步的筛选 + } + + // 然后用signature_algorithms做最后的筛选 + + + if (certificate_authorities) { + + } + + if (oid_filters) { + // 客户端可以忽略这些请求 + } + + + digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5); + + tls_seq_num_incr(conn->server_seq_num); + + return 1; +} + +int tls13_recv_server_certificate(TLS_CONNECT *conn) +{ + int ret; + const uint8_t *request_context; + size_t request_context_len; + const uint8_t *cert_list; + size_t cert_list_len; + const uint8_t *cert; + size_t certlen; + X509_KEY server_sign_key; + tls_trace("recv {Certificate}\n"); - tls13_record_trace(stderr, record, recordlen, 0, 0); - if (tls13_record_get_handshake_certificate(record, + + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { + error_print(); + } + return ret; + } + if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, conn->record, conn->recordlen, + conn->plain_record, &conn->plain_recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + return -1; + } + tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); + + if ((ret = tls13_record_get_handshake_certificate(conn->plain_record, &request_context, &request_context_len, - &cert_list, &cert_list_len) != 1) { + &cert_list, &cert_list_len)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { error_print(); tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; + return 0; } - if (tls13_process_certificate_list(cert_list, cert_list_len, conn->server_certs, &conn->server_certs_len) != 1) { + + // TLS 1.3中证书列表是由CertificateListEntry构成的 + // 其中包含一个证书和若干的扩展 + /* + CertificateListEntry中没有必选的扩展 + 可选的扩展包括:status_request, signed_certificate_timestamp + 不能存在的扩展:certificate_authorities,server_name + */ + + if (tls13_process_certificate_list(cert_list, cert_list_len, + conn->server_certs, &conn->server_certs_len) != 1) { error_print(); tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; + return -1; } + + if (x509_certs_get_cert_by_index(conn->server_certs, conn->server_certs_len, 0, &cert, &certlen) != 1 || x509_cert_get_subject_public_key(cert, certlen, &server_sign_key) != 1) { error_print(); tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; + return -1; } + if (server_sign_key.algor != OID_ec_public_key || server_sign_key.algor_param != OID_sm2) { error_print(); tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; + return -1; } - digest_update(&dgst_ctx, record + 5, recordlen - 5); + digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5); tls_seq_num_incr(conn->server_seq_num); // verify ServerCertificate @@ -1750,550 +3231,1203 @@ int tls13_do_connect(TLS_CONNECT *conn) conn->ca_certs, conn->ca_certs_len, X509_MAX_VERIFY_DEPTH, &verify_result) != 1) { error_print(); tls_send_alert(conn, TLS_alert_bad_certificate); - goto end; + return -1; } + return 1; +} + +int tls13_recv_certificate_verify(TLS_CONNECT *conn) +{ + int ret; + int sig_alg; + const uint8_t *sig; + size_t siglen; + X509_KEY server_key; + const uint8_t *cert; + size_t certlen; + // recv {CertificateVerify} tls_trace("recv {CertificateVerify}\n"); - if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; + + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { + error_print(); + } + return ret; } + + // 可能已经被解密好了 if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, enced_record, enced_recordlen, - record, &recordlen) != 1) { + conn->server_seq_num, conn->record, conn->recordlen, + conn->plain_record, &conn->plain_recordlen) != 1) { error_print(); tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; + return -1; } - tls13_record_trace(stderr, record, recordlen, 0, 0); - if (tls13_record_get_handshake_certificate_verify(record, - &server_sign_algor, &server_sig, &server_siglen) != 1) { + + tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); + + + if ((ret = tls13_record_get_handshake_certificate_verify(conn->plain_record, + &sig_alg, &sig, &siglen)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { error_print(); tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; + return -1; } - if (server_sign_algor != TLS_sig_sm2sig_sm3) { + + // sig_alg in ClientHello.signature_algorithms + if (tls_type_is_in_list(sig_alg, conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + + // sig_alg match server's certificate + if (x509_certs_get_cert_by_index(conn->server_certs, conn->server_certs_len, 0, &cert, &certlen) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &server_key) != 1) { error_print(); tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; + return -1; } - if (tls13_verify_certificate_verify(TLS_server_mode, &server_sign_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, &dgst_ctx, server_sig, server_siglen) != 1) { + switch (server_key.algor_param) { + case OID_sm2: + if (sig_alg != TLS_sig_sm2sig_sm3) { + error_print(); + return -1; + } + break; + case OID_secp256r1: + if (sig_alg != TLS_sig_ecdsa_secp256r1_sha256) { + error_print(); + return -1; + } + break; + default: error_print(); - goto end; + return -1; } - digest_update(&dgst_ctx, record + 5, recordlen - 5); + + // verify signature + if (tls13_verify_certificate_verify(TLS_server_mode, + &server_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, + &conn->dgst_ctx, sig, siglen) != 1) { + error_print(); + return -1; + } + + digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5); + tls_seq_num_incr(conn->server_seq_num); + return 1; +} - // use Transcript-Hash(Handshake Context, Certificate*, CertificateVerify*) - tls13_compute_verify_data(server_handshake_traffic_secret, - &dgst_ctx, verify_data, &verify_data_len); +int tls13_recv_server_finished(TLS_CONNECT *conn) +{ + int ret; + const uint8_t *server_verify_data; + size_t server_verify_data_len; + uint8_t verify_data[64]; + size_t verify_data_len; + + // compute verify_data before digest_update + tls13_compute_verify_data(conn->server_handshake_traffic_secret, + &conn->dgst_ctx, verify_data, &verify_data_len); - // recv {Finished} tls_trace("recv {Finished}\n"); - if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { + error_print(); + } + return ret; } + if (tls13_record_decrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, enced_record, enced_recordlen, - record, &recordlen) != 1) { + conn->server_seq_num, conn->record, conn->recordlen, + conn->plain_record, &conn->plain_recordlen) != 1) { error_print(); tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; + return -1; } - tls13_record_trace(stderr, record, recordlen, 0, 0); - if (tls13_record_get_handshake_finished(record, - &server_verify_data, &server_verify_data_len) != 1) { + tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); + digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5); + tls_seq_num_incr(conn->server_seq_num); + + if ((ret = tls13_record_get_handshake_finished(conn->plain_record, + &server_verify_data, &server_verify_data_len)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { error_print(); tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; + return -1; } + if (server_verify_data_len != verify_data_len || memcmp(server_verify_data, verify_data, verify_data_len) != 0) { error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; + tls_send_alert(conn, TLS_alert_bad_record_mac); + return -1; } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->server_seq_num); - // generate server_application_traffic_secret - /* [12] */ tls13_derive_secret(master_secret, "s ap traffic", &dgst_ctx, server_application_traffic_secret); + /* [12] */ tls13_derive_secret(conn->master_secret, "s ap traffic", &conn->dgst_ctx, conn->server_application_traffic_secret); // generate client_application_traffic_secret - /* [11] */ tls13_derive_secret(master_secret, "c ap traffic", &dgst_ctx, client_application_traffic_secret); + /* [11] */ tls13_derive_secret(conn->master_secret, "c ap traffic", &conn->dgst_ctx, conn->client_application_traffic_secret); + return 1; +} - if (conn->client_certs_len) { - int client_sign_algor; - uint8_t sig[TLS_MAX_SIGNATURE_SIZE]; - size_t siglen; +int tls13_send_client_certificate(TLS_CONNECT *conn) +{ + int ret; + int client_sign_algor; + uint8_t sig[TLS_MAX_SIGNATURE_SIZE]; + size_t siglen; - // send client {Certificate*} - tls_trace("send {Certificate*}\n"); - if (tls13_record_set_handshake_certificate(record, &recordlen, - NULL, 0, // certificate_request_context - conn->client_certs, conn->client_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - tls13_padding_len_rand(&padding_len); - if (tls13_record_encrypt(&conn->client_write_key, conn->client_write_iv, - conn->client_seq_num, record, recordlen, padding_len, - enced_record, &enced_recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->client_seq_num); + size_t padding_len; + // send client {Certificate*} + tls_trace("send {Certificate*}\n"); - // send {CertificateVerify*} - tls_trace("send {CertificateVerify*}\n"); - client_sign_algor = TLS_sig_sm2sig_sm3; // FIXME: 应该放在conn里面 - tls13_sign_certificate_verify(TLS_client_mode, &conn->sign_key.u.sm2_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, &dgst_ctx, sig, &siglen); - if (tls13_record_set_handshake_certificate_verify(record, &recordlen, - client_sign_algor, sig, siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - tls13_padding_len_rand(&padding_len); - if (tls13_record_encrypt(&conn->client_write_key, conn->client_write_iv, - conn->client_seq_num, record, recordlen, padding_len, - enced_record, &enced_recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->client_seq_num); + const uint8_t *request_context = NULL; + size_t request_context_len = 0; + const uint8_t *exts; + size_t extslen = 0; + + if (tls13_record_set_handshake_certificate(conn->plain_record, &conn->plain_recordlen, + request_context, request_context_len, + conn->client_certs, conn->client_certs_len, + exts, extslen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; } + tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); + tls13_padding_len_rand(&padding_len); + + if (tls13_record_encrypt(&conn->client_write_key, conn->client_write_iv, + conn->client_seq_num, conn->plain_record, conn->plain_recordlen, padding_len, + conn->record, &conn->recordlen) != 1) { + error_print(); + return -1; + } + + if (tls_record_send(conn->record, conn->recordlen, conn->sock) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + + digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5); + tls_seq_num_incr(conn->client_seq_num); + + return 1; +} + +int tls13_send_certificate_verify(TLS_CONNECT *conn) +{ + int ret; + int sig_alg; + uint8_t sig[256]; + size_t siglen; + size_t padding_len; + + // send {CertificateVerify*} + tls_trace("send {CertificateVerify*}\n"); + + switch (conn->sign_key.algor_param) { + case OID_sm2: + sig_alg = TLS_sig_sm2sig_sm3; + break; + case OID_secp256r1: + sig_alg = TLS_sig_ecdsa_secp256r1_sha256; + break; + default: + error_print(); + return -1; + } + + tls13_sign_certificate_verify(TLS_client_mode, + &conn->sign_key.u.sm2_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, + &conn->dgst_ctx, sig, &siglen); + + if (tls13_record_set_handshake_certificate_verify( + conn->plain_record, &conn->plain_recordlen, + sig_alg, sig, siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); + + digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5); + + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->client_write_key, conn->client_write_iv, + conn->client_seq_num, conn->plain_record, conn->plain_recordlen, padding_len, + conn->record, &conn->recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + + tls_seq_num_incr(conn->client_seq_num); + + return 1; +} + +int tls13_send_client_finished(TLS_CONNECT *conn) +{ + int ret; + uint8_t verify_data[64]; + size_t verify_data_len; + size_t padding_len; + + uint8_t server_write_key[16]; + uint8_t client_write_key[16]; // send Client {Finished} tls_trace("send {Finished}\n"); - tls13_compute_verify_data(client_handshake_traffic_secret, &dgst_ctx, verify_data, &verify_data_len); - if (tls_record_set_handshake_finished(record, &recordlen, verify_data, verify_data_len) != 1) { + + tls13_compute_verify_data(conn->client_handshake_traffic_secret, &conn->dgst_ctx, + verify_data, &verify_data_len); + + if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen, + verify_data, verify_data_len) != 1) { error_print(); tls_send_alert(conn, TLS_alert_internal_error); - goto end; + return -1; } - tls13_record_trace(stderr, record, recordlen, 0, 0); + tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); + digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5); + tls13_padding_len_rand(&padding_len); if (tls13_record_encrypt(&conn->client_write_key, conn->client_write_iv, - conn->client_seq_num, record, recordlen, padding_len, - enced_record, &enced_recordlen) != 1) { + conn->client_seq_num, conn->plain_record, conn->plain_recordlen, padding_len, + conn->record, &conn->recordlen) != 1) { error_print(); tls_send_alert(conn, TLS_alert_internal_error); - goto end; + return -1; } - if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { - error_print(); - goto end; + + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; } - digest_update(&dgst_ctx, record + 5, recordlen - 5); + tls_seq_num_incr(conn->client_seq_num); - - // update server_write_key, server_write_iv, reset server_seq_num - tls13_hkdf_expand_label(digest, server_application_traffic_secret, "key", NULL, 0, 16, server_write_key); - block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); - tls13_hkdf_expand_label(digest, server_application_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); + 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); memset(conn->server_seq_num, 0, 8); - /* + format_print(stderr, 0, 0, "update server secrets\n"); 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_print(stderr, 0, 0, "\n"); - */ //update client_write_key, client_write_iv, reset client_seq_num - tls13_hkdf_expand_label(digest, client_application_traffic_secret, "key", NULL, 0, 16, client_write_key); - tls13_hkdf_expand_label(digest, client_application_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); - block_cipher_set_encrypt_key(&conn->client_write_key, cipher, client_write_key); + tls13_hkdf_expand_label(conn->digest, conn->client_application_traffic_secret, "key", NULL, 0, 16, client_write_key); + tls13_hkdf_expand_label(conn->digest, conn->client_application_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); + block_cipher_set_encrypt_key(&conn->client_write_key, conn->cipher, client_write_key); memset(conn->client_seq_num, 0, 8); - /* 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"); - */ - if (!conn->quiet) - fprintf(stderr, "Connection established\n"); - - ret = 1; - -end: - gmssl_secure_clear(&client_ecdhe, sizeof(client_ecdhe)); - gmssl_secure_clear(&server_sign_key, sizeof(server_sign_key)); - gmssl_secure_clear(psk, sizeof(psk)); - gmssl_secure_clear(early_secret, sizeof(early_secret)); - gmssl_secure_clear(handshake_secret, sizeof(handshake_secret)); - gmssl_secure_clear(master_secret, sizeof(master_secret)); - gmssl_secure_clear(client_handshake_traffic_secret, sizeof(client_handshake_traffic_secret)); - gmssl_secure_clear(server_handshake_traffic_secret, sizeof(server_handshake_traffic_secret)); - gmssl_secure_clear(client_application_traffic_secret, sizeof(client_application_traffic_secret)); - gmssl_secure_clear(server_application_traffic_secret, sizeof(server_application_traffic_secret)); - gmssl_secure_clear(client_write_key, sizeof(client_write_key)); - gmssl_secure_clear(server_write_key, sizeof(server_write_key)); - return ret; + return 1; } -int tls13_do_accept(TLS_CONNECT *conn) + + + + + + + + + +int tls13_recv_client_hello(TLS_CONNECT *conn) { - int ret = -1; + int ret; uint8_t *record = conn->record; size_t recordlen; - uint8_t enced_record[25600]; - size_t enced_recordlen = sizeof(enced_record); - - int server_ciphers[] = { TLS_cipher_sm4_gcm_sm3 }; + int client_verify = 0; int protocol; + + // client_hello + int legacy_version; const uint8_t *random; - const uint8_t *session_id; - size_t session_id_len; - const uint8_t *client_exts; - size_t client_exts_len; + const uint8_t *legacy_session_id; + size_t legacy_session_id_len; + const uint8_t *cipher_suites; + size_t cipher_suites_len; + const uint8_t *legacy_comp_methods; + size_t legacy_comp_methods_len; + const uint8_t *exts; + size_t extslen; - uint8_t client_random[32]; - uint8_t server_random[32]; - const uint8_t *client_ciphers; - size_t client_ciphers_len; - uint8_t server_exts[TLS_MAX_EXTENSIONS_SIZE]; - size_t server_exts_len; + // extensions + const uint8_t *supported_versions = NULL; + size_t supported_versions_len; + const uint8_t *supported_groups = NULL; + size_t supported_groups_len; + const uint8_t *key_share = NULL; + size_t key_share_len; + const uint8_t *signature_algorithms = NULL; + size_t signature_algorithms_len; - SM2_KEY server_ecdhe; - SM2_KEY client_ecdhe_public; - X509_KEY client_sign_key; - const BLOCK_CIPHER *cipher = NULL; - const DIGEST *digest = NULL; - DIGEST_CTX dgst_ctx; - DIGEST_CTX null_dgst_ctx; + // parameters + int common_versions[3]; + size_t common_versions_cnt; + int selected_version; + int common_groups[2]; + size_t common_groups_cnt; + int key_share_group; + const uint8_t *key_exchange; + size_t key_exchange_len; + + // 这个判断应该改为一个函数 + /* + if (client_verify) + tls_client_verify_init(&conn->client_verify_ctx); + */ + + + + tls_trace("recv ClientHello\n"); + + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { + error_print(); + } + return ret; + } + tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); + + if (tls_record_protocol(record) != TLS_protocol_tls1) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + return -1; + } + if ((ret = tls_record_get_handshake_client_hello(conn->record, + &legacy_version, &random, &legacy_session_id, &legacy_session_id_len, + &cipher_suites, &cipher_suites_len, &exts, &extslen)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + + // legacy_version + if (legacy_version != TLS_protocol_tls12) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + return -1; + } + + // random + memcpy(conn->client_random, random, 32); + + // legacy_session_id + if (legacy_session_id_len) { + // tls13 server ignore legacy_session_id + warning_print(); + } + + // cipher_suites + if ((ret = tls_cipher_suites_select(cipher_suites, cipher_suites_len, + conn->cipher_suites, conn->cipher_suites_cnt, + &conn->cipher_suite)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + return -1; + } + format_print(stderr, 0, 0, "cipher_suite: %s\n", tls_cipher_suite_name(conn->cipher_suite)); + tls13_cipher_suite_get(conn->cipher_suite, &conn->cipher, &conn->digest); + + while (extslen) { + int ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } + if (!ext_datalen) { + // following extensions should not be empty + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } + + switch (ext_type) { + case TLS_extension_supported_versions: + if (supported_versions) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + supported_versions = ext_data; + supported_versions_len = ext_datalen; + break; + + case TLS_extension_supported_groups: + if (supported_groups) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + supported_groups = ext_data; + supported_groups_len = ext_datalen; + break; + + case TLS_extension_key_share: + if (key_share) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + key_share = ext_data; + key_share_len = ext_datalen; + break; + + case TLS_extension_signature_algorithms: + if (signature_algorithms) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + signature_algorithms = ext_data; + signature_algorithms_len = ext_datalen; + break; + + default: + warning_print(); + } + } + + // supported_versions + if (!supported_versions) { + error_print(); + tls_send_alert(conn, TLS_alert_missing_extension); + return -1; + } + if ((ret = tls13_process_client_supported_versions( + supported_versions, supported_versions_len, // client_versions + conn->ctx->supported_versions, conn->ctx->supported_versions_cnt, // server versions + common_versions, &common_versions_cnt, + sizeof(common_versions)/sizeof(common_versions[0]))) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } // 这里要处理ret == 0 吗? + if (common_versions_cnt == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + return -1; + } + if (common_versions[0] != TLS_protocol_tls13) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + return -1; + } + format_print(stderr, 0, 0, "version: %s\n", tls_protocol_name(common_versions[0])); + + + // supported_groups + if (!supported_groups) { + error_print(); + tls_send_alert(conn, TLS_alert_missing_extension); + return -1; + } + // 查找有没有服务器支持的group + if ((ret = tls_process_supported_groups(supported_groups, supported_groups_len, + conn->ctx->supported_groups, conn->ctx->supported_groups_cnt, + common_groups, &common_groups_cnt, + sizeof(common_groups)/sizeof(common_groups[0]))) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + return -1; + } + format_print(stderr, 0, 0, "common_group: %s\n", tls_named_curve_name(common_groups[0])); + + + + // key_share + if (!key_share) { + error_print(); + tls_send_alert(conn, TLS_alert_missing_extension); + return -1; + } + if ((ret = tls13_process_key_share_client_hello(key_share, key_share_len, + common_groups, common_groups_cnt, + &key_share_group, &key_exchange, &key_exchange_len)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + return -1; + } + if (key_exchange_len != 65) { + error_print(); + return -1; + } + conn->key_exchange_group = key_share_group; + memcpy(conn->peer_ecdh_point, key_exchange, key_exchange_len); + conn->peer_ecdh_point_len = key_exchange_len; + + format_print(stderr, 0, 0, "key_share_group: %s\n", tls_named_curve_name(key_share_group)); + + + // signature_algorithms + if (!signature_algorithms) { + error_print(); + tls_send_alert(conn, TLS_alert_missing_extension); + return -1; + } + + int selected_sig_alg; + size_t selected_sig_algs_cnt; + + if ((ret = tls_process_signature_algorithms( + signature_algorithms, signature_algorithms_len, + conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt, + &selected_sig_alg, &selected_sig_algs_cnt, 1)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + return -1; + } + format_print(stderr, 0, 0, "sig_alg: %s\n", tls_signature_scheme_name(selected_sig_alg)); + + + + // cipher_suite, key_share_group, sig_alg compatible + + switch (conn->cipher_suite) { + case TLS_cipher_sm4_gcm_sm3: + if (key_share_group != TLS_curve_sm2p256v1 + || selected_sig_alg != TLS_sig_sm2sig_sm3) { + error_print(); + tls_send_alert(conn, TLS_alert_insufficient_security); + return -1; + } + break; + case TLS_cipher_aes_128_gcm_sha256: + if (key_share_group != TLS_curve_secp256r1 + || selected_sig_alg != TLS_sig_ecdsa_secp256r1_sha256) { + error_print(); + tls_send_alert(conn, TLS_alert_insufficient_security); + return -1; + } + break; + default: + error_print(); + return -1; + } + + digest_init(&conn->dgst_ctx, conn->digest); + digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5); + + if (client_verify) + tls_client_verify_update(&conn->client_verify_ctx, conn->record + 5, conn->recordlen - 5); + + tls_clean_record(conn); + + return 1; +} + +int tls13_send_server_hello(TLS_CONNECT *conn) +{ + int ret; + + tls_trace("send ServerHello\n"); + + if (conn->recordlen == 0) { + uint8_t exts[256]; + uint8_t *p = exts; + size_t extslen = 0; + int curve_oid; + + tls_record_set_protocol(conn->record, TLS_protocol_tls12); + if (rand_bytes(conn->server_random, 32) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + if ((curve_oid = tls_named_curve_oid(conn->key_exchange_group)) == OID_undef) { + error_print(); + return -1; + } + if (x509_key_generate(&conn->ecdh_key, OID_ec_public_key, &curve_oid, sizeof(curve_oid)) != 1) { + error_print(); + return -1; + } + if (tls13_server_supported_versions_ext_to_bytes(TLS_protocol_tls13, &p, &extslen) != 1 + || tls13_key_share_server_hello_ext_to_bytes(&conn->ecdh_key, &p, &extslen) != 1) { + error_print(); + return -1; + } + if (tls_record_set_handshake_server_hello(conn->record, &conn->recordlen, + TLS_protocol_tls12, conn->server_random, NULL, 0, + conn->cipher_suite, exts, extslen) != 1) { + error_print(); + return -1; + } + tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); + } + + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + + digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5); + + if (conn->ca_certs_len) { + tls_client_verify_update(&conn->client_verify_ctx, conn->record + 5, conn->recordlen - 5); + } + + tls_clean_record(conn); + return 1; +} + + + + +int tls13_send_hello_retry_request(TLS_CONNECT *conn) +{ + int ret; + + tls_trace("send HelloRetryRequest\n"); + + if (conn->recordlen == 0) { + uint8_t exts[256]; + uint8_t *p = exts; + size_t extslen = 0; + int curve_oid; + + tls_record_set_protocol(conn->record, TLS_protocol_tls12); + + if (rand_bytes(conn->server_random, 32) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + + // extensions: + // supported_versions + // key_share + if (tls13_server_supported_versions_ext_to_bytes(TLS_protocol_tls13, &p, &extslen) != 1 + || tls13_key_share_hello_retry_request_ext_to_bytes(conn->key_exchange_group, &p, &extslen) != 1) { + error_print(); + return -1; + } + if (tls_record_set_handshake_server_hello(conn->record, &conn->recordlen, + TLS_protocol_tls12, conn->server_random, NULL, 0, + conn->cipher_suite, exts, extslen) != 1) { + error_print(); + return -1; + } + tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); + + } + + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + + digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5); + + if (conn->ca_certs_len) { + tls_client_verify_update(&conn->client_verify_ctx, conn->record + 5, conn->recordlen - 5); + } + + tls_clean_record(conn); + return 1; + + + return 1; +} + + + + + + + + + + + +int tls13_send_encrypted_extensions(TLS_CONNECT *conn) +{ + int ret; + tls_trace("send {EncryptedExtensions}\n"); + + if (conn->recordlen == 0) { + uint8_t exts[256]; + uint8_t *p = exts; + size_t extslen = 0; + size_t padding_len; + + tls_record_set_protocol(conn->plain_record, TLS_protocol_tls12); + + // supported_groups + if (tls_supported_groups_ext_to_bytes(conn->ctx->supported_groups, + conn->ctx->supported_groups_cnt, &p, &extslen) != 1) { + error_print(); + return -1; + } + if (tls13_record_set_handshake_encrypted_extensions( + conn->plain_record, &conn->plain_recordlen, + exts, extslen) != 1) { + error_print(); + return -1; + } + tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); + digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5); + + tls13_padding_len_rand(&padding_len); + + if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, conn->plain_record, conn->plain_recordlen, padding_len, + conn->record, &conn->recordlen) != 1) { + error_print(); + return -1; + } + } + + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + + tls_seq_num_incr(conn->server_seq_num); + + if (conn->ca_certs_len) { + tls_client_verify_update(&conn->client_verify_ctx, conn->record + 5, conn->recordlen - 5); + } + + tls_clean_record(conn); + return 1; +} + +int tls13_send_certificate_request(TLS_CONNECT *conn) +{ + int ret; + tls_trace("send {CertificateRequest*}\n"); + + const uint8_t *request_context = NULL; + size_t request_context_len = 0; + + if (conn->recordlen == 0) { + uint8_t exts[256]; + uint8_t *p = exts; + size_t extslen = 0; + int sig_algs[1]; + int sig_algs_cnt = 1; + size_t padding_len; + uint8_t ca_names[256]; + size_t ca_names_len; + + switch (conn->cipher_suite) { + case TLS_cipher_sm4_gcm_sm3: + sig_algs[0] = TLS_sig_sm2sig_sm3; + break; + case TLS_cipher_aes_128_gcm_sha256: + sig_algs[0] = TLS_sig_ecdsa_secp256r1_sha256; + break; + default: + error_print(); + return -1; + } + + // 这里要从服务器证书中找到所有的CA的名字 + + if (tls_signature_algorithms_ext_to_bytes(sig_algs, sig_algs_cnt, &p, &extslen) != 1 + || tls13_signature_algorithms_cert_ext_to_bytes(sig_algs, sig_algs_cnt, &p, &extslen) != 1 + || tls13_certificate_authorities_ext_to_bytes(ca_names, ca_names_len, &p, &extslen) != 1) { + error_print(); + return -1; + } + + if (tls13_record_set_handshake_certificate_request( + conn->plain_record, &conn->plain_recordlen, + request_context, request_context_len, exts, extslen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + + tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); + tls13_padding_len_rand(&padding_len); + + + if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, conn->plain_record, conn->plain_recordlen, padding_len, + conn->record, &conn->recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5); + tls_seq_num_incr(conn->server_seq_num); + + + + } + + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + + return 1; +} + + +/* +struct { + CertificateStatusType status_type; + select (status_type) { + case ocsp: + OCSPResponse response; + }; +} CertificateStatus; + +OCSPResponse ::= SEQUENCE { + responseStatus OCSPResponseStatus, + responseBytes [0] EXPLICIT ResponseBytes OPTIONAL +} + +OCSPResponseStatus ::= ENUMERATED { + successful (0), -- 响应有效 + malformedRequest (1), -- 请求格式错误 + internalError (2), -- 服务器内部错误 + tryLater (3), -- 稍后重试 + -- 状态码 4 未使用 + sigRequired (5), -- 必须签名 + unauthorized (6) -- 未授权 +} + +ResponseBytes ::= SEQUENCE { + responseType OBJECT IDENTIFIER, + response OCTET STRING +} + +-- 当 responseType 为 id-pkix-ocsp-basic 时,response 包含 BasicOCSPResponse +BasicOCSPResponse ::= SEQUENCE { + tbsResponseData ResponseData, + signatureAlgorithm AlgorithmIdentifier, + signature BIT STRING, + certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL +} +*/ + +int tls13_send_server_certificate(TLS_CONNECT *conn) +{ + int ret; + + // send Server {Certificate} + tls_trace("send {Certificate}\n"); + + if (conn->recordlen == 0) { + const uint8_t *request_context = NULL; + size_t request_context_len = 0; + uint8_t exts_list[256]; + size_t exts_list_len = 0; + uint8_t exts[128]; + uint8_t *p = exts; + size_t extslen = 0; + size_t padding_len; + + // CertificateEntry.extensions + if (conn->ctx->certificate_status_len) { + if (tls_ext_to_bytes(TLS_extension_status_request, + conn->ctx->certificate_status, conn->ctx->certificate_status_len, + &p, &extslen) != 1) { + error_print(); + return -1; + } + } + if (conn->ctx->signed_certificate_timestamp_len) { + if (tls_ext_to_bytes(TLS_extension_signed_certificate_timestamp, + conn->ctx->signed_certificate_timestamp, conn->ctx->signed_certificate_timestamp_len, + &p, &extslen) != 1) { + error_print(); + return -1; + } + } + p = exts_list; + tls_uint16array_to_bytes(exts, extslen, &p, &exts_list_len); + + if (tls13_record_set_handshake_certificate(conn->plain_record, &conn->plain_recordlen, + request_context, request_context_len, + conn->server_certs, conn->server_certs_len, + exts_list, exts_list_len) != 1) { + error_print(); + return -1; + } + + tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); + digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5); + + tls13_padding_len_rand(&padding_len); + + if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, conn->plain_record, conn->plain_recordlen, padding_len, + conn->record, &conn->recordlen) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(conn->server_seq_num); + } + + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + + return 1; +} + +int tls13_send_server_certificate_verify(TLS_CONNECT *conn) +{ + int ret; + + // send Server {CertificateVerify} + tls_trace("send {CertificateVerify}\n"); + + if (conn->recordlen == 0) { + uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; + size_t siglen; + size_t padding_len; + + tls13_sign_certificate_verify(TLS_server_mode, + &conn->sign_key.u.sm2_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, + &conn->dgst_ctx, sig, &siglen); + + // 服务器的签名算法实际上是由签名密钥决定的,目前签名密钥(曲线)决定了签名算法 + // 一个签名算法目前不支持可选的哈希函数,因此这个就决定了 + + // 这段代码要挪到server_hello后者之后 + switch (conn->sign_key.algor_param) { + case OID_sm2: + conn->sig_alg = TLS_sig_sm2sig_sm3; + break; + case OID_secp256r1: + conn->sig_alg = TLS_sig_ecdsa_secp256r1_sha256; + break; + default: + error_print(); + return -1; + } + + + if (tls13_record_set_handshake_certificate_verify( + conn->plain_record, &conn->plain_recordlen, + conn->sig_alg, sig, siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); + digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5); + + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, conn->plain_record, conn->plain_recordlen, padding_len, + conn->record, &conn->recordlen) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(conn->server_seq_num); + + } + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + return 1; +} + +int tls13_send_server_finished(TLS_CONNECT *conn) +{ + int ret; size_t padding_len; + tls_trace("send {Finished}\n"); - uint8_t sig[TLS_MAX_SIGNATURE_SIZE]; - size_t siglen = sizeof(sig); - uint8_t verify_data[32]; - size_t verify_data_len; + if (conn->recordlen == 0) { + uint8_t verify_data[64]; + size_t verify_data_len; - const uint8_t *client_verify_data; - size_t client_verify_data_len; + // compute server verify_data before digest_update() + tls13_compute_verify_data(conn->server_handshake_traffic_secret, + &conn->dgst_ctx, verify_data, &verify_data_len); - uint8_t client_write_key[16]; - uint8_t server_write_key[16]; + if (tls13_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen, + verify_data, verify_data_len) != 1) { + error_print(); + return -1; + } + tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); + digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5); - uint8_t zeros[32] = {0}; - uint8_t psk[32] = {0}; - uint8_t early_secret[32]; - uint8_t handshake_secret[32]; - uint8_t client_handshake_traffic_secret[32]; - uint8_t server_handshake_traffic_secret[32]; - uint8_t client_application_traffic_secret[32]; - uint8_t server_application_traffic_secret[32]; - uint8_t master_secret[32]; + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, conn->plain_record, conn->plain_recordlen, padding_len, + conn->record, &conn->recordlen) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(conn->server_seq_num); + + // generate server_application_traffic_secret + /* 12 */ tls13_derive_secret(conn->master_secret, "s ap traffic", &conn->dgst_ctx, conn->server_application_traffic_secret); + // Generate client_application_traffic_secret + /* 11 */ tls13_derive_secret(conn->master_secret, "c ap traffic", &conn->dgst_ctx, conn->client_application_traffic_secret); + // 因为后面还要解密握手消息,因此client application key, iv 等到握手结束之后再更新 + } + + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + + return 1; +} + +int tls13_recv_client_certificate(TLS_CONNECT *conn) +{ + int ret; + size_t padding_len; + + tls_trace("recv {Certificate*}\n"); + + + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { + error_print(); + } + return ret; + } + tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); + + if (tls_record_protocol(conn->record) != TLS_protocol_tls12) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + return -1; + } + + if (tls13_record_decrypt(&conn->client_write_key, conn->client_write_iv, + conn->client_seq_num, conn->record, conn->recordlen, + conn->plain_record, &conn->plain_recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + return -1; + } + tls13_record_trace(stderr, conn->plain_record, conn->plain_recordlen, 0, 0); const uint8_t *request_context; size_t request_context_len; const uint8_t *cert_list; size_t cert_list_len; - const uint8_t *cert; - size_t certlen; - - int client_verify = 0; - if (conn->ca_certs_len) - client_verify = 1; - - - // 1. Recv ClientHello - tls_trace("recv ClientHello\n"); - if (tls_record_recv(record, &recordlen, conn->sock) != 1) { + if ((ret = tls13_record_get_handshake_certificate(conn->plain_record, + &request_context, &request_context_len, + &cert_list, &cert_list_len)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { error_print(); tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; + return 0; } - tls13_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_get_handshake_client_hello(record, - &protocol, &random, - &session_id, &session_id_len, // 不支持SessionID,不做任何处理 - &client_ciphers, &client_ciphers_len, - &client_exts, &client_exts_len) != 1) { + + // 这里要处理什么? + if (tls13_process_certificate_list(cert_list, cert_list_len, + conn->server_certs, &conn->server_certs_len) != 1) { error_print(); tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; + return -1; } - if (protocol != TLS_protocol_tls12) { - error_print(); - tls_send_alert(conn, TLS_alert_protocol_version); - goto end; - } - memcpy(client_random, random, 32); - if (tls_cipher_suites_select(client_ciphers, client_ciphers_len, - server_ciphers, sizeof(server_ciphers)/sizeof(int), - &conn->cipher_suite) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_insufficient_security); - goto end; - } - if (!client_exts) { - error_print(); - goto end; - } - tls13_cipher_suite_get(conn->cipher_suite, &digest, &cipher); // 这个函数是否应该放到tls_里面? - digest_init(&dgst_ctx, digest); - null_dgst_ctx = dgst_ctx; // 在密钥导出函数中可能输入的消息为空,因此需要一个空的dgst_ctx,这里不对了,应该在tls13_derive_secret里面直接支持NULL! - digest_update(&dgst_ctx, record + 5, recordlen - 5); - - // 2. Send ServerHello - tls_trace("send ServerHello\n"); - rand_bytes(server_random, 32); - sm2_key_generate(&server_ecdhe); - if (tls13_process_client_hello_exts(client_exts, client_exts_len, - &server_ecdhe, &client_ecdhe_public, - server_exts, &server_exts_len, sizeof(server_exts)) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tls_record_set_protocol(record, TLS_protocol_tls12); - if (tls_record_set_handshake_server_hello(record, &recordlen, - TLS_protocol_tls12, server_random, - NULL, 0, // openssl的兼容模式在ClientHello中发送SessionID并检查在ServerHello是否返回,用`-no_middlebox`可关闭兼容模式 - conn->cipher_suite, server_exts, server_exts_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - if (tls_record_send(record, recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - - - uint8_t share_point_x[32]; - sm2_do_ecdh(&server_ecdhe, &client_ecdhe_public, share_point_x); - - /* 1 */ tls13_hkdf_extract(digest, zeros, psk, early_secret); - /* 5 */ tls13_derive_secret(early_secret, "derived", &null_dgst_ctx, handshake_secret); - /* 6 */ tls13_hkdf_extract(digest, handshake_secret, share_point_x, handshake_secret); - /* 7 */ tls13_derive_secret(handshake_secret, "c hs traffic", &dgst_ctx, client_handshake_traffic_secret); - /* 8 */ tls13_derive_secret(handshake_secret, "s hs traffic", &dgst_ctx, server_handshake_traffic_secret); - /* 9 */ tls13_derive_secret(handshake_secret, "derived", &null_dgst_ctx, master_secret); - /* 10 */ tls13_hkdf_extract(digest, master_secret, zeros, master_secret); - // generate server_write_key, server_write_iv, reset server_seq_num - tls13_hkdf_expand_label(digest, server_handshake_traffic_secret, "key", NULL, 0, 16, server_write_key); - block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); - tls13_hkdf_expand_label(digest, server_handshake_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); - memset(conn->server_seq_num, 0, 8); - // generate client_write_key, client_write_iv, reset client_seq_num - tls13_hkdf_expand_label(digest, client_handshake_traffic_secret, "key", NULL, 0, 16, client_write_key); - block_cipher_set_encrypt_key(&conn->client_write_key, cipher, client_write_key); - tls13_hkdf_expand_label(digest, client_handshake_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); - memset(conn->client_seq_num, 0, 8); /* - format_print(stderr, 0, 0, "generate handshake secrets\n"); - 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, "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"); - */ - - // 3. Send {EncryptedExtensions} - tls_trace("send {EncryptedExtensions}\n"); - tls_record_set_protocol(record, TLS_protocol_tls12); - tls13_record_set_handshake_encrypted_extensions(record, &recordlen); - tls13_record_trace(stderr, record, recordlen, 0, 0); - tls13_padding_len_rand(&padding_len); - if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, record, recordlen, padding_len, - enced_record, &enced_recordlen) != 1) { + if (x509_certs_get_cert_by_index(conn->server_certs, conn->server_certs_len, 0, &cert, &certlen) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &server_sign_key) != 1) { error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - // FIXME: tls13_record_encrypt需要支持握手消息 - // tls_record_data(enced_record)[0] = TLS_handshake_encrypted_extensions; - if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->server_seq_num); - - - // send {CertificateRequest*} - if (client_verify) { - tls_trace("send {CertificateRequest*}\n"); - - // TODO: 设置certificate_request中的extensions! - if (tls13_record_set_handshake_certificate_request_default(record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - tls13_padding_len_rand(&padding_len); - if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, record, recordlen, padding_len, - enced_record, &enced_recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->server_seq_num); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; } - // send Server {Certificate} - tls_trace("send {Certificate}\n"); - if (tls13_record_set_handshake_certificate(record, &recordlen, NULL, 0, conn->server_certs, conn->server_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - tls13_padding_len_rand(&padding_len); - if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, record, recordlen, padding_len, - enced_record, &enced_recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->server_seq_num); - - // send Server {CertificateVerify} - tls_trace("send {CertificateVerify}\n"); - tls13_sign_certificate_verify(TLS_server_mode, &conn->sign_key.u.sm2_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, &dgst_ctx, sig, &siglen); - if (tls13_record_set_handshake_certificate_verify(record, &recordlen, - TLS_sig_sm2sig_sm3, sig, siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - tls13_padding_len_rand(&padding_len); - if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, record, recordlen, padding_len, - enced_record, &enced_recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->server_seq_num); - - - // Send Server {Finished} - tls_trace("send {Finished}\n"); - - // compute server verify_data before digest_update() - tls13_compute_verify_data(server_handshake_traffic_secret, - &dgst_ctx, verify_data, &verify_data_len); - if (tls13_record_set_handshake_finished(record, &recordlen, verify_data, verify_data_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - tls13_padding_len_rand(&padding_len); - if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, - conn->server_seq_num, record, recordlen, padding_len, - enced_record, &enced_recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; - } - if (tls_record_send(enced_record, enced_recordlen, conn->sock) != 1) { - error_print(); - goto end; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->server_seq_num); - - // generate server_application_traffic_secret - /* 12 */ tls13_derive_secret(master_secret, "s ap traffic", &dgst_ctx, server_application_traffic_secret); - // Generate client_application_traffic_secret - /* 11 */ tls13_derive_secret(master_secret, "c ap traffic", &dgst_ctx, client_application_traffic_secret); - // 因为后面还要解密握手消息,因此client application key, iv 等到握手结束之后再更新 - - // Recv Client {Certificate*} - if (client_verify) { - tls_trace("recv {Certificate*}\n"); - if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (tls13_record_decrypt(&conn->client_write_key, conn->client_write_iv, - conn->client_seq_num, enced_record, enced_recordlen, - record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - - if (tls13_record_get_handshake_certificate(record, - &request_context, &request_context_len, - &cert_list, &cert_list_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (tls13_process_certificate_list(cert_list, cert_list_len, conn->client_certs, &conn->client_certs_len) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (x509_certs_get_cert_by_index(conn->client_certs, conn->client_certs_len, 0, &cert, &certlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } if (x509_cert_get_subject_public_key(cert, certlen, &client_sign_key) != 1) { error_print(); tls_send_alert(conn, TLS_alert_bad_certificate); @@ -2317,122 +4451,1268 @@ int tls13_do_accept(TLS_CONNECT *conn) tls_send_alert(conn, TLS_alert_bad_certificate); goto end; } + */ + + return 1; +} + + +/* +struct { + SignatureScheme algorithm; + opaque signature<0..2^16-1>; +} CertificateVerify; +*/ +int tls13_recv_client_certificate_verify(TLS_CONNECT *conn) +{ + int ret; + + // CertificateVerify + int sig_alg; + const uint8_t *sig; + size_t siglen; + + tls_trace("recv Client {CertificateVerify*}\n"); + + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { + error_print(); + } + return ret; + } + tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); + + if (tls_record_protocol(conn->record) != TLS_protocol_tls12) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + return -1; } - // Recv client {CertificateVerify*} - if (client_verify) { - int client_sign_algor; - const uint8_t *client_sig; - size_t client_siglen; + if (tls13_record_decrypt(&conn->client_write_key, conn->client_write_iv, + conn->client_seq_num, conn->record, conn->recordlen, + conn->plain_record, &conn->plain_recordlen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_record_mac); + return -1; + } + tls13_record_trace(stderr, conn->plain_record, conn->plain_recordlen, 0, 0); - tls_trace("recv Client {CertificateVerify*}\n"); - if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (tls13_record_decrypt(&conn->client_write_key, conn->client_write_iv, - conn->client_seq_num, enced_record, enced_recordlen, record, &recordlen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; - } - tls13_record_trace(stderr, record, recordlen, 0, 0); - - if (tls13_record_get_handshake_certificate_verify(record, &client_sign_algor, &client_sig, &client_siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; - } - if (tls13_verify_certificate_verify(TLS_client_mode, &client_sign_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, &dgst_ctx, client_sig, client_siglen) != 1) { - error_print(); - tls_send_alert(conn, TLS_alert_decrypt_error); - goto end; - } - digest_update(&dgst_ctx, record + 5, recordlen - 5); - tls_seq_num_incr(conn->client_seq_num); + if ((ret = tls13_record_get_handshake_certificate_verify(conn->plain_record, + &sig_alg, &sig, &siglen)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; } - // 12. Recv Client {Finished} + /* + if (sig_alg != conn->client_sig_alg) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + + */ + X509_KEY client_sign_key; + + if (tls13_verify_certificate_verify(TLS_client_mode, + &client_sign_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, + &conn->dgst_ctx,sig, siglen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } + digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5); + tls_seq_num_incr(conn->client_seq_num); + + return 1; +} + +int tls13_recv_client_finished(TLS_CONNECT *conn) +{ + int ret; + + // Finished + uint8_t local_verify_data[64]; + size_t local_verify_data_len; + const uint8_t *verify_data; + size_t verify_data_len; tls_trace("recv {Finished}\n"); - if (tls_record_recv(enced_record, &enced_recordlen, conn->sock) != 1) { + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { + error_print(); + } + return ret; + } + tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); + + if (tls_record_protocol(conn->record) != TLS_protocol_tls12) { error_print(); - tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; + tls_send_alert(conn, TLS_alert_protocol_version); + return -1; } if (tls13_record_decrypt(&conn->client_write_key, conn->client_write_iv, - conn->client_seq_num, enced_record, enced_recordlen, - record, &recordlen) != 1) { + conn->client_seq_num, conn->record, conn->recordlen, + conn->plain_record, &conn->plain_recordlen) != 1) { error_print(); tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; + return -1; } - tls13_record_trace(stderr, record, recordlen, 0, 0); - if (tls13_record_get_handshake_finished(record, &client_verify_data, &client_verify_data_len) != 1) { + tls13_record_trace(stderr, conn->plain_record, conn->plain_recordlen, 0, 0); + + if ((ret = tls13_record_get_handshake_finished(conn->plain_record, + &verify_data, &verify_data_len)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { error_print(); tls_send_alert(conn, TLS_alert_unexpected_message); - goto end; + return -1; } - if (tls13_compute_verify_data(client_handshake_traffic_secret, &dgst_ctx, verify_data, &verify_data_len) != 1) { + + if (tls13_compute_verify_data(conn->client_handshake_traffic_secret, + &conn->dgst_ctx, local_verify_data, &local_verify_data_len) != 1) { error_print(); - tls_send_alert(conn, TLS_alert_internal_error); - goto end; + return -1; } - if (client_verify_data_len != verify_data_len - || memcmp(client_verify_data, verify_data, verify_data_len) != 0) { + if (local_verify_data_len != verify_data_len + || memcmp(local_verify_data, verify_data, verify_data_len) != 0) { error_print(); - tls_send_alert(conn, TLS_alert_bad_record_mac); - goto end; + tls_send_alert(conn, TLS_alert_decrypt_error); + return -1; } - digest_update(&dgst_ctx, record + 5, recordlen - 5); + digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5); tls_seq_num_incr(conn->client_seq_num); - // 注意:OpenSSL兼容模式在此处会收发ChangeCipherSpec报文 - + // 这里不对呀,有可能使用aes256吗? + uint8_t server_write_key[16]; + uint8_t client_write_key[16]; // update server_write_key, server_write_iv, reset server_seq_num - tls13_hkdf_expand_label(digest, server_application_traffic_secret, "key", NULL, 0, 16, server_write_key); - tls13_hkdf_expand_label(digest, server_application_traffic_secret, "iv", NULL, 0, 12, conn->server_write_iv); - block_cipher_set_encrypt_key(&conn->server_write_key, cipher, server_write_key); + 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); memset(conn->server_seq_num, 0, 8); - /* + format_print(stderr, 0, 0, "update server secrets\n"); 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_print(stderr, 0, 0, "\n"); - */ // update client_write_key, client_write_iv // reset client_seq_num - tls13_hkdf_expand_label(digest, client_application_traffic_secret, "key", NULL, 0, 16, client_write_key); - tls13_hkdf_expand_label(digest, client_application_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); - block_cipher_set_encrypt_key(&conn->client_write_key, cipher, client_write_key); + 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); memset(conn->client_seq_num, 0, 8); - /* + 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"); - */ - if (!conn->quiet) - fprintf(stderr, "Connection Established!\n\n"); - - ret = 1; -end: - gmssl_secure_clear(&server_ecdhe, sizeof(server_ecdhe)); - gmssl_secure_clear(&client_sign_key, sizeof(client_sign_key)); - gmssl_secure_clear(psk, sizeof(psk)); - gmssl_secure_clear(early_secret, sizeof(early_secret)); - gmssl_secure_clear(handshake_secret, sizeof(handshake_secret)); - gmssl_secure_clear(master_secret, sizeof(master_secret)); - gmssl_secure_clear(client_handshake_traffic_secret, sizeof(client_handshake_traffic_secret)); - gmssl_secure_clear(server_handshake_traffic_secret, sizeof(server_handshake_traffic_secret)); - gmssl_secure_clear(client_application_traffic_secret, sizeof(client_application_traffic_secret)); - gmssl_secure_clear(server_application_traffic_secret, sizeof(server_application_traffic_secret)); - gmssl_secure_clear(client_write_key, sizeof(client_write_key)); - gmssl_secure_clear(server_write_key, sizeof(server_write_key)); - return ret; + return 1; } + + +// 这个的总长度是48 + 2 + 8 == 58 +typedef struct { + uint8_t master_secret[48]; + uint16_t cipher_suite; + uint64_t timestamp; +} TLS_SESSION_TICKET; + + + + + +int tls13_send_new_session_ticket(TLS_CONNECT *conn) +{ + int ret; + size_t padding_len; + + if (conn->recordlen == 0) { + uint32_t ticket_lifetime; + uint32_t ticket_age_add; + uint8_t ticket_nonce[8]; + uint8_t ticket[255]; + size_t ticketlen; + uint8_t exts[16]; + size_t extslen = 0; + uint8_t *p = exts; + + uint8_t plain_ticket[58]; + + // early_data extension + uint32_t max_early_data_size; + + ticket_lifetime = 60 * 60 * 24 * 2; // = 2 days + if (rand_bytes((uint8_t *)&ticket_age_add, sizeof(ticket_age_add)) != 1) { + error_print(); + return -1; + } + if (rand_bytes(ticket_nonce, sizeof(ticket_nonce)) != 1) { + error_print(); + return -1; + } + + // ticket + memcpy(plain_ticket, conn->master_secret, 48); + p = plain_ticket + 48; + + size_t len = 0; + + //tls_cipher_suite_to_bytes(conn->cipher_suite, &p, &len); + //tls_uint64_to_bytes(timestamp, &p, &len); + + // 加密 + + + max_early_data_size = 256 * 1024; // 256 KB + /* + if (tls13_early_data_to_bytes(max_early_data_size, &p, &extslen) != 1) { + error_print(); + return -1; + } + */ + + /* + if (tls13_record_set_handshake_new_session_ticket( + conn->plain_record, &conn->plain_recordlen, + ticket_lifetime, ticket_age_add, + ticket_nonce, ticket, ticketlen, exts, extslen) != 1) { + error_print(); + return -1; + } + */ + + tls13_padding_len_rand(&padding_len); + if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, + conn->server_seq_num, conn->plain_record, conn->plain_recordlen, padding_len, + conn->record, &conn->recordlen) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(conn->server_seq_num); + } + + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + + return 1; +} + +int tls13_recv_new_session_ticket(TLS_CONNECT *conn) +{ + uint32_t ticket_lifetime; + uint32_t ticket_age_add; + const uint8_t *ticket_nonce; + const uint8_t *ticket; + const uint8_t *exts; + size_t ticket_nonce_len, ticketlen, extslen; + uint32_t max_early_data_size; + + const uint8_t *cp; + size_t len; + + if (tls_uint32_from_bytes(&ticket_lifetime, &cp, &len) != 1 + || tls_uint32_from_bytes(&ticket_age_add, &cp, &len) != 1 + || tls_uint8array_from_bytes(&ticket_nonce, &ticket_nonce_len, &cp, &len) != 1 + || tls_uint16array_from_bytes(&ticket, &ticketlen, &cp, &len) != 1 + || tls_uint16array_from_bytes(&exts, &extslen, &cp, &len) != 1 + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + if (ticket_lifetime || ticket_lifetime > 60 * 60 * 24 * 7) { + error_print(); + return -1; + } + if (!ticketlen) { + error_print(); + return -1; + } + while (extslen) { + int ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + return -1; + } + switch (ext_type) { + case TLS_extension_early_data: + /* + if (tls13_early_data_from_bytes(&max_early_data_size, ext_data, ext_datalen) != 1) { + error_print(); + return -1; + } + */ + break; + default: + error_print(); + return -1; + } + } + return 1; +} + + +/* +struct { + ProtocolVersion server_version; // 服务器选择的版本 + CipherSuite cipher_suite; // 服务器选择的密码套件 + Extension extensions<2..2^16-1>; // 扩展列表 +} HelloRetryRequest; +*/ + +int tls13_set_handshake_hello_retry_request(uint8_t *record, size_t *recordlen, + int server_version, int cipher_suite, const uint8_t *exts, size_t extslen) +{ + int type = TLS_handshake_hello_retry_request; + uint8_t *p = record + 5 + 4; + size_t len = 0; + + if (server_version != TLS_protocol_tls13) { + error_print(); + return -1; + } + if (extslen < 2) { + error_print(); + return -1; + } + tls_uint16_to_bytes(server_version, &p, &len); + tls_uint16_to_bytes(cipher_suite, &p, &len); + tls_uint16array_to_bytes(exts, extslen, &p, &len); + tls_record_set_handshake(record, recordlen, type, NULL, len); + return 1; +} + +int tls13_record_get_handshake_hello_retry_request(uint8_t *record, + int *server_version, int *cipher_suite, const uint8_t **exts, size_t *extslen) +{ + int type; + const uint8_t *cp; + size_t len; + uint16_t version; + uint16_t cipher; + + if (tls_record_get_handshake(record, &type, &cp, &len) != 1) { + error_print(); + return -1; + } + if (type != TLS_handshake_hello_retry_request) { + error_print(); + return 0; + } + if (tls_uint16_from_bytes(&version, &cp, &len) != 1 + || tls_uint16_from_bytes(&cipher, &cp, &len) != 1 + || tls_uint16array_from_bytes(exts, extslen, &cp, &len) != 1 + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + if (!tls_protocol_name(version)) { + error_print(); + return -1; + } + *server_version = version; + if (!tls_cipher_suite_name(cipher)) { + error_print(); + return -1; + } + *cipher_suite = cipher; + if (*extslen < 2) { + error_print(); + return -1; + } + return 1; +} + +int tls13_recv_hello_retry_request(TLS_CONNECT *conn) +{ + int ret; + + // server_hello + int legacy_version; + const uint8_t *random; + const uint8_t *legacy_session_id_echo; + size_t legacy_session_id_echo_len; + int cipher_suite; + const uint8_t *exts; + size_t extslen; + + // extensions + int selected_version = -1; + int key_share_group = -1; + + tls_trace("recv HelloRetryRequest\n"); + + // backup ClientHello record for handshake message digest + memcpy(conn->plain_record, conn->record, conn->recordlen); + conn->plain_recordlen = conn->recordlen; + + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { + error_print(); + } + return ret; + } + tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); + + + if (tls_record_protocol(conn->record) != TLS_protocol_tls12) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + return -1; + } + + if ((ret = tls_record_get_handshake_server_hello(conn->record, + &legacy_version, &random, + &legacy_session_id_echo, &legacy_session_id_echo_len, + &cipher_suite, &exts, &extslen)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + + // legacy_version + if (legacy_version != TLS_protocol_tls12) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + return -1; + } + + // random + memcpy(conn->server_random, random, 32); + + // legacy_session_id_echo + if (legacy_session_id_echo_len != conn->session_id_len + || memcmp(legacy_session_id_echo, conn->session_id, conn->session_id_len) != 0) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + + // cipher_suite + if (tls_type_is_in_list(cipher_suite, conn->cipher_suites, conn->cipher_suites_cnt) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + conn->cipher_suite = cipher_suite; + if (tls13_cipher_suite_get(cipher_suite, &conn->cipher, &conn->digest) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + + while (extslen) { + int ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } + + switch (ext_type) { + case TLS_extension_supported_versions: + if (tls13_server_supported_versions_from_bytes(&selected_version, + ext_data, ext_datalen) != 1) { + tls_send_alert(conn, TLS_alert_decode_error); + error_print(); + return -1; + } + if (tls_type_is_in_list(selected_version, + conn->ctx->supported_versions, conn->ctx->supported_versions_cnt) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + if (selected_version != TLS_protocol_tls13) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + break; + + case TLS_extension_key_share: + if (tls13_key_share_hello_retry_request_from_bytes(&key_share_group, + ext_data, ext_datalen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } + if (tls_type_is_in_list(key_share_group, conn->ctx->supported_groups, 2) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + break; + + // extensions MUST NOT be included + case TLS_extension_supported_groups: + case TLS_extension_signature_algorithms: + case TLS_extension_server_name: + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + break; + + // extensions can be ignored + case TLS_extension_pre_shared_key: + default: + warning_print(); + } + } + + if (selected_version < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_missing_extension); + return -1; + } + if (key_share_group < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + + digest_init(&conn->dgst_ctx, conn->digest); + digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5); + digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5); + + + if (conn->client_certs_len) { + sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); + } + + return 1; +} + +int tls13_send_client_hello_again(TLS_CONNECT *conn) +{ + + int ret; + + if (!conn->recordlen) { + const uint8_t *session_id = NULL; + size_t session_id_len = 0; + uint8_t exts[TLS_MAX_EXTENSIONS_SIZE]; + uint8_t *p = exts; + size_t extslen = 0; + size_t i; + + int selected_version; + int key_exchange_group; + + // record_version + tls_record_set_protocol(conn->record, TLS_protocol_tls1); + + // re-generate client_random + if (rand_bytes(conn->client_random, 32) != 1) { + error_print(); + return -1; + } + + // key_share,这里必须提供服务器的哪个版本 + int curve_oid = tls_named_curve_oid(conn->key_exchange_group); + if (x509_key_generate(&conn->ecdh_keys[i], + OID_ec_public_key, &curve_oid, sizeof(curve_oid)) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_internal_error); + return -1; + } + + // extensions + if (tls13_client_supported_versions_ext_to_bytes(&selected_version, 1, &p, &extslen) != 1 + || tls_supported_groups_ext_to_bytes(&conn->key_exchange_group, 1, &p, &extslen) != 1 + || tls13_key_share_client_hello_ext_to_bytes(&conn->ecdh_key, 1, &p, &extslen) != 1 + || tls_signature_algorithms_ext_to_bytes( + conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt, &p, &extslen) != 1) { + error_print(); + return -1; + } + if (tls_record_set_handshake_client_hello(conn->record, &conn->recordlen, + TLS_protocol_tls12, conn->client_random, + session_id, conn->session_id_len, + conn->ctx->cipher_suites, conn->ctx->cipher_suites_cnt, + exts, extslen) != 1) { + error_print(); + return -1; + } + + tls_trace("send ClientHello again\n"); + + tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); + } + + if (conn->client_certificate_verify) { + sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); + } + + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + + tls_clean_record(conn); + return 1; + +} + +int tls13_recv_client_hello_again(TLS_CONNECT *conn) +{ + int ret; + uint8_t *record = conn->record; + size_t recordlen; + + int client_verify = 0; + + int protocol; + + // client_hello + int legacy_version; + const uint8_t *random; + const uint8_t *legacy_session_id; + size_t legacy_session_id_len; + const uint8_t *cipher_suites; + size_t cipher_suites_len; + const uint8_t *legacy_comp_methods; + size_t legacy_comp_methods_len; + const uint8_t *exts; + size_t extslen; + + // extensions + const uint8_t *supported_versions = NULL; + size_t supported_versions_len; + const uint8_t *supported_groups = NULL; + size_t supported_groups_len; + const uint8_t *key_share = NULL; + size_t key_share_len; + const uint8_t *signature_algorithms = NULL; + size_t signature_algorithms_len; + + // parameters + int common_versions[3]; + size_t common_versions_cnt; + int selected_version; + int common_groups[2]; + size_t common_groups_cnt; + int key_share_group; + const uint8_t *key_exchange; + size_t key_exchange_len; + + + tls_trace("recv ClientHello again\n"); + + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { + error_print(); + } + return ret; + } + tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); + + + if (tls_record_protocol(record) != TLS_protocol_tls1) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + return -1; + } + if ((ret = tls_record_get_handshake_client_hello(conn->record, + &legacy_version, &random, + &legacy_session_id, &legacy_session_id_len, + &cipher_suites, &cipher_suites_len, + &exts, &extslen)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + + // legacy_version + if (legacy_version != TLS_protocol_tls12) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + return -1; + } + + // random + memcpy(conn->client_random, random, 32); + // 可能要判断和上一次的是否一样 + + // legacy_session_id + if (legacy_session_id_len) { + // tls13 server ignore legacy_session_id + warning_print(); + } + + // cipher_suites 这里可能要判断和上次协商的是否一致 + if ((ret = tls_cipher_suites_select(cipher_suites, cipher_suites_len, + conn->cipher_suites, conn->cipher_suites_cnt, + &conn->cipher_suite)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + return -1; + } + tls13_cipher_suite_get(conn->cipher_suite, &conn->cipher, &conn->digest); + + + while (extslen) { + int ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &exts, &extslen) != 1) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } + if (!ext_datalen) { + // following extensions should not be empty + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } + + switch (ext_type) { + case TLS_extension_supported_versions: + if (supported_versions) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + supported_versions = ext_data; + supported_versions_len = ext_datalen; + break; + + case TLS_extension_supported_groups: + if (supported_groups_len >= 0) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + supported_groups = ext_data; + supported_groups_len = ext_datalen; + break; + + case TLS_extension_key_share: + if (key_share_len >= 0) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + key_share = ext_data; + key_share_len = ext_datalen; + break; + + case TLS_extension_signature_algorithms: + if (signature_algorithms_len >= 0) { + error_print(); + tls_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + signature_algorithms = ext_data; + signature_algorithms_len = ext_datalen; + break; + + default: + warning_print(); + } + } + + // supported_versions + if (supported_versions_len < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_missing_extension); + return -1; + } + if ((ret = tls13_process_client_supported_versions( + supported_versions, supported_versions_len, // client_versions + conn->ctx->supported_versions, conn->ctx->supported_versions_cnt, // server versions + common_versions, &common_versions_cnt, + sizeof(common_versions)/sizeof(common_versions[0]))) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } + if (common_versions_cnt == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + return -1; + } + if (common_versions[0] != TLS_protocol_tls13) { + error_print(); + tls_send_alert(conn, TLS_alert_protocol_version); + return -1; + } + + // supported_groups + if (supported_groups_len < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_missing_extension); + return -1; + } + // 查找有没有服务器支持的group + if ((ret = tls_process_supported_groups(supported_groups, supported_groups_len, + conn->ctx->supported_groups, conn->ctx->supported_groups_cnt, + common_groups, &common_groups_cnt, + sizeof(common_groups)/sizeof(common_groups[0]))) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + return -1; + } + + // key_share + if (key_share_len < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_missing_extension); + return -1; + } + if ((ret = tls13_process_key_share_client_hello(key_share, key_share_len, + common_groups, common_groups_cnt, + &key_share_group, &key_exchange, &key_exchange_len)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + return -1; + } + if (key_exchange_len != 65) { + error_print(); + return -1; + } + conn->key_exchange_group = key_share_group; + memcpy(conn->peer_ecdh_point, key_exchange, key_exchange_len); + //conn->peer_ecdh_point = key_exchange_len; + + // signature_algorithms + if (signature_algorithms_len < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_missing_extension); + return -1; + } + + int selected_sig_alg; + size_t common_sig_algs_cnt; + if ((ret = tls_process_signature_algorithms( + signature_algorithms, signature_algorithms_len, + conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt, + &selected_sig_alg, &common_sig_algs_cnt, 1)) < 0) { + error_print(); + tls_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls_send_alert(conn, TLS_alert_handshake_failure); + return -1; + } + //conn->sig_alg = selected_sig_alg; + + // cipher_suite, key_share_group, sig_alg compatible + + switch (conn->cipher_suite) { + case TLS_cipher_sm4_gcm_sm3: + if (key_share_group != TLS_curve_sm2p256v1 + || selected_sig_alg != TLS_sig_sm2sig_sm3) { + error_print(); + tls_send_alert(conn, TLS_alert_insufficient_security); + return -1; + } + break; + case TLS_cipher_aes_128_gcm_sha256: + if (key_share_group != TLS_curve_secp256r1 + || selected_sig_alg != TLS_sig_ecdsa_secp256r1_sha256) { + error_print(); + tls_send_alert(conn, TLS_alert_insufficient_security); + return -1; + } + break; + default: + error_print(); + return -1; + } + + digest_init(&conn->dgst_ctx, conn->digest); + digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5); + + if (client_verify) + tls_client_verify_update(&conn->client_verify_ctx, conn->record + 5, conn->recordlen - 5); + + tls_clean_record(conn); + + return 1; +} + + + +/* + send_client_hello + recv_server_hello + recv_encrypted_exts + recv_certificate_request + recv_certificate + recv_certificate_verify + recv_server_finished + send_certificate + send_certificate_verify + send_client_finished + +*/ + + + +int tls13_do_client_handshake(TLS_CONNECT *conn) +{ + int ret; + int next_state; + + switch (conn->state) { + case TLS_state_client_hello: + ret = tls13_send_client_hello(conn); + next_state = TLS_state_server_hello; + break; + + case TLS_state_server_hello: + ret = tls13_recv_server_hello(conn); + if (conn->hello_retry_request) + next_state = TLS_state_hello_retry_request; + else next_state = TLS_state_generate_keys; + break; + + case TLS_state_hello_retry_request: + ret = tls13_recv_hello_retry_request(conn); + next_state = TLS_state_client_hello_again; + break; + + case TLS_state_client_hello_again: + ret = tls13_send_client_hello_again(conn); + next_state = TLS_state_server_hello; + break; + + case TLS_state_generate_keys: + ret = tls13_generate_keys(conn); + next_state = TLS_state_encrypted_extensions; + break; + + case TLS_state_encrypted_extensions: + ret = tls13_recv_encrypted_extensions(conn); + next_state = TLS_state_certificate_request; + break; + + case TLS_state_certificate_request: + ret = tls13_recv_certificate_request(conn); + if (ret == 1) conn->client_certificate_verify = 1; + next_state = TLS_state_server_certificate; + break; + + case TLS_state_server_certificate: + ret = tls13_recv_server_certificate(conn); + next_state = TLS_state_certificate_verify; + break; + + case TLS_state_certificate_verify: + ret = tls13_recv_certificate_verify(conn); + next_state = TLS_state_server_finished; + break; + + case TLS_state_server_finished: + ret = tls13_recv_server_finished(conn); + if (conn->client_certificate_verify) + next_state = TLS_state_client_certificate; + else next_state = TLS_state_client_finished; + break; + + case TLS_state_client_certificate: + ret = tls13_send_client_certificate(conn); + next_state = TLS_state_client_certificate_verify; + break; + + case TLS_state_client_certificate_verify: + ret = tls13_send_certificate_verify(conn); + next_state = TLS_state_client_finished; + break; + + case TLS_state_client_finished: + ret = tls13_send_client_finished(conn); + next_state = TLS_state_handshake_over; + break; + + default: + error_print(); + return -1; + } + + if (ret < 0) { + if (ret == TLS_ERROR_RECV_AGAIN || ret == TLS_ERROR_SEND_AGAIN) { + return ret; + } else { + error_print(); + return ret; + } + } + + conn->state = next_state; + + // ret == 0 means this step is bypassed + if (ret == 1) { + tls_clean_record(conn); + } + + return 1; +} + +int tls13_do_server_handshake(TLS_CONNECT *conn) +{ + int ret; + int next_state; + + switch (conn->state) { + case TLS_state_client_hello: + ret = tls13_recv_client_hello(conn); + if (conn->hello_retry_request) + next_state = TLS_state_hello_retry_request; + else next_state = TLS_state_server_hello; + break; + + case TLS_state_hello_retry_request: + ret = tls13_send_hello_retry_request(conn); + next_state = TLS_state_client_hello_again; + break; + + case TLS_state_client_hello_again: + ret = tls13_recv_client_hello_again(conn); + next_state = TLS_state_server_hello; + break; + + case TLS_state_server_hello: + ret = tls13_send_server_hello(conn); + next_state = TLS_state_generate_keys; + break; + + case TLS_state_generate_keys: + ret = tls13_generate_keys(conn); + next_state = TLS_state_encrypted_extensions; + + case TLS_state_encrypted_extensions: + ret = tls13_send_encrypted_extensions(conn); + if (conn->client_certificate_verify) + next_state = TLS_state_certificate_request; + else next_state = TLS_state_server_certificate; + break; + + case TLS_state_certificate_request: + ret = tls13_send_certificate_request(conn); + next_state = TLS_state_server_certificate; + break; + + case TLS_state_server_certificate: + ret = tls13_send_server_certificate(conn); + next_state = TLS_state_certificate_verify; + break; + + case TLS_state_certificate_verify: + ret = tls13_send_server_certificate_verify(conn); + next_state = TLS_state_server_finished; + break; + + case TLS_state_server_finished: + ret = tls13_send_server_finished(conn); + if (conn->client_certificate_verify) + next_state = TLS_state_client_certificate; + else next_state = TLS_state_client_finished; + break; + + case TLS_state_client_certificate: + ret = tls13_recv_client_certificate(conn); + next_state = TLS_state_client_certificate_verify; + break; + + case TLS_state_client_certificate_verify: + ret = tls13_recv_certificate_verify(conn); + next_state = TLS_state_client_finished; + break; + + case TLS_state_client_finished: + ret = tls13_recv_client_finished(conn); + next_state = TLS_state_handshake_over; + break; + + default: + error_print(); + return -1; + } + + if (ret != 1) { + if (ret == TLS_ERROR_RECV_AGAIN || ret == TLS_ERROR_SEND_AGAIN) { + return ret; + } else { + error_print(); + return ret; + } + + } + + conn->state = next_state; + + tls_clean_record(conn); + + return 1; +} + +int tls13_client_handshake(TLS_CONNECT *conn) +{ + int ret; + + while (conn->state != TLS_state_handshake_over) { + + ret = tls13_do_client_handshake(conn); + + if (ret != 1) { + if (ret != TLS_ERROR_RECV_AGAIN && ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + } + + // TODO: cleanup conn? + + return 1; +} + +int tls13_server_handshake(TLS_CONNECT *conn) +{ + int ret; + + while (conn->state != TLS_state_handshake_over) { + + ret = tls13_do_server_handshake(conn); + + if (ret != 1) { + if (ret != TLS_ERROR_RECV_AGAIN && ret != TLS_ERROR_SEND_AGAIN) { + error_print(); + } + return ret; + } + } + + // TODO: cleanup conn? + + return 1; +} + +int tls13_do_connect(TLS_CONNECT *conn) +{ + int ret; + fd_set rfds; + fd_set wfds; + + // 应该把protocol_version的初始化放在这里 + + conn->state = TLS_state_client_hello; + sm3_init(&conn->sm3_ctx); + + while (1) { + + ret = tls13_client_handshake(conn); + if (ret == 1) { + break; + + } else if (ret == TLS_ERROR_SEND_AGAIN) { + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_SET(conn->sock, &rfds); + select(conn->sock + 1, &rfds, &wfds, NULL, NULL); + + } else if (ret == TLS_ERROR_RECV_AGAIN) { + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_SET(conn->sock, &wfds); + select(conn->sock + 1, &rfds, &wfds, NULL, NULL); + + } else { + error_print(); + return -1; + } + } + + fprintf(stderr, "tls13_do_connect: connected\n"); + + return 1; +} + +int tls13_do_accept(TLS_CONNECT *conn) +{ + int ret; + fd_set rfds; + fd_set wfds; + + conn->state = TLS_state_client_hello; + + sm3_init(&conn->sm3_ctx); + + fprintf(stderr, "tls13_do_accept\n"); + + while (1) { + + ret = tls13_server_handshake(conn); + + if (ret == 1) { + break; + + } else if (ret == TLS_ERROR_SEND_AGAIN) { + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_SET(conn->sock, &rfds); + select(conn->sock + 1, &rfds, &wfds, NULL, NULL); + + } else if (ret == TLS_ERROR_RECV_AGAIN) { + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_SET(conn->sock, &wfds); + select(conn->sock + 1, &rfds, &wfds, NULL, NULL); + + } else { + error_print(); + return -1; + } + } + + fprintf(stderr, "tls13_do_accept: connected\n"); + + return 1; +} + diff --git a/src/tls_ext.c b/src/tls_ext.c index be744515..8157cf86 100644 --- a/src/tls_ext.c +++ b/src/tls_ext.c @@ -1,4 +1,4 @@ -/* +/* * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may @@ -38,6 +38,7 @@ Example: ec_point_format_list: 0x00 (uncompressed) */ + int tls_ec_point_formats_ext_to_bytes(const int *formats, size_t formats_cnt, uint8_t **out, size_t *outlen) { @@ -70,6 +71,7 @@ int tls_ec_point_formats_ext_to_bytes(const int *formats, size_t formats_cnt, return 1; } +// 似乎不应该保留process函数 int tls_process_client_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen, uint8_t **out, size_t *outlen) { @@ -185,22 +187,61 @@ int tls_supported_groups_ext_to_bytes(const int *groups, size_t groups_cnt, return 1; } -int tls_process_client_supported_groups(const uint8_t *ext_data, size_t ext_datalen, - uint8_t **out, size_t *outlen) +int tls_supported_groups_from_bytes(int *groups, size_t *groups_cnt, size_t max_cnt, + const uint8_t *ext_data, size_t ext_datalen) { - int shared_groups[] = { TLS_curve_sm2p256v1 }; - size_t shared_groups_cnt = 0; - const uint8_t *p; - size_t len; + const uint8_t *named_group_list; + size_t named_group_list_len; + size_t i = 0; - if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 + if (tls_uint16array_from_bytes(&named_group_list, &named_group_list_len, &ext_data, &ext_datalen) != 1 || tls_length_is_zero(ext_datalen) != 1) { error_print(); return -1; } - while (len) { + if (named_group_list_len < 2) { + error_print(); + return -1; + } + while (named_group_list_len) { uint16_t group; - if (tls_uint16_from_bytes(&group, &p, &len) != 1) { + if (tls_uint16_from_bytes(&group, &named_group_list, &named_group_list_len) != 1) { + error_print(); + return -1; + } + if (!tls_named_curve_name(group)) { + warning_print(); + } + if (i < max_cnt) { + groups[i] = group; + i++; + } + } + *groups_cnt = i; + return 1; +} + +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) +{ + const uint8_t *named_group_list; + size_t named_group_list_len; + const uint8_t *cp; + size_t len; + uint16_t group; + size_t i, j = 0; + + if (tls_uint16array_from_bytes(&named_group_list, &named_group_list_len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + + cp = named_group_list; + len = named_group_list_len; + while (len) { + if (tls_uint16_from_bytes(&group, &cp, &len) != 1) { error_print(); return -1; } @@ -208,38 +249,51 @@ int tls_process_client_supported_groups(const uint8_t *ext_data, size_t ext_data error_print(); return -1; } - if (group == shared_groups[0]) { - shared_groups_cnt = 1; + if (group == local_groups[0] && j < max_cnt) { + common_groups[j++] = group; } } - if (!shared_groups_cnt) { - error_print(); - return -1; + + for (i = 1; i < local_groups_cnt && j < max_cnt; i++) { + cp = named_group_list; + len = named_group_list_len; + while (len) { + tls_uint16_from_bytes(&group, &cp, &len); + if (group == local_groups[i]) { + common_groups[j++] = group; + break; + } + } } - if (tls_supported_groups_ext_to_bytes(shared_groups, shared_groups_cnt, out, outlen) != 1) { - error_print(); - return -1; + *common_groups_cnt = j; + + if (*common_groups_cnt == 0) { + return 0; } return 1; } -int tls_process_server_supported_groups(const uint8_t *ext_data, size_t ext_datalen) +int tls_supported_groups_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen) { - const uint8_t *p; - size_t len; - uint16_t group; + const uint8_t *groups; + size_t groups_len; - if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 - || tls_length_is_zero(ext_datalen) != 1) { + format_print(fp, fmt, ind, "named_group_list\n"); + ind += 4; + + if (tls_uint16array_from_bytes(&groups, &groups_len, &d, &dlen) != 1) { error_print(); return -1; } - if (tls_uint16_from_bytes(&group, &p, &len) != 1 - || tls_length_is_zero(len) != 1) { - error_print(); - return -1; + while (groups_len) { + uint16_t group; + if (tls_uint16_from_bytes(&group, &groups, &groups_len) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "%s (%04x)\n", tls_named_curve_name(group), group); } - if (group != TLS_curve_sm2p256v1) { + if (dlen) { error_print(); return -1; } @@ -248,6 +302,7 @@ int tls_process_server_supported_groups(const uint8_t *ext_data, size_t ext_data + #define TLS_MAX_SIGNATURE_ALGORS_COUNT 64 /* @@ -264,7 +319,67 @@ Example: 0x00,0x02, // supported_signature_algorithms_length 0x07,0x07, // supported_signature_algorithms = [ sm2sig_sm3 ] + +在tls12中,只有ClientHello可以包含这个扩展,ServerHello不允许包含这个扩展 +服务器在接收到这个扩展之后,如果 +在 TLS 1.2 中,如果服务器收到客户端的 signature_algorithms 扩展,但发现其中没有自己支持的算法 +服务器必须中止握手,并返回一个致命的 handshake_failure 警报 + */ + +int tls_signature_algorithms_print_ex(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +{ + const uint8_t *sig_algs; + size_t sig_algs_len; + + if (tls_uint16array_from_bytes(&sig_algs, &sig_algs_len, &d, &dlen) != 1) { + error_print(); + return -1; + } + + format_print(fp, fmt, ind, "supported_signature_algorithms\n"); + ind += 4; + while (sig_algs_len) { + uint16_t sig_alg; + if (tls_uint16_from_bytes(&sig_alg, &sig_algs, &sig_algs_len) != 1) { + error_print(); + return -1; + } + format_print(fp, fmt, ind, "%s (%04x)\n", tls_signature_scheme_name(sig_alg), sig_alg); + } + + if (dlen) { + error_print(); + return -1; + } + return 1; +} + +int tls_signature_algorithms_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen) +{ + if (tls_signature_algorithms_print_ex(fp, fmt, ind, "signature_algorithms", d, dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls13_signature_algorithms_cert_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen) +{ + if (tls_signature_algorithms_print_ex(fp, fmt, ind, "signature_algorithms_cert", d, dlen) != 1) { + error_print(); + return -1; + } + return 1; +} + + + + + + + + int tls_signature_algorithms_ext_to_bytes_ex(int ext_type, const int *algs, size_t algs_cnt, uint8_t **out, size_t *outlen) { @@ -318,342 +433,120 @@ int tls13_signature_algorithms_cert_ext_to_bytes(const int *algs, size_t algs_cn return 1; } -int tls_process_client_signature_algorithms(const uint8_t *ext_data, size_t ext_datalen, - uint8_t **out, size_t *outlen) +int tls_process_signature_algorithms(const uint8_t *ext_data, size_t ext_datalen, + const int *local_sig_algs, size_t local_sig_algs_cnt, + int *common_sig_algs, size_t *common_sig_algs_cnt, size_t max_cnt) { - int shared_algs[1] = { TLS_sig_sm2sig_sm3 }; - size_t shared_algs_cnt = 0; - const uint8_t *p; + const uint8_t *supported_sig_algs; + size_t supported_sig_algs_len; + const uint8_t *cp; size_t len; + uint16_t sig_alg; + size_t i, j = 0; - if (!ext_data || !ext_datalen || !outlen) { + if (!common_sig_algs || !common_sig_algs_cnt || !max_cnt) { error_print(); return -1; } - if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 + if (tls_uint16array_from_bytes(&supported_sig_algs, &supported_sig_algs_len, &ext_data, &ext_datalen) != 1 || tls_length_is_zero(ext_datalen) != 1) { error_print(); return -1; } + if (supported_sig_algs_len < 2) { + error_print(); + return -1; + } + + cp = supported_sig_algs; + len = supported_sig_algs_len; while (len) { + if (tls_uint16_from_bytes(&sig_alg, &cp, &len) != 1) { + error_print(); + return -1; + } + if (!tls_signature_scheme_name(sig_alg)) { + error_print(); + return -1; + } + if (sig_alg == local_sig_algs[0] && j < max_cnt) { + common_sig_algs[j++] = sig_alg; + } + } + + for (i = 1; i < local_sig_algs_cnt && j < max_cnt; i++) { + cp = supported_sig_algs; + len = supported_sig_algs_len; + while (len) { + tls_uint16_from_bytes(&sig_alg, &cp, &len); + if (sig_alg == local_sig_algs[i]) { + common_sig_algs[j++] = sig_alg; + break; + } + } + } + *common_sig_algs_cnt = j; + + if (!(*common_sig_algs_cnt)) { + warning_print(); + return 0; + } + return 1; +} + +int tls_signature_algorithms_ext_from_bytes(int *algs, size_t *algs_cnt, size_t max_cnt, + const uint8_t *ext_data, size_t ext_datalen) +{ + const uint8_t *cp; + size_t len; + size_t i; + + if (tls_uint16array_from_bytes(&cp, &len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + for (i = 0; i < max_cnt && len; i++) { uint16_t alg; - if (tls_uint16_from_bytes(&alg, &p, &len) != 1) { + if (tls_uint16_from_bytes(&alg, &cp, &len) != 1) { error_print(); return -1; } if (!tls_signature_scheme_name(alg)) { - error_print_msg("unknown TLS signature scheme %04x\n", alg); - continue; - } - if (alg == shared_algs[0]) { - shared_algs_cnt = 1; - break; - } - } - if (!shared_algs_cnt) { - error_print(); - return -1; - } - if (tls_signature_algorithms_ext_to_bytes(shared_algs, shared_algs_cnt, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int tls_process_server_signature_algors(const uint8_t *ext_data, size_t ext_datalen) -{ - const uint8_t *p; - size_t len; - uint16_t alg; - - if (tls_uint16array_from_bytes(&p, &len, &ext_data, &ext_datalen) != 1 - || tls_length_is_zero(ext_datalen) != 1) { - error_print(); - return -1; - } - if (tls_uint16_from_bytes(&alg, &p, &len) != 1 - || tls_length_is_zero(len) != 1) { - error_print(); - return -1; - } - if (alg != TLS_sig_sm2sig_sm3) { - error_print(); - return -1; - } - return 1; -} - -/* -supported_versions - - struct { - select (Handshake.msg_type) { - case client_hello: - ProtocolVersion versions<2..254>; - case server_hello: -- and HelloRetryRequest - ProtocolVersion selected_version; - }; - } SupportedVersions; -*/ - -int tls13_supported_versions_ext_print(FILE *fp, int fmt, int ind, - int handshake_type, const uint8_t *data, size_t datalen) -{ - const uint8_t *versions; - size_t versions_len; - uint16_t version; - - switch (handshake_type) { - case TLS_handshake_client_hello: - format_print(fp, fmt, ind, "versions\n"); - ind += 4; - - if (tls_uint8array_from_bytes(&versions, &versions_len, &data, &datalen) != 1) { error_print(); return -1; } - if (versions_len < 2 || versions_len > 254) { - error_print(); - return -1; - } - while (versions_len) { - if (tls_uint16_from_bytes(&version, &versions, &versions_len) != 1) { - error_print(); - return -1; + algs[i] = alg; + } + *algs_cnt = i; + return 1; +} + + +static int tls_server_parameter_select(const int *server_params, size_t server_params_cnt, + const int *client_params, size_t client_params_cnt, + int *selected) +{ + size_t i, j; + + for (i = 0; i < server_params_cnt; i++) { + *selected = server_params[i]; + for (j = 0; j < client_params_cnt; j++) { + if (client_params[j] == *selected) { + return 1; } - format_print(fp, fmt, ind, "%s (0x%04x)\n", tls_protocol_name(version), version); - } - break; - - case TLS_handshake_server_hello: - case TLS_handshake_hello_retry_request: - if (tls_uint16_from_bytes(&version, &data, &datalen) != 1) { - error_print(); - return -1; - } - format_print(fp, fmt, ind, "selected_version: %s (0x%04x)\n", tls_protocol_name(version), version); - break; - - default: - error_print(); - return -1; - } - - if (datalen) { - error_print(); - return -1; - } - return 1; -} - -int tls13_supported_versions_ext_to_bytes(int handshake_type, const int *protos, size_t protos_cnt, - uint8_t **out, size_t *outlen) -{ - uint16_t ext_type = TLS_extension_supported_versions; - size_t ext_datalen; - size_t i; - - if (!protos || !protos_cnt || !outlen) { - error_print(); - return -1; - } - switch (handshake_type) { - case TLS_handshake_client_hello: - { - size_t versions_len; - if (protos_cnt > 254/2) { - error_print(); - return -1; - } - versions_len = tls_uint16_size() * protos_cnt; - ext_datalen = tls_uint8_size() + versions_len; - tls_uint16_to_bytes(ext_type, out, outlen); - tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); - tls_uint8_to_bytes((uint8_t)versions_len, out, outlen); - for (i = 0; i < protos_cnt; i++) { - if (!tls_protocol_name(protos[i])) { - error_print(); - return -1; - } - tls_uint16_to_bytes((uint16_t)protos[i], out, outlen); - } - break; - } - case TLS_handshake_server_hello: - case TLS_handshake_hello_retry_request: - { - uint16_t selected_version; - if (protos_cnt > 1) { - error_print(); - return -1; - } - selected_version = protos[0]; - ext_datalen = tls_uint16_size(); - tls_uint16_to_bytes(ext_type, out, outlen); - tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); - tls_uint16_to_bytes(selected_version, out, outlen); - break; - } - default: - error_print(); - return -1; - } - return 1; -} - -int tls13_process_client_supported_versions(const uint8_t *ext_data, size_t ext_datalen, - uint8_t **out, size_t *outlen) -{ - const uint8_t *versions; - size_t versions_len; - int selected_version = -1; - - if (tls_uint8array_from_bytes(&versions, &versions_len, &ext_data, &ext_datalen) != 1 - || tls_length_is_zero(ext_datalen) != 1) { - error_print(); - return -1; - } - if (versions_len < 2 || versions_len > 254) { - error_print(); - return -1; - } - while (versions_len) { - uint16_t proto; - if (tls_uint16_from_bytes(&proto, &versions, &versions_len) != 1) { - error_print(); - return -1; - } - if (!tls_protocol_name(proto)) { - error_print(); - return -1; - } - if (proto == TLS_protocol_tls13) { - selected_version = proto; } } - if (selected_version < 0) { - error_print(); - return -1; - } - if (tls13_supported_versions_ext_to_bytes(TLS_handshake_server_hello, &selected_version, 1, out, outlen) != 1) { - error_print(); - return -1; - } - return 1; -} - -int tls13_process_server_supported_versions(const uint8_t *ext_data, size_t ext_datalen) -{ - uint16_t selected_version; - - if (tls_uint16_from_bytes(&selected_version, &ext_data, &ext_datalen) != 1 - || tls_length_is_zero(ext_datalen) != 1) { - error_print(); - return -1; - } - if (selected_version != TLS_protocol_tls13) { - error_print(); - return -1; - } - return 1; -} - -/* -key_share - -实际上这个 key_share 也存在相同的问题 - - - struct { - NamedGroup group; - opaque key_exchange<1..2^16-1>; - } KeyShareEntry; - - struct { - KeyShareEntry client_shares<0..2^16-1>; - } KeyShareClientHello; - - struct { - KeyShareEntry server_share; - } KeyShareServerHello; -*/ - -int tls13_key_share_ext_print(FILE *fp, int fmt, int ind, int handshake_type, const uint8_t *data, size_t datalen) -{ - const uint8_t *client_shares; - size_t client_shares_len; - uint16_t group; - const uint8_t *key_exchange; - size_t key_exchange_len; - - switch (handshake_type) { - case TLS_handshake_client_hello: - format_print(fp, fmt, ind, "client_shares\n"); - ind += 4; - if (tls_uint16array_from_bytes(&client_shares, &client_shares_len, &data, &datalen) != 1) { - error_print(); - return -1; - } - format_print(fp, fmt, ind, "KeyShareEntry\n"); - ind += 4; - while (client_shares_len) { - if (tls_uint16_from_bytes(&group, &client_shares, &client_shares_len) != 1) goto err; - format_print(fp, fmt, ind, "group: %s (0x%04x)\n", tls_named_curve_name(group), group); - if (tls_uint16array_from_bytes(&key_exchange, &key_exchange_len, &client_shares, &client_shares_len) != 1) goto err; - format_bytes(fp, fmt, ind, "key_exchange", key_exchange, key_exchange_len); - } - break; - case TLS_handshake_server_hello: - format_print(fp, fmt, ind, "server_share\n"); - ind += 4; - if (tls_uint16_from_bytes(&group, &data, &datalen) != 1) goto err; - format_print(fp, fmt, ind, "group: %s (0x%04x)\n", tls_named_curve_name(group), group); - if (tls_uint16array_from_bytes(&key_exchange, &key_exchange_len, &data, &datalen) != 1) goto err; - format_bytes(fp, fmt, ind, "key_exchange", key_exchange, key_exchange_len); - break; - default: - error_print(); - return -1; - } - if (tls_length_is_zero(datalen) != 1) goto err; - return 1; -err: error_print(); - return -1; + return 0; } -int tls13_key_share_entry_to_bytes(const SM2_Z256_POINT *point, uint8_t **out, size_t *outlen) -{ - uint16_t group = TLS_curve_sm2p256v1; - uint8_t key_exchange[65]; - if (!point || !outlen) { - error_print(); - return -1; - } - sm2_z256_point_to_uncompressed_octets(point, key_exchange); - tls_uint16_to_bytes(group, out, outlen); - tls_uint16array_to_bytes(key_exchange, 65, out, outlen); - return 1; -} -int tls13_server_key_share_ext_to_bytes(const SM2_Z256_POINT *point, uint8_t **out, size_t *outlen) -{ - uint16_t ext_type = TLS_extension_key_share; - size_t ext_datalen = 0; - if (!point || !outlen) { - error_print(); - return -1; - } - tls13_key_share_entry_to_bytes(point, NULL, &ext_datalen); - tls_uint16_to_bytes(ext_type, out, outlen); - tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); - tls13_key_share_entry_to_bytes(point, out, outlen); - return 1; -} + +/* int tls13_process_server_key_share(const uint8_t *ext_data, size_t ext_datalen, SM2_Z256_POINT *point) { uint16_t group; @@ -685,29 +578,16 @@ int tls13_process_server_key_share(const uint8_t *ext_data, size_t ext_datalen, return 1; } -int tls13_client_key_share_ext_to_bytes(const SM2_Z256_POINT *point, uint8_t **out, size_t *outlen) -{ - uint16_t ext_type = TLS_extension_key_share; - size_t ext_datalen; - size_t client_shares_len = 0; +*/ - if (!point || !outlen) { - error_print(); - return -1; - } - tls13_key_share_entry_to_bytes(point, NULL, &client_shares_len); - ext_datalen = tls_uint16_size() + client_shares_len; - - tls_uint16_to_bytes(ext_type, out, outlen); - tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); // FIXME: do we need to check length < UINT16_MAX? - tls_uint16_to_bytes((uint16_t)client_shares_len, out, outlen); - tls13_key_share_entry_to_bytes(point, out, outlen); - return 1; -} - -int tls13_process_client_key_share(const uint8_t *ext_data, size_t ext_datalen, - const SM2_KEY *server_ecdhe_key, SM2_KEY *client_ecdhe_public, - uint8_t **out, size_t *outlen) +/* +如果客户端提供的key_share满足服务器支持的group,那么就缓存这个key_share,任务完成 +否则,如果客户端的groups和服务器的groups找到了共同的group,那么服务器可以发送HelloRetryRequest +*/ +/* +int tls13_process_client_key_share(const int *server_groups, size_t server_groups_cnt, + const uint8_t *client_ext_data, size_t client_ext_datalen, + int *client_group, uint8_t *client_key_exchange, size_t client_key_exchange_len) { const uint8_t *client_shares; size_t client_shares_len; @@ -758,54 +638,8 @@ int tls13_process_client_key_share(const uint8_t *ext_data, size_t ext_datalen, error_print(); return -1; } - -/* -certificate_authorities - - opaque DistinguishedName<1..2^16-1>; - - struct { - DistinguishedName authorities<3..2^16-1>; - } CertificateAuthoritiesExtension; */ -int tls13_certificate_authorities_ext_to_bytes(const uint8_t *ca_names, size_t ca_names_len, - uint8_t **out, size_t *outlen) -{ - int ext_type = TLS_extension_certificate_authorities; - size_t ext_datalen; - size_t authorities_len; - const uint8_t *name; - size_t namelen; - const uint8_t *p; - size_t len; - - p = ca_names; - len = ca_names_len; - authorities_len = 0; - while (len) { - if (x509_name_from_der(&name, &namelen, &p, &len) != 1) { - error_print(); - return -1; - } - tls_uint16array_to_bytes(name, namelen, NULL, &authorities_len); - } - if (authorities_len < 3 || authorities_len > (1 << 16) - 1) { - error_print(); - return -1; - } - ext_datalen = tls_uint16_size() + authorities_len; - - tls_uint16_to_bytes(ext_type, out, outlen); - tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen); - tls_uint16_to_bytes((uint16_t)authorities_len, out, outlen); - while (ca_names_len) { - x509_name_from_der(&name, &namelen, &ca_names, &ca_names_len); - tls_uint16array_to_bytes(name, namelen, out, outlen); - } - return 1; -} - int tls_ext_from_bytes(int *type, const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen) { @@ -843,6 +677,7 @@ int tls_process_client_hello_exts(const uint8_t *exts, size_t extslen, uint8_t * } break; case TLS_extension_signature_algorithms: + /* if (tls_process_client_signature_algorithms(data, datalen, &out, outlen) != 1) { error_print(); return -1; @@ -853,6 +688,7 @@ int tls_process_client_hello_exts(const uint8_t *exts, size_t extslen, uint8_t * error_print(); return -1; } + */ break; default: error_print(); @@ -888,6 +724,8 @@ int tls_process_server_hello_exts(const uint8_t *exts, size_t extslen, *ec_point_format = TLS_point_uncompressed; break; case TLS_extension_signature_algorithms: + + /* if (tls_process_server_signature_algors(data, datalen) != 1) { error_print(); return -1; @@ -899,6 +737,7 @@ int tls_process_server_hello_exts(const uint8_t *exts, size_t extslen, error_print(); return -1; } + */ *signature_algor = TLS_sig_sm2sig_sm3; break; default: @@ -955,31 +794,3 @@ static int tls13_hello_retry_request_exts[] = { }; - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/tls_trace.c b/src/tls_trace.c index 6e06fa38..27093ab1 100644 --- a/src/tls_trace.c +++ b/src/tls_trace.c @@ -1,4 +1,4 @@ -/* +/* * Copyright 2014-2026 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may @@ -454,61 +454,6 @@ int tls_extension_print(FILE *fp, int type, const uint8_t *data, size_t datalen, return 1; } -int tls13_extension_print(FILE *fp, int fmt, int ind, - int handshake_type, int ext_type, const uint8_t *ext_data, size_t ext_datalen) -{ - switch (ext_type) { - case TLS_extension_supported_groups: - case TLS_extension_ec_point_formats: - case TLS_extension_signature_algorithms: - return tls_extension_print(fp, ext_type, ext_data, ext_datalen, fmt, ind); - } - - format_print(fp, fmt, ind, "%s (%d)\n", tls_extension_name(ext_type), ext_type); - ind += 4; - - switch (ext_type) { - case TLS_extension_supported_versions: - tls13_supported_versions_ext_print(fp, fmt, ind, handshake_type, ext_data, ext_datalen); - break; - case TLS_extension_key_share: - tls13_key_share_ext_print(fp, fmt, ind, handshake_type, ext_data, ext_datalen); - break; - default: - format_bytes(fp, fmt, ind, "raw_data", ext_data, ext_datalen); - } - return 1; -} - -int tls13_extensions_print(FILE *fp, int fmt, int ind, - int handshake_type, const uint8_t *exts, size_t extslen) -{ - uint16_t ext_type; - const uint8_t *ext_data; - size_t ext_datalen; - - if (!exts) { - format_print(fp, fmt, ind, "Extensions: (null)\n"); - return 1; - } - - format_print(fp, fmt, ind, "Extensions\n"); - ind += 4; - - while (extslen > 0) { - if (tls_uint16_from_bytes(&ext_type, &exts, &extslen) != 1 - || tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &extslen) != 1) { - error_print(); - return -1; - } - if (tls13_extension_print(fp, fmt, ind, handshake_type, ext_type, ext_data, ext_datalen) != 1) { - error_print(); - return -1; - } - } - return 1; -} - int tls_extensions_print(FILE *fp, const uint8_t *exts, size_t extslen, int format, int indent) { uint16_t ext_type; @@ -581,9 +526,27 @@ int tls_client_hello_print(FILE *fp, const uint8_t *data, size_t datalen, int fo } if (datalen > 0) { if (tls_uint16array_from_bytes(&exts, &exts_len, &data, &datalen) != 1) goto end; - //tls_extensions_print(fp, exts, exts_len, format, indent); - tls13_extensions_print(fp, format, indent, TLS_handshake_client_hello, exts, exts_len); + format_print(fp, format, indent, "Extensions\n"); + indent += 4; } + // 打印扩展 + while (exts_len > 0) { + uint16_t ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + if (tls_uint16_from_bytes(&ext_type, &exts, &exts_len) != 1 + || tls_uint16array_from_bytes(&ext_data, &ext_datalen, &exts, &exts_len) != 1) { + error_print(); + return -1; + } + + format_print(fp, format, indent, "%s (%d)\n", tls_extension_name(ext_type), ext_type); + indent += 4; + + tls_extensions_print(fp, exts, exts_len, format, indent); + } + if (datalen > 0) { error_print(); return -1; @@ -593,6 +556,23 @@ end: return ret; } + + + + + + + + + + + + + + + + + int tls_server_hello_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) { int ret = -1; @@ -622,7 +602,7 @@ int tls_server_hello_print(FILE *fp, const uint8_t *data, size_t datalen, int fo if (tls_uint16array_from_bytes(&exts, &exts_len, &data, &datalen) != 1) goto bad; //format_bytes(fp, format, indent, "Extensions : ", exts, exts_len); // FIXME: extensions_print //tls_extensions_print(fp, exts, exts_len, format, indent); - tls13_extensions_print(fp, format, indent, TLS_handshake_server_hello, exts, exts_len); + //tls13_extensions_print(fp, format, indent, TLS_handshake_server_hello, exts, exts_len); } return 1; bad: @@ -854,6 +834,13 @@ int tls_client_key_exchange_print(FILE *fp, const uint8_t *data, size_t datalen, return 1; } +// 这个格式似乎是不对的 +/* +struct { + SignatureAndHashAlgorithm algorithm; + opaque signature<0..2^16-1>; +} DigitallySigned; +*/ int tls_certificate_verify_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent) { format_print(fp, format, indent, "CertificateVerify\n"); @@ -869,43 +856,6 @@ int tls_finished_print(FILE *fp, const uint8_t *data, size_t datalen, int format return 1; } -// FIXME: 应该将这个函数融合到 tls_handshake_print 中 -int tls13_handshake_print(FILE *fp, int fmt, int ind, const uint8_t *handshake, size_t handshake_len) -{ - const uint8_t *p = handshake; - size_t len = handshake_len; - uint8_t type; - const uint8_t *data; - size_t datalen; - - if (tls_uint8_from_bytes(&type, &handshake, &handshake_len) != 1 - || tls_uint24array_from_bytes(&data, &datalen, &handshake, &handshake_len) != 1 - || tls_length_is_zero(handshake_len) != 1) { - error_print(); - return -1; - } - - switch (type) { - case TLS_handshake_certificate: - case TLS_handshake_certificate_request: - case TLS_handshake_certificate_verify: - format_print(fp, fmt, ind, "Handshake\n"); - ind += 4; - format_print(fp, fmt, ind, "Type: %s (%d)\n", tls_handshake_type_name(type), type); - format_print(fp, fmt, ind, "Length: %zu\n", datalen); - break; - } - switch (type) { - case TLS_handshake_certificate: - return tls13_certificate_print(fp, fmt, ind, data, datalen); - case TLS_handshake_certificate_request: - return tls13_certificate_request_print(fp, fmt, ind, data, datalen); - case TLS_handshake_certificate_verify: - return tls13_certificate_verify_print(fp, fmt, ind, data, datalen); - } - - return tls_handshake_print(fp, p, len, fmt, ind); -} // 这个是有问题的,因为TLS 1.3的证书和TLS 1.2是不一样的 int tls_handshake_print(FILE *fp, const uint8_t *handshake, size_t handshakelen, int format, int indent) @@ -1006,75 +956,10 @@ int tls_application_data_print(FILE *fp, const uint8_t *data, size_t datalen, in return 1; } -int tls13_record_print(FILE *fp, int format, int indent, const uint8_t *record, size_t recordlen) -{ - const uint8_t *data; - size_t datalen; - int protocol; - format |= TLS_cipher_sm4_gcm_sm3 << 8; - if (!fp || !record || recordlen < 5) { - error_print(); - return -1; - } - protocol = tls_record_protocol(record); - format_print(fp, format, indent, "Record\n"); indent += 4; - format_print(fp, format, indent, "ContentType: %s (%d)\n", tls_record_type_name(record[0]), record[0]); - format_print(fp, format, indent, "Version: %s (%d.%d)\n", tls_protocol_name(protocol), protocol >> 8, protocol & 0xff); - format_print(fp, format, indent, "Length: %d\n", tls_record_data_length(record)); - data = tls_record_data(record); - datalen = tls_record_data_length(record); - if (recordlen < tls_record_length(record)) { - error_print(); - return -1; - } - - // 最高字节设置后强制打印记录原始数据 - if (format >> 24) { - format_bytes(fp, format, indent, "Data", data, datalen); - fprintf(fp, "\n"); - return 1; - } - - switch (record[0]) { - case TLS_record_handshake: - tls13_handshake_print(fp, format, indent, data, datalen); - break; - case TLS_record_alert: - if (tls_alert_print(fp, data, datalen, format, indent) != 1) { - error_print(); - return -1; - } - break; - case TLS_record_change_cipher_spec: - if (tls_change_cipher_spec_print(fp, data, datalen, format, indent) != 1) { - error_print(); - return -1; - } - break; - case TLS_record_application_data: - if (tls_application_data_print(fp, data, datalen, format, indent) != 1) { - error_print(); - return -1; - } - break; - default: - error_print(); - return -1; - } - - recordlen -= tls_record_length(record); - if (recordlen) { - format_print(fp, 0, 0, "DataLeftInRecord: %zu\n", recordlen); - } - - fprintf(fp, "\n"); - return 1; - -} // FIXME: 根据RFC来考虑这个函数的参数,从底向上逐步修改每个函数的接口参数 diff --git a/tests/tls13test.c b/tests/tls13test.c index 82b4f394..242913e4 100644 --- a/tests/tls13test.c +++ b/tests/tls13test.c @@ -69,10 +69,426 @@ static int test_tls13_gcm(void) printf("%s() ok\n", __FUNCTION__); return 1; } + +static int test_tls13_supported_versions_ext(void) +{ + const int client_versions[] = { TLS_protocol_tls13, TLS_protocol_tls12, TLS_protocol_tlcp }; + const int server_versions[] = { TLS_protocol_tls12, TLS_protocol_tls13, TLS_protocol_tlcp }; + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + + int ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + int common_versions[2]; + size_t common_versions_cnt; + int selected_version; + + // server => client + if (tls13_client_supported_versions_ext_to_bytes(client_versions, + sizeof(client_versions)/sizeof(client_versions[0]), &p, &len) != 1) { + error_print(); + return -1; + } + if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &cp, &len) != 1 + || ext_type != TLS_extension_supported_versions + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "ClientHello.exts.supported_versions\n"); + tls13_client_supported_versions_print(stderr, 0, 8, ext_data, ext_datalen); + + // client process + if (tls13_process_client_supported_versions(ext_data, ext_datalen, + server_versions, sizeof(server_versions)/sizeof(server_versions[0]), + common_versions, &common_versions_cnt, + sizeof(common_versions)/sizeof(common_versions[0])) != 1) { + error_print(); + return -1; + } + if (common_versions[0] != TLS_protocol_tls12 + || common_versions[1] != TLS_protocol_tls13 + || common_versions_cnt != 2) { + error_print(); + return -1; + } + + // client => server + if (tls13_server_supported_versions_ext_to_bytes(common_versions[0], &p, &len) != 1) { + error_print(); + return -1; + } + if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &cp, &len) != 1 + || ext_type != TLS_extension_supported_versions + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "ServerHello.exts.supported_versions\n"); + tls13_server_supported_versions_print(stderr, 0, 8, ext_data, ext_datalen); + + // server process + if (tls13_process_server_supported_versions( + client_versions, sizeof(client_versions)/sizeof(client_versions[0]), + ext_data, ext_datalen, &selected_version) != 1) { + error_print(); + return -1; + } + if (selected_version != TLS_protocol_tls12) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_tls13_key_share_ext(void) +{ + const int curve_oid[] = { + OID_sm2, + OID_secp256r1, + }; + + uint8_t buf[512]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + + + X509_KEY x509_key[2]; + int group; + const uint8_t *key_exchange; + size_t key_exchange_len; + int common_groups[] = { + TLS_curve_secp256r1, + TLS_curve_sm2p256v1, + }; + size_t i; + + for (i = 0; i < sizeof(curve_oid)/sizeof(curve_oid[0]); i++) { + if (x509_key_generate(&x509_key[i], OID_ec_public_key, + &curve_oid[i], sizeof(curve_oid[i])) != 1) { + error_print(); + return -1; + } + } + + // KeyShareEntry + if (tls13_key_share_entry_to_bytes(&x509_key[0], &p, &len) != 1) { + error_print(); + return -1; + } + if (tls13_key_share_entry_from_bytes(&group, &key_exchange, &key_exchange_len, &cp, &len) != 1 + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + if (group != tls_named_curve_from_oid(curve_oid[0]) + || !key_exchange || key_exchange_len != 65) { + error_print(); + return -1; + } + + + + // KeyShareClientHello + if (tls13_key_share_client_hello_ext_to_bytes(x509_key, + sizeof(curve_oid)/sizeof(curve_oid[0]), &p, &len) != 1) { + error_print(); + return -1; + } + if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &cp, &len) != 1 + || tls_length_is_zero(len) != 1) { + error_print(); + return -1; + } + tls13_key_share_client_hello_print(stderr, 0, 4, ext_data, ext_datalen); + if (tls13_process_key_share_client_hello(ext_data, ext_datalen, + common_groups, sizeof(common_groups)/sizeof(common_groups[0]), + &group, &key_exchange, &key_exchange_len) != 1) { + error_print(); + return -1; + } + if (group != common_groups[0]) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "group: %s\n", tls_named_curve_name(group)); + format_bytes(stderr, 0, 4, "key_exchange", key_exchange, key_exchange_len); + + + // KeyShareServerHello + + X509_KEY server_key; + + int server_curve; + + server_curve = tls_named_curve_oid(group); + + if (server_curve == OID_undef) { + error_print(); + return -1; + } + + if (x509_key_generate(&server_key, OID_ec_public_key, &server_curve, sizeof(server_curve)) != 1) { + error_print(); + return -1; + } + if (tls13_key_share_server_hello_ext_to_bytes(&server_key, &p, &len) != 1) { + error_print(); + return -1; + } + if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &cp, &len) != 1 + || tls_length_is_zero(len) != 1 + || ext_type != TLS_extension_key_share) { + error_print(); + return -1; + } + tls13_key_share_server_hello_print(stderr, 0, 4, ext_data, ext_datalen); + + if (tls13_key_share_server_hello_from_bytes(&group, &key_exchange, &key_exchange_len, + ext_data, ext_datalen) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + + + +static int test_tls13_certificate_authorities_ext(void) +{ + + // 首先生成多个证书,并且将证书写入到一个PEM文件中 + + // 从证书文件中读取名字 + + + // 然后生成这个扩展 + + + return 1; +} + + +static int test_tls_supported_groups_ext(void) +{ + const int client_groups[] = { + TLS_curve_sm2p256v1, + TLS_curve_secp256r1, + }; + const size_t client_groups_cnt = sizeof(client_groups)/sizeof(client_groups[0]); + const int server_groups[] = { + TLS_curve_secp256r1, + TLS_curve_sm2p256v1, + }; + const size_t server_groups_cnt = sizeof(server_groups)/sizeof(server_groups[0]); + int common_groups[2]; + size_t common_groups_cnt; + + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + size_t i; + + if (tls_supported_groups_ext_to_bytes(client_groups, client_groups_cnt, &p, &len) != 1) { + error_print(); + return -1; + } + if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &cp, &len) != 1 + || tls_length_is_zero(len) != 1 + || ext_type != TLS_extension_supported_groups) { + error_print(); + return -1; + } + tls_supported_groups_print(stderr, 0, 4, ext_data, ext_datalen); + + if (tls_process_supported_groups(ext_data, ext_datalen, + server_groups, server_groups_cnt, common_groups, &common_groups_cnt, + sizeof(common_groups)/sizeof(common_groups[0])) != 1) { + error_print(); + return -1; + } + format_print(stderr, 0, 4, "common_groups\n"); + for (i = 0; i < common_groups_cnt; i++) { + format_print(stderr, 0, 8, "%s\n", tls_named_curve_name(common_groups[i])); + } + + if (common_groups[0] != server_groups[0]) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_tls_signature_algorithms_ext(void) +{ + const int server_sig_algs[] = { + TLS_sig_sm2sig_sm3, + TLS_sig_ecdsa_secp256r1_sha256, + }; + const size_t server_sig_algs_cnt = sizeof(server_sig_algs)/sizeof(server_sig_algs[0]); + const int client_sig_algs[] = { + TLS_sig_sm2sig_sm3, + TLS_sig_ecdsa_secp256r1_sha256, + }; + const size_t client_sig_algs_cnt = sizeof(client_sig_algs)/sizeof(client_sig_algs[0]); + + int common_sig_algs[2]; + size_t common_sig_algs_cnt; + + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + size_t i; + + if (tls_signature_algorithms_ext_to_bytes(client_sig_algs, client_sig_algs_cnt, &p, &len) != 1) { + error_print(); + return -1; + } + if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &cp, &len) != 1 + || tls_length_is_zero(len) != 1 + || ext_type != TLS_extension_signature_algorithms) { + error_print(); + return -1; + } + tls_signature_algorithms_print(stderr, 0, 4, ext_data, ext_datalen); + + if (tls_process_signature_algorithms(ext_data, ext_datalen, + server_sig_algs, server_sig_algs_cnt, + common_sig_algs, &common_sig_algs_cnt, + sizeof(common_sig_algs)/sizeof(common_sig_algs[0])) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_tls13_signature_algorithms_cert_ext(void) +{ + const int server_sig_algs[] = { + TLS_sig_sm2sig_sm3, + TLS_sig_ecdsa_secp256r1_sha256, + }; + const size_t server_sig_algs_cnt = sizeof(server_sig_algs)/sizeof(server_sig_algs[0]); + const int client_sig_algs[] = { + TLS_sig_sm2sig_sm3, + TLS_sig_ecdsa_secp256r1_sha256, + }; + const size_t client_sig_algs_cnt = sizeof(client_sig_algs)/sizeof(client_sig_algs[0]); + + int common_sig_algs[2]; + size_t common_sig_algs_cnt; + + uint8_t buf[256]; + uint8_t *p = buf; + const uint8_t *cp = buf; + size_t len = 0; + int ext_type; + const uint8_t *ext_data; + size_t ext_datalen; + size_t i; + + if (tls13_signature_algorithms_cert_ext_to_bytes( + client_sig_algs, client_sig_algs_cnt, &p, &len) != 1) { + error_print(); + return -1; + } + if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &cp, &len) != 1 + || tls_length_is_zero(len) != 1 + || ext_type != TLS_extension_signature_algorithms_cert) { + error_print(); + return -1; + } + tls13_signature_algorithms_cert_print(stderr, 0, 4, ext_data, ext_datalen); + + if (tls_process_signature_algorithms(ext_data, ext_datalen, + server_sig_algs, server_sig_algs_cnt, + common_sig_algs, &common_sig_algs_cnt, + sizeof(common_sig_algs)/sizeof(common_sig_algs[0])) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + int main(void) { if (test_tls13_gcm() != 1) goto err; + if (test_tls13_supported_versions_ext() != 1) goto err; + if (test_tls13_key_share_ext() != 1) goto err; + if (test_tls_supported_groups_ext() != 1) goto err; + if (test_tls_signature_algorithms_ext() != 1) goto err; + if (test_tls13_signature_algorithms_cert_ext() != 1) goto err; + printf("%s all tests passed\n", __FILE__); return 0; err: diff --git a/tools/tls13_server.c b/tools/tls13_server.c index ae82fa7c..fddb2165 100644 --- a/tools/tls13_server.c +++ b/tools/tls13_server.c @@ -143,7 +143,6 @@ bad: } } - if (tls_socket_create(&sock, AF_INET, SOCK_STREAM, 0) != 1) { fprintf(stderr, "%s: socket create error\n", prog); goto end;